diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-21 18:23:07 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-21 18:23:07 +0000 |
commit | f450df300c9c057141a4caf79ff6dbfbf58492d9 (patch) | |
tree | 409f9c56056a337cade83d45ccff47ccdb06dd0c /libs/pbd | |
parent | 738387f9a417537e768d56d3fc4afcb9dc82d66b (diff) |
fully implement and deploy explicit x-thread signal connection syntax (testing comes next)
git-svn-id: svn://localhost/ardour2/branches/3.0@6379 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd')
-rw-r--r-- | libs/pbd/base_ui.cc | 2 | ||||
-rw-r--r-- | libs/pbd/controllable.cc | 2 | ||||
-rw-r--r-- | libs/pbd/event_loop.cc | 19 | ||||
-rw-r--r-- | libs/pbd/pbd/base_ui.h | 4 | ||||
-rw-r--r-- | libs/pbd/pbd/event_loop.h (renamed from libs/pbd/pbd/ui_callback.h) | 18 | ||||
-rw-r--r-- | libs/pbd/pbd/memento_command.h | 2 | ||||
-rw-r--r-- | libs/pbd/pbd/shiva.h | 139 | ||||
-rw-r--r-- | libs/pbd/pbd/signals.h | 98 | ||||
-rw-r--r-- | libs/pbd/ui_callback.cc | 19 | ||||
-rw-r--r-- | libs/pbd/undo.cc | 4 | ||||
-rw-r--r-- | libs/pbd/wscript | 2 |
11 files changed, 116 insertions, 193 deletions
diff --git a/libs/pbd/base_ui.cc b/libs/pbd/base_ui.cc index ea7e469c74..5e856d1ca0 100644 --- a/libs/pbd/base_ui.cc +++ b/libs/pbd/base_ui.cc @@ -70,7 +70,7 @@ BaseUI::new_request_type () void BaseUI::main_thread () { - set_ui_for_thread (this); + set_event_loop_for_thread (this); thread_init (); _main_loop->run (); } diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc index dd0dfd4445..d751c3c80b 100644 --- a/libs/pbd/controllable.cc +++ b/libs/pbd/controllable.cc @@ -62,7 +62,7 @@ Controllable::add (Controllable& ctl) /* Controllable::remove() is static - no need to manage this connection */ - ctl.GoingAway.connect (registry_connections, boost::bind (&Controllable::remove, ref (ctl))); + ctl.GoingAway.connect_same_thread (registry_connections, boost::bind (&Controllable::remove, ref (ctl))); } void diff --git a/libs/pbd/event_loop.cc b/libs/pbd/event_loop.cc new file mode 100644 index 0000000000..3bc4abcbdf --- /dev/null +++ b/libs/pbd/event_loop.cc @@ -0,0 +1,19 @@ +#include "pbd/event_loop.h" + +using namespace PBD; + +Glib::StaticPrivate<EventLoop> EventLoop::thread_event_loop; + +static void do_not_delete_the_loop_pointer (void*) { } + +EventLoop* +EventLoop::get_event_loop_for_thread() { + return thread_event_loop.get (); +} + +void +EventLoop::set_event_loop_for_thread (EventLoop* loop) +{ + thread_event_loop.set (loop, do_not_delete_the_loop_pointer); +} + diff --git a/libs/pbd/pbd/base_ui.h b/libs/pbd/pbd/base_ui.h index 2bfaa11be0..9e88be60f2 100644 --- a/libs/pbd/pbd/base_ui.h +++ b/libs/pbd/pbd/base_ui.h @@ -30,9 +30,9 @@ #include <glibmm/main.h> #include "pbd/crossthread.h" -#include "pbd/ui_callback.h" +#include "pbd/event_loop.h" -class BaseUI : virtual public sigc::trackable, public PBD::UICallback +class BaseUI : virtual public sigc::trackable, public PBD::EventLoop { public: BaseUI (const std::string& name); diff --git a/libs/pbd/pbd/ui_callback.h b/libs/pbd/pbd/event_loop.h index 8574de0dec..be98fcd852 100644 --- a/libs/pbd/pbd/ui_callback.h +++ b/libs/pbd/pbd/event_loop.h @@ -17,8 +17,8 @@ */ -#ifndef __pbd_ui_callback_h__ -#define __pbd_ui_callback_h__ +#ifndef __pbd_event_loop_h__ +#define __pbd_event_loop_h__ #include <boost/function.hpp> #include <boost/bind.hpp> /* we don't need this here, but anything calling call_slot() probably will, so this is convenient */ @@ -27,22 +27,22 @@ namespace PBD { -class UICallback +class EventLoop { public: - UICallback() {} - virtual ~UICallback() {} + EventLoop() {} + virtual ~EventLoop() {} virtual void call_slot (const boost::function<void()>&) = 0; - static UICallback* get_ui_for_thread(); - static void set_ui_for_thread (UICallback* ui); + static EventLoop* get_event_loop_for_thread(); + static void set_event_loop_for_thread (EventLoop* ui); private: - static Glib::StaticPrivate<UICallback> thread_ui; + static Glib::StaticPrivate<EventLoop> thread_event_loop; }; } -#endif /* __pbd_ui_callback_h__ */ +#endif /* __pbd_event_loop_h__ */ diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h index b87f784334..a08d3bb717 100644 --- a/libs/pbd/pbd/memento_command.h +++ b/libs/pbd/pbd/memento_command.h @@ -42,7 +42,7 @@ public: : obj(a_object), before(a_before), after(a_after) { /* if the object dies, make sure that we die and that everyone knows about it */ - obj.GoingAway.connect (obj_death_connection, boost::bind (&MementoCommand::object_died, this)); + obj.GoingAway.connect_same_thread (obj_death_connection, boost::bind (&MementoCommand::object_died, this)); } ~MementoCommand () { diff --git a/libs/pbd/pbd/shiva.h b/libs/pbd/pbd/shiva.h deleted file mode 100644 index 90adad6250..0000000000 --- a/libs/pbd/pbd/shiva.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __pbd_shiva_h__ -#define __pbd_shiva_h__ - -#include <sigc++/sigc++.h> - -namespace PBD { - -/* named after the Hindu god Shiva, The Destroyer */ - -template<typename ObjectWithGoingAway, typename ObjectToBeDestroyed> -class Shiva : public sigc::trackable -{ - public: - Shiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver) { - - /* if the emitter goes away, destroy the receiver */ - - _connection = emitter.GoingAway.connect - (sigc::bind (sigc::mem_fun - (*this, &Shiva<ObjectWithGoingAway,ObjectToBeDestroyed>::destroy), - &receiver)); - } - - ~Shiva() { - forget (); - } - - private: - sigc::connection _connection; - - void destroy (ObjectToBeDestroyed* obj) { - delete obj; - forget (); - } - - void forget () { - _connection.disconnect (); - } - -}; - -template<typename ObjectWithGoingAway, typename ObjectToBeDestroyed> -class ProxyShiva : public sigc::trackable -{ - public: - ProxyShiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver, void (*callback)(ObjectToBeDestroyed*, ObjectWithGoingAway*)) { - - /* if the emitter goes away, destroy the receiver */ - - _callback = callback; - _callback_argument = &emitter; - - _connection = emitter.GoingAway.connect - (sigc::bind (sigc::mem_fun - (*this, &ProxyShiva<ObjectWithGoingAway,ObjectToBeDestroyed>::destroy), - &receiver)); - } - - ~ProxyShiva () { - forget (); - } - - private: - sigc::connection _connection; - void (*_callback) (ObjectToBeDestroyed*, ObjectWithGoingAway*); - ObjectWithGoingAway* _callback_argument; - - void destroy (ObjectToBeDestroyed* obj) { - /* callback must destroy obj if appropriate, not done here */ - _callback (obj, _callback_argument); - forget (); - } - - void forget () { - _connection.disconnect (); - } -}; - -template<typename ObjectWithGoingAway, typename ObjectToBeDestroyed> -class PairedShiva : public sigc::trackable -{ - public: - PairedShiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver) { - - /* if the emitter goes away, destroy the receiver */ - - _connection1 = emitter.GoingAway.connect - (sigc::bind (sigc::mem_fun - (*this, &PairedShiva<ObjectWithGoingAway,ObjectToBeDestroyed>::destroy), - &receiver)); - - /* if the receiver goes away, forget all this nonsense */ - - _connection2 = receiver.GoingAway.connect - (sigc::mem_fun (*this, &PairedShiva<ObjectWithGoingAway,ObjectToBeDestroyed>::forget)); - } - - ~PairedShiva() { - forget (); - } - - private: - sigc::connection _connection1; - sigc::connection _connection2; - - void destroy (ObjectToBeDestroyed* obj) { - delete obj; - forget (); - } - - void forget () { - _connection1.disconnect (); - _connection2.disconnect (); - } - -}; - -} - -#endif /* __pbd_shiva_h__ */ diff --git a/libs/pbd/pbd/signals.h b/libs/pbd/pbd/signals.h index 47e8d143bc..0b44ee8051 100644 --- a/libs/pbd/pbd/signals.h +++ b/libs/pbd/pbd/signals.h @@ -22,8 +22,13 @@ #include <list> #include <glibmm/thread.h> + #include <boost/signals2.hpp> #include <boost/noncopyable.hpp> +#include <boost/bind.hpp> +#include <boost/bind/protect.hpp> + +#include "pbd/event_loop.h" namespace PBD { @@ -40,10 +45,6 @@ class ScopedConnectionList : public boost::noncopyable void add_connection (const UnscopedConnection& c); void drop_connections (); - template<typename S> void scoped_connect (S& sig, const typename S::slot_function_type& sf) { - add_connection (sig.connect (sf)); - } - private: /* this class is not copyable */ ScopedConnectionList(const ScopedConnectionList&); @@ -76,14 +77,26 @@ public: Signal0 () {} typedef boost::signals2::signal<R()> SignalType; - void connect (ScopedConnectionList& clist, + void connect_same_thread (Connection& c, + const typename SignalType::slot_function_type& slot) { + c = _signal.connect (slot); + } + + void connect_same_thread (ScopedConnectionList& clist, const typename SignalType::slot_function_type& slot) { clist.add_connection (_signal.connect (slot)); } + + void connect (ScopedConnectionList& clist, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + clist.add_connection (_signal.connect (boost::bind (&EventLoop::call_slot, event_loop, slot))); + } void connect (Connection& c, - const typename SignalType::slot_function_type& slot) { - c = _signal.connect (slot); + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + c = _signal.connect (boost::bind (&EventLoop::call_slot, event_loop, slot)); } typename SignalType::result_type operator()() { @@ -100,15 +113,32 @@ public: Signal1 () {} typedef boost::signals2::signal<R(A)> SignalType; - void connect (ScopedConnectionList& clist, + void connect_same_thread (ScopedConnectionList& clist, const typename SignalType::slot_function_type& slot) { clist.add_connection (_signal.connect (slot)); } - void connect (Connection& c, - const typename SignalType::slot_function_type& slot) { + void connect_same_thread (Connection& c, + const typename SignalType::slot_function_type& slot) { c = _signal.connect (slot); } + + static void compositor (typename boost::function<void(A)> f, EventLoop* event_loop, A arg) { + event_loop->call_slot (boost::bind (f, arg)); + } + + void connect (ScopedConnectionList& clist, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1))); + } + + void connect (Connection& c, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + c = _signal.connect (boost::bind (&compositor, slot, event_loop, _1)); + + } typename SignalType::result_type operator()(A arg1) { return _signal (arg1); @@ -124,16 +154,32 @@ public: Signal2 () {} typedef boost::signals2::signal<R(A1, A2)> SignalType; - void connect (ScopedConnectionList& clist, + void connect_same_thread (ScopedConnectionList& clist, const typename SignalType::slot_function_type& slot) { clist.add_connection (_signal.connect (slot)); } - - void connect (Connection& c, - const typename SignalType::slot_function_type& slot) { + + void connect_same_thread (Connection& c, + const typename SignalType::slot_function_type& slot) { c = _signal.connect (slot); } - + + static void compositor (typename boost::function<void(A1,A2)> f, PBD::EventLoop* event_loop, A1 arg1, A2 arg2) { + event_loop->call_slot (boost::bind (f, arg1, arg2)); + } + + void connect (ScopedConnectionList& clist, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2))); + } + + void connect (Connection& c, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + c = _signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2)); + } + typename SignalType::result_type operator()(A1 arg1, A2 arg2) { return _signal (arg1, arg2); } @@ -148,14 +194,30 @@ public: Signal3 () {} typedef boost::signals2::signal<R(A1,A2,A3)> SignalType; - void connect (ScopedConnectionList& clist, + void connect_same_thread (ScopedConnectionList& clist, const typename SignalType::slot_function_type& slot) { clist.add_connection (_signal.connect (slot)); } + + void connect_same_thread (Connection& c, + const typename SignalType::slot_function_type& slot) { + c = _signal.connect (slot); + } + + static void compositor (typename boost::function<void(A1,A2,A3)> f, PBD::EventLoop* event_loop, A1 arg1, A2 arg2, A3 arg3) { + event_loop->call_slot (boost::bind (f, arg1, arg2, arg3)); + } + + void connect (ScopedConnectionList& clist, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3))); + } void connect (Connection& c, - const typename SignalType::slot_function_type& slot) { - c = _signal.connect (slot); + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + c = _signal.connect (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3))); } typename SignalType::result_type operator()(A1 arg1, A2 arg2, A3 arg3) { diff --git a/libs/pbd/ui_callback.cc b/libs/pbd/ui_callback.cc deleted file mode 100644 index 9a8feb3d2c..0000000000 --- a/libs/pbd/ui_callback.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "pbd/ui_callback.h" - -using namespace PBD; - -Glib::StaticPrivate<UICallback> UICallback::thread_ui; - -static void do_not_delete_the_ui_pointer (void*) { } - -UICallback* -UICallback::get_ui_for_thread() { - return thread_ui.get (); -} - -void -UICallback::set_ui_for_thread (UICallback* ui) -{ - thread_ui.set (ui, do_not_delete_the_ui_pointer); -} - diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc index 1a2574ae28..81e31f3a88 100644 --- a/libs/pbd/undo.cc +++ b/libs/pbd/undo.cc @@ -83,7 +83,7 @@ UndoTransaction::add_command (Command *const action) so there is no need to manage this connection. */ - action->GoingAway.connect (*this, boost::bind (&command_death, this, action)); + action->GoingAway.connect_same_thread (*this, boost::bind (&command_death, this, action)); actions.push_back (action); } @@ -186,7 +186,7 @@ UndoHistory::add (UndoTransaction* const ut) { uint32_t current_depth = UndoList.size(); - ut->GoingAway.connect (*this, boost::bind (&UndoHistory::remove, this, ut)); + ut->GoingAway.connect_same_thread (*this, boost::bind (&UndoHistory::remove, this, ut)); /* if the current undo history is larger than or equal to the currently requested depth, then pop off at least 1 element to make space diff --git a/libs/pbd/wscript b/libs/pbd/wscript index d7e456ada7..b25d8059ce 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -59,6 +59,7 @@ def build(bld): controllable.cc crossthread.cc enumwriter.cc + event_loop.cc dmalloc.cc error.cc filesystem.cc @@ -82,7 +83,6 @@ def build(bld): strsplit.cc textreceiver.cc transmitter.cc - ui_callback.cc undo.cc uuid.cc version.cc |