all repos — fluxbox @ 9ad388c5bf160c8a6c90d76065286540274685fd

custom fork of the fluxbox windowmanager

Added Tracker interface for SignalHolder.

This is used by SignalTracker so Signals can disconnect from it when
they die.
Henrik Kinnunen fluxgen@fluxbox.org
commit

9ad388c5bf160c8a6c90d76065286540274685fd

parent

1cae9f22f8aa459e781a62387c19a03b2b8d6ee9

1 files changed, 40 insertions(+), 3 deletions(-)

jump to
M src/FbTk/Signal.hhsrc/FbTk/Signal.hh

@@ -26,6 +26,7 @@ #include "Slot.hh"

#include <list> #include <map> #include <vector> +#include <set> namespace FbTk {

@@ -39,6 +40,14 @@ * handled by the child class so it can do the type checking.

*/ class SignalHolder { public: + /// Special tracker interface used by SignalTracker. + class Tracker { + public: + virtual ~Tracker() { } + /// Disconnect this holder. + virtual void disconnect(SignalHolder& signal) = 0; + }; + /// Do not use this type outside this class typedef std::list<SlotHolder> SlotList;

@@ -46,7 +55,14 @@ typedef SlotList::iterator Iterator;

typedef Iterator SlotID; typedef SlotList::const_iterator ConstIterator; - ~SignalHolder() { } + ~SignalHolder() { + // Disconnect this holder from all trackers. + for (Trackers::iterator it = m_trackers.begin(), + it_end = m_trackers.end(); + it != it_end; ++it ) { + (*it)->disconnect(*this); + } + } /// Remove a specific slot \c id from this signal void disconnect(SlotID slotIt) {

@@ -59,6 +75,14 @@ void clear() {

m_slots.clear(); } + void connectTracker(SignalHolder::Tracker& tracker) { + m_trackers.insert(&tracker); + } + + void disconnectTracker(SignalHolder::Tracker& tracker) { + m_trackers.erase(&tracker); + } + protected: ConstIterator begin() const { return m_slots.begin(); } ConstIterator end() const { return m_slots.end(); }

@@ -72,7 +96,9 @@ return m_slots.insert(m_slots.end(), slot);

} private: + typedef std::set<Tracker*> Trackers; SlotList m_slots; ///< all slots connected to a signal + Trackers m_trackers; ///< all instances that tracks this signal. }; /// Signal with no argument

@@ -188,7 +214,7 @@ /**

* Tracks a signal during it's life time. All signals connected using \c * SignalTracker::join will be erased when this instance dies. */ -class SignalTracker { +class SignalTracker: public SigImpl::SignalHolder::Tracker { public: /// Internal type, do not use. typedef std::map<SigImpl::SignalHolder*,

@@ -200,7 +226,7 @@ leaveAll();

} /// Starts tracking a signal. - /// @return A tracking ID ( not unique ) + /// @return A tracking ID template <typename Signal, typename Functor> TrackID join(Signal& sig, const Functor& functor) { ValueType value = ValueType(&sig, sig.connect(functor));

@@ -209,6 +235,9 @@ if ( !ret.second ) {

// failed to insert this functor sig.disconnect(value.second); } + + sig.connectTracker(*this); + return ret.first; }

@@ -239,8 +268,16 @@ // in some strange cases get a call to this again

ValueType tmp = *conIt; m_connections.erase(conIt); tmp.first->disconnect(tmp.second); + tmp.first->disconnectTracker(*this); } } + +protected: + + void disconnect(SigImpl::SignalHolder& signal) { + m_connections.erase(&signal); + } + private: typedef Connections::value_type ValueType; typedef Connections::iterator Iterator;