From f14e3abe3de4317c53953d26d7a2b39c2ff67dab Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 10 Aug 2011 21:31:24 +1000 Subject: [PATCH] Add cookies for selective signal disconnection --- signal.hpp | 63 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/signal.hpp b/signal.hpp index f4108ae4..ea184d9f 100644 --- a/signal.hpp +++ b/signal.hpp @@ -20,8 +20,11 @@ #ifndef __SIGNAL_HPP #define __SIGNAL_HPP +#include "debug.hpp" +#include "nocopy.hpp" + #include -#include +#include #include namespace util { @@ -32,36 +35,60 @@ namespace util { typedef std::function callback_object; protected: - std::vector m_children; + typedef std::list group; + group m_children; + + public: + typedef typename group::iterator cookie; + struct scoped_cookie : public nocopy { + cookie m_cookie; + signal& m_parent; + + scoped_cookie (cookie _cookie, + signal &_parent): + m_cookie (_cookie), + m_parent (_parent) + { ; } + + scoped_cookie (scoped_cookie &&rhs): + m_cookie (rhs.m_cookie), + m_parent (rhs.m_parent) + { + rhs.m_cookie = rhs.m_parent.m_children.end (); + } + + ~scoped_cookie () { + if (m_parent.m_children.end () != m_cookie) + m_parent.disconnect (m_cookie); + } + }; public: signal () - { m_children.reserve (16); } + { /*m_children.reserve (16);*/ } + /// Add a callback to list. - void connect (callback_object _cb) - { m_children.push_back (_cb); } + const cookie + connect (const callback_object &_cb) + { return m_children.insert (m_children.end (), _cb); } + /// Add a callback to the list. - void connect (callback_function _cb) - { m_children.push_back (_cb); } + const cookie + connect (const callback_function &_cb) + { return m_children.insert (m_children.end (), _cb); } - /// Remove all instances of callback `cb' - //void disconnect (callback_function _cb) - // { disconnect (callback_object (_cb)); } - /// Remove all instances of callback `cb' - /*void disconnect (callback_object _cb) { - m_children.erase (std::remove (m_children.begin (), - m_children.end (), - _cb), - m_children.end ()); - }*/ + void disconnect (const cookie _cb) + { m_children.erase (_cb); } + /// Disconnect all callbacks - void clear (void) + void clear (void) { m_children.clear (); } + /// Returns the number of callbacks connected. unsigned int size (void) const { return m_children.size (); }