Add cookies for selective signal disconnection

This commit is contained in:
Danny Robson 2011-08-10 21:31:24 +10:00
parent 10c6a22df1
commit f14e3abe3d

View File

@ -20,8 +20,11 @@
#ifndef __SIGNAL_HPP #ifndef __SIGNAL_HPP
#define __SIGNAL_HPP #define __SIGNAL_HPP
#include "debug.hpp"
#include "nocopy.hpp"
#include <algorithm> #include <algorithm>
#include <vector> #include <list>
#include <functional> #include <functional>
namespace util { namespace util {
@ -32,36 +35,60 @@ namespace util {
typedef std::function<Ret(Args...)> callback_object; typedef std::function<Ret(Args...)> callback_object;
protected: protected:
std::vector<callback_object> m_children; typedef std::list<callback_object> group;
group m_children;
public:
typedef typename group::iterator cookie;
struct scoped_cookie : public nocopy {
cookie m_cookie;
signal<Ret, Args...>& m_parent;
scoped_cookie (cookie _cookie,
signal<Ret, Args...> &_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: public:
signal () signal ()
{ m_children.reserve (16); } { /*m_children.reserve (16);*/ }
/// Add a callback to list. /// Add a callback to list.
void connect (callback_object _cb) const cookie
{ m_children.push_back (_cb); } connect (const callback_object &_cb)
{ return m_children.insert (m_children.end (), _cb); }
/// Add a callback to the list. /// Add a callback to the list.
void connect (callback_function _cb) const cookie
{ m_children.push_back (_cb); } 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 (const cookie _cb)
/*void disconnect (callback_object _cb) { { m_children.erase (_cb); }
m_children.erase (std::remove (m_children.begin (),
m_children.end (),
_cb),
m_children.end ());
}*/
/// Disconnect all callbacks /// Disconnect all callbacks
void clear (void) void clear (void)
{ m_children.clear (); } { m_children.clear (); }
/// Returns the number of callbacks connected. /// Returns the number of callbacks connected.
unsigned int size (void) const unsigned int size (void) const
{ return m_children.size (); } { return m_children.size (); }