X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpbd%2Fshiva.h;h=53b613ea2b0cc14e1f66e1a096a477d31145b5f6;hb=17469ea0e3607ef954f415cb2429893315d49898;hp=5110f483324b950485c4e8517edaa817fc8ba504;hpb=0c31e4c4f3d0bfe37d26a793c934f1b436f8fa0f;p=ardour.git diff --git a/libs/pbd/pbd/shiva.h b/libs/pbd/pbd/shiva.h index 5110f48332..53b613ea2b 100644 --- a/libs/pbd/pbd/shiva.h +++ b/libs/pbd/pbd/shiva.h @@ -5,28 +5,96 @@ namespace PBD { -template - /* named after the Hindu god Shiva, The Destroyer */ +template class Shiva { public: Shiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver) { /* if the emitter goes away, destroy the receiver */ - _connection1 = emitter.GoingAway.connect + _connection = emitter.GoingAway.connect (sigc::bind (sigc::mem_fun (*this, &Shiva::destroy), &receiver)); + } + + ~Shiva() { + forget (); + } + + private: + sigc::connection _connection; + + void destroy (ObjectToBeDestroyed* obj) { + delete obj; + forget (); + } + + void forget () { + _connection.disconnect (); + } + +}; + +template +class ProxyShiva { + public: + ProxyShiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver, void (*callback)(ObjectToBeDestroyed*, ObjectWithGoingAway*)) { + + /* if the emitter goes away, destroy the receiver */ + + _callback = callback; + _callback_argument1 = &receiver; + _callback_argument2 = &emitter; + + _connection = emitter.GoingAway.connect + (sigc::bind (sigc::mem_fun + (*this, &ProxyShiva::destroy), + &receiver)); + } + + ~ProxyShiva() { + forget (); + } + + private: + sigc::connection _connection; + void (*_callback) (ObjectToBeDestroyed*, ObjectWithGoingAway*); + ObjectToBeDestroyed* _callback_argument1; + ObjectWithGoingAway* _callback_argument2; + + void destroy (ObjectToBeDestroyed* obj) { + /* callback must destroy obj if appropriate, not done here */ + _callback (obj, _callback_argument2); + forget (); + } + + void forget () { + _connection.disconnect (); + } +}; + +template +class PairedShiva { + 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::destroy), + &receiver)); /* if the receiver goes away, forget all this nonsense */ _connection2 = receiver.GoingAway.connect - (sigc::mem_fun (*this, &Shiva::forget)); + (sigc::mem_fun (*this, &PairedShiva::forget)); } - ~Shiva() { + ~PairedShiva() { forget (); }