/* 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 namespace PBD { /* named after the Hindu god Shiva, The Destroyer */ template 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::destroy), &receiver)); } ~Shiva() { forget (); } private: sigc::connection _connection; void destroy (ObjectToBeDestroyed* obj) { delete obj; forget (); } void forget () { _connection.disconnect (); } }; template 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::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 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::destroy), &receiver)); /* if the receiver goes away, forget all this nonsense */ _connection2 = receiver.GoingAway.connect (sigc::mem_fun (*this, &PairedShiva::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__ */