diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-06-29 21:46:10 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-06-29 21:46:10 +0200 | 
| commit | 1827f1ab9bf44490cf24779e0eab8533845b4a77 (patch) | |
| tree | d374c7cc1aed4af9d351113cd43178a7e1f4b5f9 | |
| parent | d6b684158d3549f343d1f4d22f4eefba7c873837 (diff) | |
New inter-thread message system.
| -rw-r--r-- | lv2/lv2_gui.cc | 2 | ||||
| -rw-r--r-- | plugingui/Makefile.am | 4 | ||||
| -rw-r--r-- | plugingui/plugingui.cc | 179 | ||||
| -rw-r--r-- | plugingui/plugingui.h | 10 | ||||
| -rw-r--r-- | src/Makefile.am | 4 | ||||
| -rw-r--r-- | src/Makefile.am.drumgizmo | 2 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 219 | ||||
| -rw-r--r-- | src/drumgizmo.h | 44 | ||||
| -rw-r--r-- | src/drumkitloader.cc | 2 | ||||
| -rw-r--r-- | src/message.h | 19 | ||||
| -rw-r--r-- | src/messagehandler.cc | 88 | ||||
| -rw-r--r-- | src/messagehandler.h | 66 | ||||
| -rw-r--r-- | src/messagereceiver.cc | 79 | ||||
| -rw-r--r-- | src/messagereceiver.h | 74 | 
14 files changed, 496 insertions, 296 deletions
| diff --git a/lv2/lv2_gui.cc b/lv2/lv2_gui.cc index 7d9cfbf..7b56c5b 100644 --- a/lv2/lv2_gui.cc +++ b/lv2/lv2_gui.cc @@ -190,7 +190,7 @@ static LV2UI_Handle ui_instantiate(const struct _LV2UI_Descriptor * descriptor,    pt->virt.run = ui_run;    pt->virt.show = ui_show;    pt->virt.hide = ui_hide; -  pt->gui = new PluginGUI(pt->instance); +  pt->gui = new PluginGUI();    pt->gui->setWindowClosedCallback(closeHandler, pt);    *widget = (LV2UI_Widget)pt; diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am index aee2de6..fed12fc 100644 --- a/plugingui/Makefile.am +++ b/plugingui/Makefile.am @@ -15,7 +15,9 @@ plugingui_CFLAGS = $(plugingui_CXXFLAGS)  plugingui_SOURCES = \  	$(PLUGIN_GUI_SOURCES) \  	$(top_srcdir)/src/thread.cc \ -	$(top_srcdir)/src/semaphore.cc +	$(top_srcdir)/src/semaphore.cc \ +	$(top_srcdir)/src/mutex.cc \ +	$(top_srcdir)/src/messagehandler.cc  rcgen_SOURCES = rcgen.cc diff --git a/plugingui/plugingui.cc b/plugingui/plugingui.cc index 9de7c94..a4f99d7 100644 --- a/plugingui/plugingui.cc +++ b/plugingui/plugingui.cc @@ -30,31 +30,10 @@  #include <stdio.h>  #include "knob.h" -  #include "verticalline.h" +#include "../version.h" -#ifndef STANDALONE -#include <drumgizmo.h> -#include "../src/configuration.h" -#else -#include "../src/message.h" -class DrumGizmo { -public: -  bool loadkit(std::string) { return true; } -  bool init(bool) { return true; } -  std::string drumkitfile() { return ""; } -  std::string midimapfile; -  Message *receiveGUIMessage() { return NULL; } -  Message *peekGUIMessage() { return NULL; } -  void sendEngineMessage(Message *msg) { delete msg; } -}; - -namespace Conf { -  bool enable_velocity_modifier; -  float velocity_modifier_weight; -  float velocity_modifier_falloff; -}; -#endif +#include "messagehandler.h"  static void checkClick(void *ptr)  { @@ -63,7 +42,7 @@ static void checkClick(void *ptr)    ChangeSettingMessage *msg =      new ChangeSettingMessage(ChangeSettingMessage::enable_velocity_modifier,                               gui->check->checked()); -  gui->drumgizmo->sendEngineMessage(msg); +  msghandler.sendMessage(MSGRCV_ENGINE, msg);  }  static void knobChange(void *ptr) @@ -73,7 +52,8 @@ static void knobChange(void *ptr)    ChangeSettingMessage *msg =      new ChangeSettingMessage(ChangeSettingMessage::velocity_modifier_weight,                               gui->knob->value()); -  gui->drumgizmo->sendEngineMessage(msg); + +  msghandler.sendMessage(MSGRCV_ENGINE, msg);  #ifdef STANDALONE    int i = gui->knob->value() * 4; @@ -94,7 +74,7 @@ static void knobChange2(void *ptr)    ChangeSettingMessage *msg =      new ChangeSettingMessage(ChangeSettingMessage::velocity_modifier_falloff,                               gui->knob2->value()); -  gui->drumgizmo->sendEngineMessage(msg); +  msghandler.sendMessage(MSGRCV_ENGINE, msg);  #ifdef STANDALONE    gui->progress->setProgress(gui->knob2->value()); @@ -116,16 +96,8 @@ static void selectKitFile(void *ptr, std::string filename)    LoadDrumKitMessage *msg = new LoadDrumKitMessage();    msg->drumkitfile = drumkit; -  gui->drumgizmo->sendEngineMessage(msg); -  /* -  if(!gui->drumgizmo || -     !gui->drumgizmo->loadkit(drumkit) || -     !gui->drumgizmo->init(true)) { -    gui->progress->setState(GUI::ProgressBar::red); -  } else { -    gui->progress->setState(GUI::ProgressBar::blue); -  } -  */ + +  msghandler.sendMessage(MSGRCV_ENGINE, msg);  }  static void kitBrowseClick(void *ptr) @@ -151,7 +123,7 @@ static void selectMapFile(void *ptr, std::string filename)    LoadMidimapMessage *msg = new LoadMidimapMessage();    msg->midimapfile = midimap; -  gui->drumgizmo->sendEngineMessage(msg); +  msghandler.sendMessage(MSGRCV_ENGINE, msg);    /*    if(gui->changeMidimapHandler) @@ -180,15 +152,12 @@ void closeClick(void *ptr)  }  */ -#include "../version.h" - -PluginGUI::PluginGUI(DrumGizmo *drumgizmo) +PluginGUI::PluginGUI() +  : MessageReceiver(MSGRCV_UI)  {    windowClosedHandler = NULL;    changeMidimapHandler = NULL; -  this->drumgizmo = drumgizmo; -    window = NULL;    running = true; @@ -216,13 +185,67 @@ void PluginGUI::stopThread()    }  } + +void PluginGUI::handleMessage(Message *msg) +{ +  switch(msg->type()) { +  case Message::LoadStatus: +    { +      LoadStatusMessage *ls = (LoadStatusMessage*)msg; +      progress->setProgress((float)ls->numer_of_files_loaded / +                            (float)ls->number_of_files); +      if(ls->numer_of_files_loaded == ls->number_of_files) { +        progress->setState(GUI::ProgressBar::green); +      } +    } +    break; +  case Message::LoadStatusMidimap: +    { +      LoadStatusMessageMidimap *ls = (LoadStatusMessageMidimap*)msg; +      progress2->setProgress(1); +      if(ls->success) { +        progress2->setState(GUI::ProgressBar::green); +      } else { +        progress2->setState(GUI::ProgressBar::red); +      } +    } +    break; +  case Message::EngineSettingsMessage: +    { +      EngineSettingsMessage *settings = (EngineSettingsMessage *)msg; +      lineedit->setText(settings->drumkitfile); +      if(settings->drumkit_loaded) { +        progress->setProgress(1); +        progress->setState(GUI::ProgressBar::green); +      } else { +        progress->setProgress(0); +        progress->setState(GUI::ProgressBar::blue); +      } +      lineedit2->setText(settings->midimapfile); +      if(settings->midimap_loaded) { +        progress2->setProgress(1); +        progress2->setState(GUI::ProgressBar::green); +      } else { +        progress2->setProgress(0); +        progress2->setState(GUI::ProgressBar::blue); +      } +      check->setChecked(settings->enable_velocity_modifier); +      knob->setValue(settings->velocity_modifier_weight); +      knob2->setValue(settings->velocity_modifier_falloff); +       +    } +  default: +    break; +  } +} +  void PluginGUI::thread_main()  {    init();    { // Request all engine settings      EngineSettingsMessage *msg = new EngineSettingsMessage(); -    drumgizmo->sendEngineMessage(msg); +    msghandler.sendMessage(MSGRCV_ENGINE, msg);    }    while(1) { @@ -235,67 +258,7 @@ void PluginGUI::thread_main()      if(!running) break;      window->eventHandler()->processEvents(); - -    Message *msg; -    if((msg = drumgizmo->receiveGUIMessage()) != NULL) { -      switch(msg->type()) { -      case Message::LoadStatus: -        { -          Message *pmsg; -          while( (pmsg = drumgizmo->peekGUIMessage()) != NULL) { -            if(pmsg->type() != Message::LoadStatus) break; -            delete msg; -            msg = drumgizmo->receiveGUIMessage(); -          }  -          LoadStatusMessage *ls = (LoadStatusMessage*)msg; -          progress->setProgress((float)ls->numer_of_files_loaded / -                                (float)ls->number_of_files); -          if(ls->numer_of_files_loaded == ls->number_of_files) { -            progress->setState(GUI::ProgressBar::green); -          } -        } -        break; -      case Message::LoadStatusMidimap: -        { -          LoadStatusMessageMidimap *ls = (LoadStatusMessageMidimap*)msg; -          progress2->setProgress(1); -          if(ls->success) { -            progress2->setState(GUI::ProgressBar::green); -          } else { -            progress2->setState(GUI::ProgressBar::red); -          } -        } -        break; -      case Message::EngineSettingsMessage: -        { -          EngineSettingsMessage *settings = (EngineSettingsMessage *)msg; -          lineedit->setText(settings->drumkitfile); -          if(settings->drumkit_loaded) { -            progress->setProgress(1); -            progress->setState(GUI::ProgressBar::green); -          } else { -            progress->setProgress(0); -            progress->setState(GUI::ProgressBar::blue); -          } -          lineedit2->setText(settings->midimapfile); -          if(settings->midimap_loaded) { -            progress2->setProgress(1); -            progress2->setState(GUI::ProgressBar::green); -          } else { -            progress2->setProgress(0); -            progress2->setState(GUI::ProgressBar::blue); -          } -          check->setChecked(settings->enable_velocity_modifier); -          knob->setValue(settings->velocity_modifier_weight); -          knob2->setValue(settings->velocity_modifier_falloff); -       -        } -      default: -        break; -      } - -      delete msg; -    } +    handleMessages();    }    deinit(); @@ -500,6 +463,12 @@ void PluginGUI::setWindowClosedCallback(void (*handler)(void *), void *ptr)  #ifdef STANDALONE +class Engine : public MessageHandler { +public: +  void handleMessage(Message *msg) {} +}; + +  void stop(void *ptr)  {    DEBUG(stop, "Stopping...\n"); @@ -524,7 +493,7 @@ int main()    bool running = true; -  PluginGUI gui(NULL); +  PluginGUI gui;    gui.setWindowClosedCallback(stop, &running);    // gui.show(); diff --git a/plugingui/plugingui.h b/plugingui/plugingui.h index 97e45b8..cd050de 100644 --- a/plugingui/plugingui.h +++ b/plugingui/plugingui.h @@ -42,11 +42,11 @@  #include "thread.h"  #include "semaphore.h" -class DrumGizmo; +#include "messagereceiver.h" -class PluginGUI : public Thread { +class PluginGUI : public Thread, public MessageReceiver {  public: -  PluginGUI(DrumGizmo *drumgizmo); +  PluginGUI();    ~PluginGUI();    void thread_main(); @@ -60,14 +60,14 @@ public:    void processEvents();    void setWindowClosedCallback(void (*handler)(void *), void *ptr); +  void handleMessage(Message *msg); +    //private:    GUI::Window *window;    GUI::EventHandler *eventhandler;    GUI::FileBrowser *filebrowser; -  DrumGizmo *drumgizmo; -    GUI::CheckBox *check;    GUI::Knob *knob;    GUI::Knob *knob2; diff --git a/src/Makefile.am b/src/Makefile.am index 35d052b..75c209c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,8 @@ EXTRA_DIST = \  	instrument.h \  	instrumentparser.h \  	message.h \ +	messagehandler.h \ +	messagereceiver.h \  	midimapparser.h \  	midimapper.h \  	mutex.h \ @@ -42,6 +44,8 @@ EXTRA_DIST = \  	events.cc \  	instrument.cc \  	instrumentparser.cc \ +	messagehandler.cc \ +	messagereceiver.cc \  	midimapparser.cc \  	midimapper.cc \  	mutex.cc \ diff --git a/src/Makefile.am.drumgizmo b/src/Makefile.am.drumgizmo index 428d2a7..b1ad862 100644 --- a/src/Makefile.am.drumgizmo +++ b/src/Makefile.am.drumgizmo @@ -11,6 +11,8 @@ DRUMGIZMO_SOURCES = \  	$(top_srcdir)/src/events.cc \  	$(top_srcdir)/src/instrument.cc \  	$(top_srcdir)/src/instrumentparser.cc \ +	$(top_srcdir)/src/messagehandler.cc \ +	$(top_srcdir)/src/messagereceiver.cc \  	$(top_srcdir)/src/midimapparser.cc \  	$(top_srcdir)/src/midimapper.cc \  	$(top_srcdir)/src/mutex.cc \ diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index b6ac98f..135975d 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -41,7 +41,8 @@  #include "configuration.h"  DrumGizmo::DrumGizmo(AudioOutputEngine *o, AudioInputEngine *i) -  : loader(this), oe(o), ie(i) +  : MessageReceiver(MSGRCV_ENGINE), +    loader(this), oe(o), ie(i)  {    loader.run(); // Start drumkit loader thread.  } @@ -59,78 +60,6 @@ DrumGizmo::~DrumGizmo()    loader.stop();  } -/* - * Add a message to the GUI message queue. - */ -void DrumGizmo::sendGUIMessage(Message *msg) -{ -  MutexAutolock l(gui_message_mutex); -  gui_message_queue.push_back(msg); -} - -/* - * Receive message from the engine. The caller takes over the memory. - */ -Message *DrumGizmo::receiveGUIMessage() -{ -  MutexAutolock l(gui_message_mutex); -  Message *msg = NULL; -  if(gui_message_queue.size()) { -    msg = gui_message_queue.front(); -    gui_message_queue.pop_front(); -  } -  return msg; -} - -/* - * Receive message from the engine without removing it from the queue. - */ -Message *DrumGizmo::peekGUIMessage() -{ -  MutexAutolock l(gui_message_mutex); -  Message *msg = NULL; -  if(gui_message_queue.size()) { -    msg = gui_message_queue.front(); -  } -  return msg; -} - -/* - * Add a message to the GUI message queue. - */ -void DrumGizmo::sendEngineMessage(Message *msg) -{ -  MutexAutolock l(engine_message_mutex); -  engine_message_queue.push_back(msg); -} - -/* - * Receive message from the engine. The caller takes over the memory. - */ -Message *DrumGizmo::receiveEngineMessage() -{ -  MutexAutolock l(engine_message_mutex); -  Message *msg = NULL; -  if(engine_message_queue.size()) { -    msg = engine_message_queue.front(); -    engine_message_queue.pop_front(); -  } -  return msg; -} - -/* - * Receive message from the engine without removing it from the queue. - */ -Message *DrumGizmo::peekEngineMessage() -{ -  MutexAutolock l(engine_message_mutex); -  Message *msg = NULL; -  if(engine_message_queue.size()) { -    msg = engine_message_queue.front(); -  } -  return msg; -} -  std::string DrumGizmo::drumkitfile()  {    return kitfile; @@ -181,86 +110,88 @@ bool DrumGizmo::init(bool preload)    return true;  } -void DrumGizmo::handleEngineEvents() +void DrumGizmo::handleMessage(Message *msg)  { -  Message *msg = receiveEngineMessage(); -  if(msg) { -    DEBUG(msg, "got message."); -    switch(msg->type()) { -    case Message::LoadDrumKit: -      { -        DEBUG(msg, "got LoadDrumKitMessage message."); -        LoadDrumKitMessage *m = (LoadDrumKitMessage*)msg; -        loadkit(m->drumkitfile); -        //init(true); -      } -      break; -    case Message::LoadMidimap: -      DEBUG(msg, "got LoadMidimapMessage message."); -      if(!ie->isMidiEngine()) break; -      { +  DEBUG(msg, "got message."); +  switch(msg->type()) { +  case Message::RegisterUIMessage: +    { +      DEBUG(msg, "got RegisterUIMessage message."); +      RegisterUIMessage *m = (RegisterUIMessage*)msg; +      ui = m->messagehandler; +    } +    break; +  case Message::LoadDrumKit: +    { +      DEBUG(msg, "got LoadDrumKitMessage message."); +      LoadDrumKitMessage *m = (LoadDrumKitMessage*)msg; +      loadkit(m->drumkitfile); +      //init(true); +    } +    break; +  case Message::LoadMidimap: +    DEBUG(msg, "got LoadMidimapMessage message."); +    if(!ie->isMidiEngine()) break; +    { +      AudioInputEngineMidi *aim = (AudioInputEngineMidi*)ie; +      LoadMidimapMessage *m = (LoadMidimapMessage*)msg; +      bool ret = aim->loadMidiMap(m->midimapfile, kit.instruments); +       +      LoadStatusMessageMidimap *ls = new LoadStatusMessageMidimap(); +      ls->success = ret; +      msghandler.sendMessage(MSGRCV_UI, ls); +    } +    break; +  case Message::EngineSettingsMessage: +    { +      DEBUG(msg, "--------------- Send: EngineSettingsMessage ------------ \n"); +       +      bool mmap_loaded = false; +      std::string mmapfile; +      if(ie->isMidiEngine()) {          AudioInputEngineMidi *aim = (AudioInputEngineMidi*)ie; -        LoadMidimapMessage *m = (LoadMidimapMessage*)msg; -        bool ret = aim->loadMidiMap(m->midimapfile, kit.instruments); -         -        LoadStatusMessageMidimap *ls = new LoadStatusMessageMidimap(); -        ls->success = ret; -        sendGUIMessage(ls); -      } -      break; -    case Message::EngineSettingsMessage: -      { -        DEBUG(msg, "--------------- Send: EngineSettingsMessage --------------- \n"); - -        bool mmap_loaded = false; -        std::string mmapfile; -        if(ie->isMidiEngine()) { -          AudioInputEngineMidi *aim = (AudioInputEngineMidi*)ie; -          mmapfile = aim->midimapFile(); -          mmap_loaded = aim->isValid(); -           -        } - -        EngineSettingsMessage *msg = new EngineSettingsMessage(); -        msg->midimapfile = mmapfile; -        msg->midimap_loaded = mmap_loaded; -        msg->drumkitfile = drumkitfile(); -        msg->drumkit_loaded = loader.isDone(); -        msg->enable_velocity_modifier = Conf::enable_velocity_modifier; -        msg->velocity_modifier_falloff = Conf::velocity_modifier_falloff; -        msg->velocity_modifier_weight = Conf::velocity_modifier_weight; -        msg->enable_velocity_randomiser = Conf::enable_velocity_randomiser; -        msg->velocity_randomiser_weight = Conf::velocity_randomiser_weight; -        sendGUIMessage(msg); +        mmapfile = aim->midimapFile(); +        mmap_loaded = aim->isValid();        } -      break; -    case Message::ChangeSettingMessage: -      { -        ChangeSettingMessage *ch = (ChangeSettingMessage*)msg; -        switch(ch->name) { -        case ChangeSettingMessage::enable_velocity_modifier: -          Conf::enable_velocity_modifier = ch->value; -          break; -        case ChangeSettingMessage::velocity_modifier_weight: -          Conf::velocity_modifier_weight = ch->value; -          break; -        case ChangeSettingMessage::velocity_modifier_falloff: -          Conf::velocity_modifier_falloff = ch->value; -          break; -        } +       +      EngineSettingsMessage *msg = new EngineSettingsMessage(); +      msg->midimapfile = mmapfile; +      msg->midimap_loaded = mmap_loaded; +      msg->drumkitfile = drumkitfile(); +      msg->drumkit_loaded = loader.isDone(); +      msg->enable_velocity_modifier = Conf::enable_velocity_modifier; +      msg->velocity_modifier_falloff = Conf::velocity_modifier_falloff; +      msg->velocity_modifier_weight = Conf::velocity_modifier_weight; +      msg->enable_velocity_randomiser = Conf::enable_velocity_randomiser; +      msg->velocity_randomiser_weight = Conf::velocity_randomiser_weight; +      msghandler.sendMessage(MSGRCV_UI, msg); +    } +    break; +  case Message::ChangeSettingMessage: +    { +      ChangeSettingMessage *ch = (ChangeSettingMessage*)msg; +      switch(ch->name) { +      case ChangeSettingMessage::enable_velocity_modifier: +        Conf::enable_velocity_modifier = ch->value; +        break; +      case ChangeSettingMessage::velocity_modifier_weight: +        Conf::velocity_modifier_weight = ch->value; +        break; +      case ChangeSettingMessage::velocity_modifier_falloff: +        Conf::velocity_modifier_falloff = ch->value; +        break;        } -      break; -    default: -      break;      } -    delete msg; +    break; +  default: +    break;    }  }  bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)  {    // Handle engine messages, at most one in each iteration: -  handleEngineEvents(); +  handleMessages(1);    ie->pre();    oe->pre(nsamples); @@ -609,7 +540,7 @@ bool DrumGizmo::setConfigString(std::string cfg)      */      LoadDrumKitMessage *msg = new LoadDrumKitMessage();      msg->drumkitfile = newkit; -    sendEngineMessage(msg); +    msghandler.sendMessage(MSGRCV_ENGINE, msg);    }    std::string newmidimap = p.value("midimapfile"); @@ -617,7 +548,7 @@ bool DrumGizmo::setConfigString(std::string cfg)      //midimapfile = newmidimap;      LoadMidimapMessage *msg = new LoadMidimapMessage();      msg->midimapfile = newmidimap; -    sendEngineMessage(msg); +    msghandler.sendMessage(MSGRCV_ENGINE, msg);    }    return true; diff --git a/src/drumgizmo.h b/src/drumgizmo.h index ffb9b07..31c192c 100644 --- a/src/drumgizmo.h +++ b/src/drumgizmo.h @@ -43,9 +43,11 @@  #include "message.h" +#include "messagereceiver.h" +  #define MAX_NUM_CHANNELS 512 -class DrumGizmo { +class DrumGizmo : public MessageReceiver {  public:    DrumGizmo(AudioOutputEngine *outputengine,              AudioInputEngine *inputengine); @@ -69,50 +71,14 @@ public:    std::string kitfile; -  /* -   * Receive message from the engine. The caller takes over the memory. -   */ -  Message *receiveGUIMessage(); - -  /* -   * Receive message from the engine without removing it from the queue. -   */ -  Message *peekGUIMessage(); - -  /* -   * Add a message to the GUI message queue. -   */ -  void sendEngineMessage(Message *msg); - -  /* -   * Receive message from the engine. The caller takes over the memory. -   */ -  Message *receiveEngineMessage(); - -  /* -   * Receive message from the engine without removing it from the queue. -   */ -  Message *peekEngineMessage(); - -  /* -   * Add a message to the GUI message queue. -   */ -  void sendGUIMessage(Message *msg); +  void handleMessage(Message *msg);  private: -  void handleEngineEvents(); - -  Mutex gui_message_mutex; -  std::list<Message *> gui_message_queue; - -  Mutex engine_message_mutex; -  std::list<Message *> engine_message_queue; -    DrumKitLoader loader;    Mutex mutex;    bool is_running; -   +    AudioOutputEngine *oe;    AudioInputEngine *ie; diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc index 41b56a1..a7a8989 100644 --- a/src/drumkitloader.cc +++ b/src/drumkitloader.cc @@ -191,7 +191,7 @@ void DrumKitLoader::thread_main()              ls->number_of_files = count;              ls->numer_of_files_loaded = loaded;              ls->current_file = af->filename; -            drumgizmo->sendGUIMessage(ls); +            msghandler.sendMessage(MSGRCV_UI, ls);              a++; diff --git a/src/message.h b/src/message.h index 4ce65ef..d51c263 100644 --- a/src/message.h +++ b/src/message.h @@ -27,6 +27,10 @@  #ifndef __DRUMGIZMO_MESSAGE_H__  #define __DRUMGIZMO_MESSAGE_H__ +#include <string> + +class MessageHandler; +  class Message {  public:    typedef enum { @@ -39,15 +43,24 @@ public:      LoadMidimap, // Signal engine to load midimap.      EngineSettingsMessage, // Request or receive engine settings.      ChangeSettingMessage, // Update named setting in engine. +    RegisterUIMessage, // Register new UI message handler    } type_t; +  typedef enum { +    NormalProcessing, // Just add to the queue +    FilterMultiple, // Ignore top message if it has the same type. +    // SyncWait, // Block the send call until the message has been handled by the receiver. +  } processing_mode_t; +    virtual ~Message() {}    virtual type_t type() = 0; +  virtual processing_mode_t processing_mode() { return NormalProcessing; }  };  class LoadStatusMessage : public Message {  public:    type_t type() { return Message::LoadStatus; } +  processing_mode_t processing_mode() { return FilterMultiple; }    unsigned int number_of_files;    unsigned int numer_of_files_loaded;    std::string current_file; @@ -106,4 +119,10 @@ public:    float value;  }; +class RegisterUIMessage : public Message { +public: +  type_t type() { return Message::RegisterUIMessage; } +  MessageHandler *messagehandler; +}; +  #endif/*__DRUMGIZMO_MESSAGE_H__*/ diff --git a/src/messagehandler.cc b/src/messagehandler.cc new file mode 100644 index 0000000..a5a71f1 --- /dev/null +++ b/src/messagehandler.cc @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            messagehandler.cc + * + *  Fri Jun 14 20:30:43 CEST 2013 + *  Copyright 2013 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "messagehandler.h" + +#include <hugin.hpp> + +#include "messagereceiver.h" + +// Global messagehandler: +MessageHandler msghandler; + +MessageHandler::MessageHandler() +{ +} + +void MessageHandler::addReceiver(message_receiver_id_t id, +                                 MessageReceiver *receiver) +{ +  MutexAutolock l(mutex); + +  receivers[id] = receiver; +} + +void MessageHandler::removeReceiver(MessageReceiver *receiver) +{ +  MutexAutolock l(mutex); + +  std::map<message_receiver_id_t, MessageReceiver *>::iterator i = +    receivers.begin(); +  while(i != receivers.end()) { +    if(i->second == receiver) { +      receivers.erase(i); +      break; +    } +    i++; +  } +} + +bool MessageHandler::sendMessage(message_receiver_id_t id, Message* msg) +{ +  MutexAutolock l(mutex); + +  if(receivers.find(id) == receivers.end()) { +    WARN(msghandler, "Could not find id %d\n", id); +    delete msg; +    return false; +  } + +  DEBUG(msghandler, "Sending message to id %d\n", id); + +  MessageReceiver *receiver = receivers[id]; + +  if(msg->processing_mode() == Message::FilterMultiple) { +    Message *pmsg; +    while( (pmsg = receiver->peekMessage()) != NULL) { +      if(pmsg->type() != Message::LoadStatus) break; +      delete msg; +      msg = receiver->receiveMessage(); +    } +  } + +  receiver->sendMessage(msg); +  return true; +} diff --git a/src/messagehandler.h b/src/messagehandler.h new file mode 100644 index 0000000..9812777 --- /dev/null +++ b/src/messagehandler.h @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            messagehandler.h + * + *  Fri Jun 14 20:30:43 CEST 2013 + *  Copyright 2013 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#ifndef __DRUMGIZMO_MESSAGEHANDLER_H__ +#define __DRUMGIZMO_MESSAGEHANDLER_H__ + +#include <map> + +#include "message.h" +#include "mutex.h" + +typedef enum { +  MSGRCV_ENGINE = 1, +  MSGRCV_UI = 2, +  MSGRCV_LOADER = 3, +} message_receiver_id_t; + +class MessageReceiver; + +class MessageHandler { +public: +  MessageHandler(); + +  void addReceiver(message_receiver_id_t id, MessageReceiver *receiver); +  void removeReceiver(MessageReceiver *receiver); + +  /** +   * Send Message to receiver with specified id. +   * @return Return true if id is registered. Return false if id is not +   * currently registered. +   */ +  bool sendMessage(message_receiver_id_t id, Message* msg); + +private: +  std::map<message_receiver_id_t, MessageReceiver *> receivers; + +  Mutex mutex; +}; + +// Global MessageHandler; +extern MessageHandler msghandler; + +#endif/*__DRUMGIZMO_MESSAGEHANDLER_H__*/ diff --git a/src/messagereceiver.cc b/src/messagereceiver.cc new file mode 100644 index 0000000..f391aad --- /dev/null +++ b/src/messagereceiver.cc @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            messagereceiver.cc + * + *  Sun Jun 16 12:09:06 CEST 2013 + *  Copyright 2013 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "messagereceiver.h" + +#include <hugin.hpp> + +MessageReceiver::MessageReceiver(message_receiver_id_t id) +{ +  msghandler.addReceiver(id, this); +} + +MessageReceiver::~MessageReceiver() +{ +  msghandler.removeReceiver(this); +} + +void MessageReceiver::sendMessage(Message *msg) +{ +  MutexAutolock l(message_mutex); + +  message_queue.push_back(msg); +} + +Message *MessageReceiver::receiveMessage() +{ +  MutexAutolock l(message_mutex); +  Message *msg = NULL; +  if(message_queue.size()) { +    msg = message_queue.front(); +    message_queue.pop_front(); +  } +  return msg; +} + +Message *MessageReceiver::peekMessage() +{ +  MutexAutolock l(message_mutex); +  Message *msg = NULL; +  if(message_queue.size()) { +    msg = message_queue.front(); +  } +  return msg; +} + +void MessageReceiver::handleMessages(size_t max) +{ +  bool process_all = false; +  if(max == 0) process_all = true; + +  while((process_all || max--) && peekMessage()) { +    Message *msg = receiveMessage(); +    handleMessage(msg); +    delete msg; +  } +} diff --git a/src/messagereceiver.h b/src/messagereceiver.h new file mode 100644 index 0000000..4185f29 --- /dev/null +++ b/src/messagereceiver.h @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            messagereceiver.h + * + *  Sun Jun 16 12:09:06 CEST 2013 + *  Copyright 2013 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#ifndef __DRUMGIZMO_MESSAGERECEIVER_H__ +#define __DRUMGIZMO_MESSAGERECEIVER_H__ + +#include <list> + +#include "mutex.h" +#include "message.h" +#include "messagehandler.h" + +class MessageReceiver { +public: +  MessageReceiver(message_receiver_id_t id); +  ~MessageReceiver(); + +  /** +   * Receive message from the message queue. +   */ +  Message *receiveMessage(); + +  /** +   * Receive message from the message queue without removing it. +   */ +  Message *peekMessage(); + +  /** +   * Add a message to the message queue. +   */ +  void sendMessage(Message *msg); + +  /** +   * Handle messages from the event queue. +   * @param max_number_of_events the maximum number of events to be handled in +   * this call. 0 means all. +   */ +  void handleMessages(size_t max_number_of_events = 0); + +  /** +   * Handler to be implemented in child classes. +   * Handles a single event. +   */ +  virtual void handleMessage(Message *msg) = 0; + +private: +  Mutex message_mutex; +  std::list<Message *> message_queue; +}; + +#endif/*__DRUMGIZMO_MESSAGERECEIVER_H__*/ | 
