Thread: [Libufo-commits] ufo-0.5/include/ufo/signals uobjectslot.hpp,1.11,1.12 usignal.hpp,1.10,1.11 uslot.h
Status: Beta
Brought to you by:
schmidtjf
|
From: Johannes S. <sch...@us...> - 2005-09-15 10:22:53
|
Update of /cvsroot/libufo/ufo-0.5/include/ufo/signals In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23786/include/ufo/signals Modified Files: uobjectslot.hpp usignal.hpp uslot.hpp Log Message: Added automatic disconnection from signals if the object of an object slot is destroyed (only if object is derived from UObject). Interesting part is the IsDerivedFrom template (love it :). Implemented USlotNode::notify. Index: usignal.hpp =================================================================== RCS file: /cvsroot/libufo/ufo-0.5/include/ufo/signals/usignal.hpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** usignal.hpp 13 Feb 2005 17:49:29 -0000 1.10 --- usignal.hpp 15 Sep 2005 10:22:44 -0000 1.11 *************** *** 65,68 **** --- 65,82 ---- ++iter) { if ((*iter)->equals(slot)) { + (*iter)->node()->notify(false); + ret = true; + break; + } + } + return ret; + } + protected: + bool final_remove(const USlotBase * slot) { + bool ret = false; + for (SlotIterator iter = _slots.begin(); + iter != _slots.end(); + ++iter) { + if ((*iter)->equals(slot)) { // remove garbage delete (*iter); *************** *** 99,107 **** } void emit() { ! for (SlotIterator next_iter = _slots.begin(), iter = _slots.begin(); ! iter != _slots.end(); iter = next_iter) { ! ++next_iter; InSlotType * slot = static_cast<InSlotType*>(*iter); ! (*slot)(); } } --- 113,125 ---- } void emit() { ! for (SlotIterator iter = _slots.begin();iter != _slots.end();) { InSlotType * slot = static_cast<InSlotType*>(*iter); ! if (!slot->node()->died()) { ! (*slot)(); ! } ! ++iter; ! if (slot->node()->died()) { ! final_remove(slot); ! } } } *************** *** 124,132 **** } void emit(typename UTrait<P1>::ref p1) { ! for (SlotIterator next_iter = _slots.begin(), iter = _slots.begin(); ! iter != _slots.end(); iter = next_iter) { ! ++next_iter; InSlotType * slot = static_cast<InSlotType*>(*iter); ! (*slot)(p1); } } --- 142,154 ---- } void emit(typename UTrait<P1>::ref p1) { ! for (SlotIterator iter = _slots.begin();iter != _slots.end();) { InSlotType * slot = static_cast<InSlotType*>(*iter); ! if (!slot->node()->died()) { ! (*slot)(p1); ! } ! ++iter; ! if (slot->node()->died()) { ! final_remove(slot); ! } } } *************** *** 150,158 **** } void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2) { ! for (SlotIterator next_iter = _slots.begin(), iter = _slots.begin(); ! iter != _slots.end(); iter = next_iter) { ! ++next_iter; InSlotType * slot = static_cast<InSlotType*>(*iter); ! (*slot)(p1, p2); } } --- 172,184 ---- } void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2) { ! for (SlotIterator iter = _slots.begin();iter != _slots.end();) { InSlotType * slot = static_cast<InSlotType*>(*iter); ! if (!slot->node()->died()) { ! (*slot)(p1, p2); ! } ! ++iter; ! if (slot->node()->died()) { ! final_remove(slot); ! } } } *************** *** 178,186 **** void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, typename UTrait<P3>::ref p3) { ! for (SlotIterator next_iter = _slots.begin(), iter = _slots.begin(); ! iter != _slots.end(); iter = next_iter) { ! ++next_iter; InSlotType * slot = static_cast<InSlotType*>(*iter); ! (*slot)(p1, p2, p3); } } --- 204,216 ---- void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, typename UTrait<P3>::ref p3) { ! for (SlotIterator iter = _slots.begin();iter != _slots.end();) { InSlotType * slot = static_cast<InSlotType*>(*iter); ! if (!slot->node()->died()) { ! (*slot)(p1, p2, p3); ! } ! ++iter; ! if (slot->node()->died()) { ! final_remove(slot); ! } } } *************** *** 205,213 **** void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, typename UTrait<P3>::ref p3, typename UTrait<P4>::ref p4) { ! for (SlotIterator next_iter = _slots.begin(), iter = _slots.begin(); ! iter != _slots.end(); iter = next_iter) { ! ++next_iter; InSlotType * slot = static_cast<InSlotType*>(*iter); ! (*slot)(p1, p2, p3, p4); } } --- 235,247 ---- void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, typename UTrait<P3>::ref p3, typename UTrait<P4>::ref p4) { ! for (SlotIterator iter = _slots.begin();iter != _slots.end();) { InSlotType * slot = static_cast<InSlotType*>(*iter); ! if (!slot->node()->died()) { ! (*slot)(p1, p2, p3, p4); ! } ! ++iter; ! if (slot->node()->died()) { ! final_remove(slot); ! } } } Index: uobjectslot.hpp =================================================================== RCS file: /cvsroot/libufo/ufo-0.5/include/ufo/signals/uobjectslot.hpp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** uobjectslot.hpp 13 Feb 2005 17:49:29 -0000 1.11 --- uobjectslot.hpp 15 Sep 2005 10:22:44 -0000 1.12 *************** *** 38,54 **** class UObject; ! // (internal) struct UObjectSlotNode : public USlotNode { typedef void (UObject::*Method)(void); - //typedef void (*Method)(void); void * m_object; Method m_method; ! UObjectSlotNode(ProxyPtr proxy, void * object, Method method) ! : USlotNode(proxy) { ! m_object = object; ! m_method = method; } virtual bool equals(const USlotNode * node) const { --- 38,109 ---- class UObject; ! ! /** A compile time check whether Base is really a base class of Child ! * This is from GotW #71 resp. from "More exceptional C++" ! */ ! ! template<class Child, class Base> ! class IsDerivedFrom { ! private: ! class Yes { char a[1]; }; ! class No { char a[10]; }; ! ! static Yes Test(Base*); // undefined ! static No Test(...); // undefined ! ! public: ! enum { ! Is = sizeof(Test(static_cast<Child*>(0))) == sizeof(Yes) ? 1 : 0 ! }; ! }; ! ! ! /** The slot node for objects. ! * If it is a UObject, does automatic clean up if the UObject pointer gets ! * invalid. ! * @author Johannes Schmidt ! */ struct UObjectSlotNode : public USlotNode { + /** We could use a generic class, but why not simply UObject to cast to. + */ typedef void (UObject::*Method)(void); + /** The object pointer. */ void * m_object; + /** This pointer is only not NULL if the object is derived from UObject.*/ + UObject * m_uobject; + /** The method to call. */ Method m_method; ! /** We need to make this a template for a compile-time check whether ! * object is derived from UObject. ! */ ! template<typename Obj> ! UObjectSlotNode(ProxyPtr proxy, Obj * object, Method method) ! : USlotNode(proxy) ! , m_object(object) ! , m_uobject(NULL) ! , m_method(method) ! { ! if (IsDerivedFrom<Obj, UObject>::Is) { ! m_uobject = reinterpret_cast<UObject*>(object); ! } ! if (m_uobject) { ! m_uobject->m_objectSlots.push_back(this); ! } } + virtual ~UObjectSlotNode() { + if (m_uobject) { + m_uobject->m_objectSlots.remove(this); + } + } + virtual void notify(bool from_child) { + if (!from_child && m_uobject) { + m_uobject->m_objectSlots.remove(this); + } + m_uobject = NULL; + m_object = NULL; + } + virtual bool died() { return (m_object == NULL); } virtual bool equals(const USlotNode * node) const { *************** *** 61,66 **** } } - - virtual ~UObjectSlotNode() {} }; --- 116,119 ---- Index: uslot.hpp =================================================================== RCS file: /cvsroot/libufo/ufo-0.5/include/ufo/signals/uslot.hpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** uslot.hpp 13 Feb 2005 17:49:29 -0000 1.12 --- uslot.hpp 15 Sep 2005 10:22:44 -0000 1.13 *************** *** 43,46 **** --- 43,48 ---- struct UFO_EXPORT USlotNode { + USlotNode() : m_died(false) {} + USlotNode(FuncPtr proxy) : _proxy(proxy), m_died(false) {} virtual ~USlotNode() {} *************** *** 48,52 **** // our shut down. If from_child is true, we do not need // to clean up the child links. ! virtual void notify(bool from_child) {} virtual bool equals(const USlotNode * node) const { return false; } --- 50,57 ---- // our shut down. If from_child is true, we do not need // to clean up the child links. ! virtual void notify(bool from_child) { ! m_died = true; ! } ! virtual bool died() { return m_died; } virtual bool equals(const USlotNode * node) const { return false; } *************** *** 54,61 **** bool connected() { return _proxy != NULL; } ! USlotNode(FuncPtr proxy) : _proxy(proxy) {} ! ! /** A proxy func which does the actual callback calling. */ ProxyPtr _proxy; }; --- 59,69 ---- bool connected() { return _proxy != NULL; } ! public: // Public attributes ! /** A proxy func which does the actual callback calling. ! * FIXME: make this private. ! */ ProxyPtr _proxy; + private: // Private attributes + bool m_died; }; *************** *** 65,69 **** class UFO_EXPORT USlotBase { ! public: USlotBase() : _node(0) {} USlotBase(USlotNode * node) : _node(node) {} --- 73,77 ---- class UFO_EXPORT USlotBase { ! public: USlotBase() : _node(0) {} USlotBase(USlotNode * node) : _node(node) {} *************** *** 101,105 **** typedef void (*Callback)(); typedef void (*Proxy)(void*); ! void operator()() { if (!node()) return; --- 109,113 ---- typedef void (*Callback)(); typedef void (*Proxy)(void*); ! void operator()() { if (!node()) return; *************** *** 115,119 **** public: typedef void (*Proxy)(typename UTrait<P1>::ref, void*); ! void operator ()(typename UTrait<P1>::ref p1) { if (!node()) return; --- 123,127 ---- public: typedef void (*Proxy)(typename UTrait<P1>::ref, void*); ! void operator ()(typename UTrait<P1>::ref p1) { if (!node()) return; *************** *** 129,133 **** public: typedef void (*Proxy)(typename UTrait<P1>::ref, typename UTrait<P2>::ref, void*); ! void operator ()(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2) { if (!node()) return; --- 137,141 ---- public: typedef void (*Proxy)(typename UTrait<P1>::ref, typename UTrait<P2>::ref, void*); ! void operator ()(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2) { if (!node()) return; |