#pragma once // // a delegate // class UnsafeDelegate { public: inline UnsafeDelegate () { m_DelegateID [0] = 0; m_bTrace = true; } inline UnsafeDelegate (const char * DelegateID) { strncpy (m_DelegateID, DelegateID, sizeof(m_DelegateID)); m_bTrace = true; } inline virtual ~UnsafeDelegate () { RemoveAll (); } inline virtual void AddDelegateHandler (DelegateHandler * handler) { try { if (! IsExist (handler)) m_handlers.Add (handler); else delete handler; } catch (...) { } } inline UnsafeDelegate & operator += (DelegateHandler * handler) { AddDelegateHandler (handler); return *this; } inline virtual void RemoveDelegateHandler (DelegateHandler * handler) { try { RemoveHandler (handler); delete handler; } catch (...) { } } inline UnsafeDelegate & operator -= (DelegateHandler * handler) { RemoveDelegateHandler (handler); return *this; } inline void operator () (const void * sender, DelegateArgs * arg) { Invoke (sender, arg); } inline virtual void Invoke (const void * sender, DelegateArgs * arg) { int Size = GetSize (); if (Size == 0) return; if (m_bTrace) { if (m_DelegateID[0]) _info ("Invoking Delegate %s, total %d handles", m_DelegateID, Size); else _info ("Invoking Delegate 0x%0x, total %d handles", this, Size); } if (Size <= DelegateMaxHandler) { DelegateHandler * arTemp [DelegateMaxHandler]; const Array & ar = m_handlers; int NbOfElem = ar.CopyTo (arTemp, DelegateMaxHandler); for (int Index=0; Indexm_Name[0]) msg = h->m_Name; else msg.Format ("0x%0x", h); _tinfo ("Invoking " + msg); } h->Invoke (sender, arg); if (m_bTrace) _tinfo ("Invoked " + msg); } #ifndef _DEBUG catch (...) { Beep (1000, 1000); OnDelegateInvokeFailed (h); } #endif } } else { FixArray arTemp (m_handlers.GetSize ()); const Array & ar = m_handlers; int NbOfElem = ar.CopyTo (arTemp); for (int Index=0; Indexm_Name[0]) msg = h->m_Name; else msg.Format ("0x%0x", h); _tinfo ("Invoking " + msg); } h->Invoke (sender, arg); if (m_bTrace) _tinfo ("Invoked " + msg); } #ifndef _DEBUG catch (...) { Beep (1000, 1000); OnDelegateInvokeFailed (h); } #endif } } } inline int GetSize () const { return m_handlers.GetSize (); } inline bool IsEmpty () const { return m_handlers.IsEmpty (); } inline bool IsExist (const DelegateHandler * handler) const { for (ArrayOfPtr ::Iterator Iter (m_handlers); Iter; Iter++) { DelegateHandler * curHandler = Iter (); if (curHandler->IsEqual (* handler)) return true; } return false; } inline void RemoveAll () { m_handlers.RemoveAll (); } inline virtual void AddFirst (DelegateHandler * handler) { try { if (! IsExist (handler)) m_handlers.InsertFirst (handler); else delete handler; } catch (...) { } } inline virtual void AddLast (DelegateHandler * handler) { try { if (! IsExist (handler)) m_handlers.InsertLast (handler); else delete handler; } catch (...) { } } template void ForEach (pfnForEach pFunction) { int Size = GetSize (); if (Size == 0) return; DelegateHandler * arTemp [DelegateMaxHandler]; int NbOfElem = m_handlers.CopyTo (arTemp, DelegateMaxHandler); for (int Index=0; Index void ForEach (T * t, classForEach pFunction) { int Size = GetSize (); if (Size == 0) return; DelegateHandler * arTemp [DelegateMaxHandler]; int NbOfElem = m_handlers.CopyTo (arTemp, DelegateMaxHandler); for (int Index=0; Index void ForEach (pfnForEach pFunction, Parameter para) { int Size = GetSize (); if (Size == 0) return; DelegateHandler * arTemp [DelegateMaxHandler]; int NbOfElem = m_handlers.CopyTo (arTemp, DelegateMaxHandler); for (int Index=0; Index & toArray) { m_handlers.TransferTo (toArray); return toArray.GetSize (); } inline int TransferFrom (Array & fromArray) { fromArray.TransferTo (m_handlers); return m_handlers.GetSize (); } inline int CopyTo (Array & toArray) const { for (ArrayOfPtr ::Iterator Iter (m_handlers); Iter; Iter++) { DelegateHandler * h = Iter (); toArray.Add (h->Clone ()); } return toArray.GetSize (); } inline int CopyTo (UnsafeDelegate & toDelegate) const { for (ArrayOfPtr ::Iterator Iter (m_handlers); Iter; Iter++) { DelegateHandler * h = Iter (); toDelegate.AddDelegateHandler (h->Clone ()); } return toDelegate.GetSize (); } inline DString GetDelegateID (void) const { return m_DelegateID; } DString ToString (void) const; virtual void SetTrace (bool bEnable) { m_bTrace = bEnable; } protected: inline bool RemoveHandler (const DelegateHandler * handler) { for (ArrayOfPtr ::Iterator Iter (m_handlers); Iter; Iter++) { DelegateHandler * curHandler = Iter (); if (curHandler->IsEqual (* handler)) { m_handlers.RemoveAt (Iter); return true; } } return false; } protected: char m_DelegateID [64]; ArrayOfPtr m_handlers; bool m_bTrace; protected: static const int DelegateMaxHandler = 64; };