X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fui_signaller.h;h=221bcbe9581ad2cdfaacdcaaeabf4487ab6e6723;hb=7f203e4df9ca94a44099c26158c6c81b5299567f;hp=6b0e73c601fa6e8360ab6c48904e64bae3b6671e;hpb=17830349b580b5933589f2b739671828b5cfc208;p=dcpomatic.git diff --git a/src/lib/ui_signaller.h b/src/lib/ui_signaller.h index 6b0e73c60..221bcbe95 100644 --- a/src/lib/ui_signaller.h +++ b/src/lib/ui_signaller.h @@ -22,28 +22,53 @@ #include #include +#include +/** A class to allow signals to be emitted from non-UI threads and handled + * by a UI thread. + */ class UISignaller { public: + /** Create a UISignaller. Must be called from the UI thread */ UISignaller () : _work (_service) - {} - - template - void emit (S signal) { - _service.post (boost::bind (boost::ref (signal))); + { + _ui_thread = boost::this_thread::get_id (); } + /** Emit a signal from any thread whose handlers will be called in the UI + * thread. Use something like: + * + * ui_signaller->emit (boost::bind (boost::ref (SomeSignal), parameter)); + */ + template + void emit (T f) { + if (boost::this_thread::get_id() == _ui_thread) { + /* already in the UI thread */ + f (); + } else { + /* non-UI thread; post to the service and wake up the UI */ + _service.post (f); + wake_ui (); + } + } + + /** Call this in the UI when it is idle */ void ui_idle () { _service.poll (); } + /** This should wake the UI and make it call ui_idle() */ virtual void wake_ui () = 0; private: + /** A io_service which is used as the conduit for messages */ boost::asio::io_service _service; + /** Object required to keep io_service from stopping when it has nothing to do */ boost::asio::io_service::work _work; + /** The UI thread's ID */ + boost::thread::id _ui_thread; }; extern UISignaller* ui_signaller;