diff --git a/include/core/dispatch.hpp b/include/core/dispatch.hpp index 8712092a..72dc0869 100644 --- a/include/core/dispatch.hpp +++ b/include/core/dispatch.hpp @@ -255,23 +255,23 @@ private: void dispatch_set_error_streams(std::ostream* stream); -extern struct dispatcher<> notify_autohold_reconfigure; -extern struct dispatcher notify_autohold_update; -extern struct dispatcher notify_autofire_update; -extern struct dispatcher<> notify_close; -extern struct dispatcher&> notify_set_screen; -extern struct dispatcher> notify_sound_change; -extern struct dispatcher<> notify_screen_update; -extern struct dispatcher<> notify_status_update; -extern struct dispatcher notify_sound_unmute; -extern struct dispatcher notify_mode_change; -extern struct dispatcher<> notify_core_change; -extern struct dispatcher<> notify_title_change; -extern struct dispatcher notify_core_changed; -extern struct dispatcher<> notify_new_core; -extern struct dispatcher<> notify_voice_stream_change; -extern struct dispatcher<> notify_vu_change; -extern struct dispatcher<> notify_subtitle_change; -extern struct dispatcher notify_multitrack_change; +extern struct dispatch::source<> notify_autohold_reconfigure; +extern struct dispatch::source notify_autohold_update; +extern struct dispatch::source notify_autofire_update; +extern struct dispatch::source<> notify_close; +extern struct dispatch::source&> notify_set_screen; +extern struct dispatch::source> notify_sound_change; +extern struct dispatch::source<> notify_screen_update; +extern struct dispatch::source<> notify_status_update; +extern struct dispatch::source notify_sound_unmute; +extern struct dispatch::source notify_mode_change; +extern struct dispatch::source<> notify_core_change; +extern struct dispatch::source<> notify_title_change; +extern struct dispatch::source notify_core_changed; +extern struct dispatch::source<> notify_new_core; +extern struct dispatch::source<> notify_voice_stream_change; +extern struct dispatch::source<> notify_vu_change; +extern struct dispatch::source<> notify_subtitle_change; +extern struct dispatch::source notify_multitrack_change; #endif diff --git a/include/library/dispatch.hpp b/include/library/dispatch.hpp index b2fd3f36..486dbfa2 100644 --- a/include/library/dispatch.hpp +++ b/include/library/dispatch.hpp @@ -8,51 +8,86 @@ #include #include "threadtypes.hpp" -mutex_class& dispatch_global_init_lock(); - -template struct dispatcher; - -template struct dispatch_target +namespace dispatch { - dispatch_target() +mutex_class& global_init_lock(); + +template struct source; + +/** + * Dispatch target handler. + */ +template struct target +{ +/** + * Create a new target handler. + */ + target() { src = NULL; fn = dummy; } - inline ~dispatch_target(); - inline void set(dispatcher& d, std::function _fn); +/** + * Destroy a target, detaching it from source. + */ + inline ~target(); +/** + * Connect a target to given source and give a handler. + * + * Parameter d: The source to connect to. + * Parameter _fn: The function to use as handler. + */ + inline void set(source& d, std::function _fn); private: static void dummy(T... args) {}; - void set_source(dispatcher* d) { src = d; } + void set_source(source* d) { src = d; } void call(T... args) { fn(args...); } - dispatcher* src; + source* src; std::function fn; - friend class dispatcher; + friend class source; }; -template struct dispatcher +/** + * Dispatch source (event generator). + */ +template struct source { - dispatcher(const char* _name) +/** + * Create a new event source. + * + * Parameter _name: The name of the event. + */ + source(const char* _name) { init(); name = _name; } - ~dispatcher() +/** + * Destory an event source. + * + * All targets are disconnected. + */ + ~source() { delete _targets; delete lck; lck = NULL; } +/** + * Send an event. + * + * Parameter args: The arguments to send. + */ void operator()(T... args) { init(); uint64_t k = 0; - typename std::map*>::iterator i; + typename std::map*>::iterator i; lck->lock(); i = targets().lower_bound(k); while(i != targets().end()) { k = i->first + 1; - dispatch_target* t = i->second; + target* t = i->second; lck->unlock(); try { t->call(args...); @@ -64,14 +99,24 @@ template struct dispatcher } lck->unlock(); } - void connect(dispatch_target& target) +/** + * Connect a new target. + * + * Parameters target: The target to connect. + */ + void connect(target& target) { init(); umutex_class h(*lck); targets()[next_cbseq++] = ⌖ target.set_source(this); } - void disconnect(dispatch_target& target) +/** + * Disconnect a target. + * + * Parameters target: The target to disconnect. + */ + void disconnect(target& target) { init(); if(!lck) @@ -84,6 +129,11 @@ template struct dispatcher } target.set_source(NULL); } +/** + * Set stream to send error messages to. + * + * Parameter to: The stream (if NULL, use std::cerr). + */ void errors_to(std::ostream* to) { errstrm = to ? to : &std::cerr; @@ -93,7 +143,7 @@ private: { if(inited) return; - umutex_class h(dispatch_global_init_lock()); + umutex_class h(global_init_lock()); if(inited) return; errstrm = &std::cerr; @@ -104,32 +154,32 @@ private: inited = true; } mutex_class* lck; - std::map*>& targets() + std::map*>& targets() { - if(!_targets) _targets = new std::map*>; + if(!_targets) _targets = new std::map*>; return *_targets; } - std::map*>* _targets; + std::map*>* _targets; uint64_t next_cbseq; std::ostream* errstrm; const char* name; bool inited; - dispatcher(const dispatcher&); - dispatcher& operator=(const dispatcher&); + source(const source&); + source& operator=(const source&); }; -template dispatch_target::~dispatch_target() +template target::~target() { if(src) src->disconnect(*this); } -template void dispatch_target::set(dispatcher& d, std::function _fn) +template void target::set(source& d, std::function _fn) { fn = _fn; src = &d; if(src) src->connect(*this); } - +} #endif diff --git a/include/platform/wxwidgets/menu_loadrom.hpp b/include/platform/wxwidgets/menu_loadrom.hpp index 0f504fb8..c5300799 100644 --- a/include/platform/wxwidgets/menu_loadrom.hpp +++ b/include/platform/wxwidgets/menu_loadrom.hpp @@ -20,7 +20,7 @@ private: int wxid_range_low; int wxid_range_high; std::function callback; - struct dispatch_target<> corelistener; + struct dispatch::target<> corelistener; }; #endif diff --git a/include/platform/wxwidgets/menu_tracelog.hpp b/include/platform/wxwidgets/menu_tracelog.hpp index 1778a793..cd7c7aba 100644 --- a/include/platform/wxwidgets/menu_tracelog.hpp +++ b/include/platform/wxwidgets/menu_tracelog.hpp @@ -17,7 +17,7 @@ public: void update(); bool any_enabled(); private: - struct dispatch_target<> corechange; + struct dispatch::target<> corechange; wxWindow* pwin; int wxid_range_low; int wxid_range_high; diff --git a/include/platform/wxwidgets/window_mainwindow.hpp b/include/platform/wxwidgets/window_mainwindow.hpp index 2e4d89ed..dfb1b50f 100644 --- a/include/platform/wxwidgets/window_mainwindow.hpp +++ b/include/platform/wxwidgets/window_mainwindow.hpp @@ -76,11 +76,11 @@ private: void* sounddev2; void* dmenu; wxTimer* focus_timer; - struct dispatch_target<> corechange; - struct dispatch_target<> titlechange; - struct dispatch_target<> newcore; - struct dispatch_target unmuted; - struct dispatch_target modechange; + struct dispatch::target<> corechange; + struct dispatch::target<> titlechange; + struct dispatch::target<> newcore; + struct dispatch::target unmuted; + struct dispatch::target modechange; }; #endif diff --git a/src/core/controller.cpp b/src/core/controller.cpp index 409878c0..5d8235b8 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -515,7 +515,7 @@ namespace { ncore.set(notify_new_core, []() { init_buttonmap(); }); } - struct dispatch_target<> ncore; + struct dispatch::target<> ncore; } coresnoop; } diff --git a/src/core/debug.cpp b/src/core/debug.cpp index e42853a2..33eb640a 100644 --- a/src/core/debug.cpp +++ b/src/core/debug.cpp @@ -31,7 +31,7 @@ namespace cb2_list dummy_cb2; //Always empty. uint64_t xmask = 1; std::function tracelog_change_cb; - struct dispatch_target<> corechange; + struct dispatch::target<> corechange; bool corechange_r = false; struct tracelog_file diff --git a/src/core/dispatch.cpp b/src/core/dispatch.cpp index 42e05e58..3eef76d5 100644 --- a/src/core/dispatch.cpp +++ b/src/core/dispatch.cpp @@ -88,7 +88,7 @@ uint64_t gameinfo_struct::get_rerecords() const throw() namespace { - globalwrap> dispatch; + globalwrap> _dispatch; globalwrap> dispatch_audio; uint32_t srate_n = 32000; uint32_t srate_d = 1; @@ -99,7 +99,7 @@ namespace information_dispatch::information_dispatch(const std::string& name) throw(std::bad_alloc) { target_name = name; - dispatch().push_back(this); + _dispatch().push_back(this); known_if_dumper = false; marked_as_dumper = false; notified_as_dumper = false; @@ -107,9 +107,9 @@ information_dispatch::information_dispatch(const std::string& name) throw(std::b information_dispatch::~information_dispatch() throw() { - for(auto i = dispatch().begin(); i != dispatch().end(); ++i) { + for(auto i = _dispatch().begin(); i != _dispatch().end(); ++i) { if(*i == this) { - dispatch().erase(i); + _dispatch().erase(i); break; } } @@ -120,7 +120,7 @@ information_dispatch::~information_dispatch() throw() } } if(notified_as_dumper) - for(auto& i : dispatch()) { + for(auto& i : _dispatch()) { START_EH_BLOCK i->on_destroy_dumper(target_name); END_EH_BLOCK(i, "on_destroy_dumper"); @@ -135,7 +135,7 @@ void information_dispatch::on_frame(struct framebuffer_raw& _frame, uint32_t fps void information_dispatch::do_frame(struct framebuffer_raw& _frame, uint32_t fps_n, uint32_t fps_d) throw() { update_dumpers(); - for(auto& i : dispatch()) { + for(auto& i : _dispatch()) { START_EH_BLOCK i->on_frame(_frame, fps_n, fps_d); END_EH_BLOCK(i, "on_frame"); @@ -165,7 +165,7 @@ void information_dispatch::on_dump_end() void information_dispatch::do_dump_end() throw() { update_dumpers(); - for(auto& i : dispatch()) { + for(auto& i : _dispatch()) { START_EH_BLOCK i->on_dump_end(); END_EH_BLOCK(i, "on_dump_end"); @@ -194,7 +194,7 @@ void information_dispatch::do_sound_rate(uint32_t rate_n, uint32_t rate_d) throw return; srate_n = rate_n; srate_d = rate_d; - for(auto& i : dispatch()) { + for(auto& i : _dispatch()) { START_EH_BLOCK i->on_sound_rate(rate_n, rate_d); END_EH_BLOCK(i, "on_sound_rate"); @@ -219,7 +219,7 @@ void information_dispatch::do_gameinfo(const struct gameinfo_struct& gi) throw() } catch(...) { OOM_panic(); } - for(auto& i : dispatch()) { + for(auto& i : _dispatch()) { START_EH_BLOCK i->on_gameinfo(sgi); END_EH_BLOCK(i, "on_gameinfo"); @@ -250,7 +250,7 @@ unsigned information_dispatch::get_dumper_count() throw() { update_dumpers(true); unsigned count = 0; - for(auto& i : dispatch()) + for(auto& i : _dispatch()) if(i->marked_as_dumper) count++; if(!recursive) { @@ -266,7 +266,7 @@ std::set information_dispatch::get_dumpers() throw(std::bad_alloc) update_dumpers(); std::set r; try { - for(auto& i : dispatch()) + for(auto& i : _dispatch()) if(i->notified_as_dumper) r.insert(i->get_name()); } catch(...) { @@ -283,13 +283,13 @@ const std::string& information_dispatch::get_name() throw() void information_dispatch::update_dumpers(bool nocalls) throw() { - for(auto& i : dispatch()) { + for(auto& i : _dispatch()) { if(!i->known_if_dumper) { i->marked_as_dumper = i->get_dumper_flag(); i->known_if_dumper = true; } if(i->marked_as_dumper && !i->notified_as_dumper && !nocalls) { - for(auto& j : dispatch()) { + for(auto& j : _dispatch()) { START_EH_BLOCK j->on_new_dumper(i->target_name); END_EH_BLOCK(j, "on_new_dumper"); @@ -313,7 +313,7 @@ void information_dispatch::do_dumper_update() throw() { if(in_global_ctors()) return; - for(auto& i : dispatch()) { + for(auto& i : _dispatch()) { START_EH_BLOCK i->on_dumper_update(); END_EH_BLOCK(i, "on_dumper_update"); @@ -342,21 +342,21 @@ void dispatch_set_error_streams(std::ostream* stream) notify_title_change.errors_to(stream); } -struct dispatcher<> notify_autohold_reconfigure("autohold_reconfigure"); -struct dispatcher notify_autohold_update("autohold_update"); -struct dispatcher notify_autofire_update("autofire_update"); -struct dispatcher<> notify_close("notify_close"); -struct dispatcher&> notify_set_screen("set_screen"); -struct dispatcher> notify_sound_change("sound_change"); -struct dispatcher<> notify_screen_update("screen_update"); -struct dispatcher<> notify_status_update("status_update"); -struct dispatcher notify_sound_unmute("sound_unmute"); -struct dispatcher notify_mode_change("mode_change"); -struct dispatcher<> notify_core_change("core_change"); -struct dispatcher notify_core_changed("core_changed"); -struct dispatcher<> notify_new_core("new_core"); -struct dispatcher<> notify_voice_stream_change("voice_stream_change"); -struct dispatcher<> notify_vu_change("vu_change"); -struct dispatcher<> notify_subtitle_change("subtitle_change"); -struct dispatcher notify_multitrack_change("multitrack_change"); -struct dispatcher<> notify_title_change("title_change"); \ No newline at end of file +struct dispatch::source<> notify_autohold_reconfigure("autohold_reconfigure"); +struct dispatch::source notify_autohold_update("autohold_update"); +struct dispatch::source notify_autofire_update("autofire_update"); +struct dispatch::source<> notify_close("notify_close"); +struct dispatch::source&> notify_set_screen("set_screen"); +struct dispatch::source> notify_sound_change("sound_change"); +struct dispatch::source<> notify_screen_update("screen_update"); +struct dispatch::source<> notify_status_update("status_update"); +struct dispatch::source notify_sound_unmute("sound_unmute"); +struct dispatch::source notify_mode_change("mode_change"); +struct dispatch::source<> notify_core_change("core_change"); +struct dispatch::source notify_core_changed("core_changed"); +struct dispatch::source<> notify_new_core("new_core"); +struct dispatch::source<> notify_voice_stream_change("voice_stream_change"); +struct dispatch::source<> notify_vu_change("vu_change"); +struct dispatch::source<> notify_subtitle_change("subtitle_change"); +struct dispatch::source notify_multitrack_change("multitrack_change"); +struct dispatch::source<> notify_title_change("title_change"); diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index 5b1fc362..a475695a 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -1017,7 +1017,7 @@ namespace update_movie_state(); } private: - struct dispatch_target<> closenotify; + struct dispatch::target<> closenotify; } mywcb; //If there is a pending load, perform it. Return 1 on successful load, 0 if nothing to load, -1 on load diff --git a/src/core/window.cpp b/src/core/window.cpp index 73599e46..b31f06f4 100644 --- a/src/core/window.cpp +++ b/src/core/window.cpp @@ -526,9 +526,9 @@ namespace setscreen.set(notify_set_screen, [](framebuffer& scr) { our_screen = &scr; }); } private: - struct dispatch_target<> screenupdate; - struct dispatch_target<> statusupdate; - struct dispatch_target&> setscreen; + struct dispatch::target<> screenupdate; + struct dispatch::target<> statusupdate; + struct dispatch::target&> setscreen; } x; } diff --git a/src/library/dispatch.cpp b/src/library/dispatch.cpp index 3e03fba2..3218ce4f 100644 --- a/src/library/dispatch.cpp +++ b/src/library/dispatch.cpp @@ -1,7 +1,10 @@ #include "dispatch.hpp" -mutex_class& dispatch_global_init_lock() +namespace dispatch +{ +mutex_class& global_init_lock() { static mutex_class m; return m; } +} diff --git a/src/platform/wxwidgets/editor-autohold.cpp b/src/platform/wxwidgets/editor-autohold.cpp index 20dd7e6e..2419d0a8 100644 --- a/src/platform/wxwidgets/editor-autohold.cpp +++ b/src/platform/wxwidgets/editor-autohold.cpp @@ -29,9 +29,9 @@ public: void on_wclose(wxCloseEvent& e); void on_checkbox(wxCommandEvent& e); private: - struct dispatch_target ahupdate; - struct dispatch_target afupdate; - struct dispatch_target<> ahreconfigure; + struct dispatch::target ahupdate; + struct dispatch::target afupdate; + struct dispatch::target<> ahreconfigure; struct control_triple { diff --git a/src/platform/wxwidgets/editor-hexedit.cpp b/src/platform/wxwidgets/editor-hexedit.cpp index b3fd485c..372ef66f 100644 --- a/src/platform/wxwidgets/editor-hexedit.cpp +++ b/src/platform/wxwidgets/editor-hexedit.cpp @@ -876,7 +876,7 @@ private: _panel* hpanel; wxMenu* valuemenu; wxMenu* typemenu; - struct dispatch_target corechange; + struct dispatch::target corechange; unsigned current_vma; std::vector vma_names; std::map vma_endians; diff --git a/src/platform/wxwidgets/editor-multitrack.cpp b/src/platform/wxwidgets/editor-multitrack.cpp index 2f95d7de..16797a74 100644 --- a/src/platform/wxwidgets/editor-multitrack.cpp +++ b/src/platform/wxwidgets/editor-multitrack.cpp @@ -40,9 +40,9 @@ public: void on_wclose(wxCloseEvent& e); void on_control(wxCommandEvent& e); private: - struct dispatch_target<> ahreconfigure; - struct dispatch_target ahmodechange; - struct dispatch_target ahmtchange; + struct dispatch::target<> ahreconfigure; + struct dispatch::target ahmodechange; + struct dispatch::target ahmtchange; struct controller_info { unsigned port; diff --git a/src/platform/wxwidgets/editor-subtitles.cpp b/src/platform/wxwidgets/editor-subtitles.cpp index d62d6359..23800247 100644 --- a/src/platform/wxwidgets/editor-subtitles.cpp +++ b/src/platform/wxwidgets/editor-subtitles.cpp @@ -45,7 +45,7 @@ private: wxButton* _delete; wxButton* close; std::map subtexts; - struct dispatch_target<> subchange; + struct dispatch::target<> subchange; }; namespace diff --git a/src/platform/wxwidgets/editor-tasinput.cpp b/src/platform/wxwidgets/editor-tasinput.cpp index 871562c3..f5f2505d 100644 --- a/src/platform/wxwidgets/editor-tasinput.cpp +++ b/src/platform/wxwidgets/editor-tasinput.cpp @@ -93,7 +93,7 @@ public: void on_keyboard_down(wxKeyEvent& e); void call_screen_update(); private: - struct dispatch_target<> ahreconfigure; + struct dispatch::target<> ahreconfigure; struct xypanel; struct control_triple { diff --git a/src/platform/wxwidgets/editor-voicesub.cpp b/src/platform/wxwidgets/editor-voicesub.cpp index 4941ee7c..ef449e98 100644 --- a/src/platform/wxwidgets/editor-voicesub.cpp +++ b/src/platform/wxwidgets/editor-voicesub.cpp @@ -57,8 +57,8 @@ private: wxButton* unloadbutton; wxButton* refreshbutton; wxButton* closebutton; - struct dispatch_target<> corechange; - struct dispatch_target<> vstreamchange; + struct dispatch::target<> corechange; + struct dispatch::target<> vstreamchange; }; wxeditor_voicesub::wxeditor_voicesub(wxWindow* parent) diff --git a/src/platform/wxwidgets/vumeter.cpp b/src/platform/wxwidgets/vumeter.cpp index 0979aaed..91bcc30d 100644 --- a/src/platform/wxwidgets/vumeter.cpp +++ b/src/platform/wxwidgets/vumeter.cpp @@ -202,7 +202,7 @@ private: volatile bool update_sent; bool closing; wxButton* closebutton; - struct dispatch_target<> vulistener; + struct dispatch::target<> vulistener; _vupanel* vupanel; wxStaticText* rate; wxSlider* gamevol; @@ -214,8 +214,8 @@ private: wxComboBox* pdev; wxComboBox* rdev; wxCheckBox* mute; - struct dispatch_target unmuted; - struct dispatch_target> devchange; + struct dispatch::target unmuted; + struct dispatch::target> devchange; }; wxwin_vumeter::wxwin_vumeter(wxWindow* parent)