// Delegate.h #pragma once //----------------------------------------------------------------------------- // 注: 我把 dynamic_cast 改成了 static_cast, 因为 dynamic_cast 需要RTTI // 但因为IsEqual是比较成员函数的地址,所以即使用 static_cast 也是正确的. //----------------------------------------------------------------------------- #define NewDelegateStatic(staticFunc) \ new StaticDelegateHandler ((StaticDelegateHandler::pStaticFunctor)staticFunc, #staticFunc"") #define NewDelegate(theClass, instance, memberFunc) \ new ClassDelegateHandler (instance, (ClassDelegateHandler::classMember) (theClass::memberFunc), #theClass"::"#memberFunc) #define MAXLEN_DELEGATE_NAME 64 class DelegateArgs; class DelegateHandler; void OnDelegateInvokeFailed (const DelegateHandler * h); // // Arguments of a Delegate // You are supposed to derive this class to include // more informations regarding the delegate class DelegateArgs { public: DelegateArgs () { } virtual ~DelegateArgs () { } }; // // this the base DelegateHandler which is the static/member function that is called // class DelegateHandler { public: inline DelegateHandler () { m_Name[0] = 0; } inline DelegateHandler (const char * Name) { strncpy (m_Name, Name, sizeof(m_Name)-1); } inline void operator () (const void * sender, DelegateArgs * arg) { Invoke (sender, arg); } virtual void Invoke (const void * sender, DelegateArgs * arg) = 0; virtual int IsEqual (const DelegateHandler & handler) const = 0; virtual bool IsEmpty (void) const = 0; virtual DelegateHandler * Clone (void) const = 0; public: char m_Name [MAXLEN_DELEGATE_NAME]; }; // // static functions as handlers // class StaticDelegateHandler : public DelegateHandler { public: typedef void (* pStaticFunctor) (const void *, DelegateArgs *); inline StaticDelegateHandler (pStaticFunctor functor) { m_pStaticFunctor = functor; } inline StaticDelegateHandler (pStaticFunctor functor, const char * Name) : DelegateHandler (Name) { m_pStaticFunctor = functor; } inline virtual void Invoke (const void * sender, DelegateArgs * arg) { #ifndef _DEBUG try #endif { m_pStaticFunctor (sender, arg); } #ifndef _DEBUG catch (...) { Beep (1000, 1000); OnDelegateInvokeFailed (this); } #endif } inline virtual int IsEqual (const DelegateHandler & handler) const { // const StaticDelegateHandler * staticHandler = dynamic_cast (& handler); const StaticDelegateHandler * staticHandler = static_cast (& handler); if (staticHandler != 0) { return (staticHandler->m_pStaticFunctor == m_pStaticFunctor); } return false; } inline virtual bool IsEmpty (void) const { return (m_pStaticFunctor == NULL); } inline virtual DelegateHandler * Clone (void) const { StaticDelegateHandler * p; if (m_Name[0]) p = new StaticDelegateHandler (m_pStaticFunctor, m_Name); else p = new StaticDelegateHandler (m_pStaticFunctor); return p; } protected: pStaticFunctor m_pStaticFunctor; }; // // member function as handlers // template class ClassDelegateHandler : public DelegateHandler { public: typedef void (T::*classMember) (const void *, DelegateArgs *); inline ClassDelegateHandler (T * pthis, classMember functor) { m_pthis = pthis; m_classMember = functor; } inline ClassDelegateHandler (T * pthis, classMember functor, const char * Name) : DelegateHandler (Name) { m_pthis = pthis; m_classMember = functor; } inline virtual void Invoke (const void * sender, DelegateArgs * arg) { #ifndef _DEBUG try #endif { (* m_pthis.*m_classMember) (sender, arg); } #ifndef _DEBUG catch (...) { Beep (1000, 1000); OnDelegateInvokeFailed (this); } #endif } inline virtual int IsEqual (const DelegateHandler & handler) const { // const ClassDelegateHandler * classHandler = dynamic_cast ( &handler); const ClassDelegateHandler * classHandler = static_cast (& handler); if (classHandler != 0) { return (classHandler->m_classMember == m_classMember && m_pthis == classHandler->m_pthis); } return false; } inline virtual bool IsEmpty (void) const { return (m_classMember == NULL); } inline virtual DelegateHandler * Clone (void) const { class ClassDelegateHandler * p; if (m_Name[0]) p = new ClassDelegateHandler (m_pthis, m_classMember, m_Name); else p = new ClassDelegateHandler (m_pthis, m_classMember); return p; } const T * GetClassInstance (void) const { return m_pthis; } T * GetClassInstance (void) { return m_pthis; } protected: classMember m_classMember; T * m_pthis; };