#include <boost/asio.hpp>
#include <boost/thread.hpp>
+/** A class to allow signals to be emitted from non-UI threads and handled
+ * by a UI thread.
+ */
class UISignaller
{
public:
{
_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 <typename T>
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;
};