#include #define COMBINE(a,b) COMBINE1(a,b) #define COMBINE1(a,b) a##b #define COMBINE3(a,b,c) COMBINE3(a,b,c) #define COMBINE31(a,b,c) a##b##c #define I_DELEGATE COMBINE(Delegate, SUFFIX) #define I_EVENT COMBINE(Event, SUFFIX) #define C_STATIC_DELEGATE COMBINE(StaticDelegate, SUFFIX) #define C_METHOD_DELEGATE COMBINE(MethodDelegate, SUFFIX) template class I_DELEGATE : public CDelegate { public: virtual ~I_DELEGATE(){} virtual TRet Invoke(PARAMS) = 0; virtual bool Compare(I_DELEGATE* other) = 0; }; template class C_STATIC_DELEGATE : public I_DELEGATE { public: typedef TRet (*Func)(PARAMS); C_STATIC_DELEGATE(Func func) { pFunc = func; } C_STATIC_DELEGATE(const C_STATIC_DELEGATE& other) { pFunc = other.pFunc; } const C_STATIC_DELEGATE& operator=(const C_STATIC_DELEGATE& other) { this->pFunc = other.pFunc; return *this; } virtual TRet Invoke(PARAMS) { return pFunc(ARGS); } virtual bool Compare(I_DELEGATE* other) { return true; } private: Func pFunc; }; template class C_METHOD_DELEGATE : public I_DELEGATE { public: typedef TRet (TBase::*Func)(PARAMS); C_METHOD_DELEGATE(TBase* base, Func func) { pBase = base; pFunc = func; } C_METHOD_DELEGATE(const C_METHOD_DELEGATE& other) { pBase = other.pBase; pFunc = other.pFunc; } const C_METHOD_DELEGATE& operator=(const C_METHOD_DELEGATE& other) { this->pFunc = other.pFunc; this->pBase = other.pBase; return *this; } virtual TRet Invoke(PARAMS) { return (pBase->*pFunc)(ARGS); } virtual bool Compare(I_DELEGATE* other) { return true; } private: Func pFunc; TBase* pBase; }; template __forceinline I_DELEGATE* NewDelegate(TRet (*pFunc)(PARAMS)) { return new C_STATIC_DELEGATE(pFunc); } template __forceinline I_DELEGATE* NewDelegate(TBase* base, TRet (TBase::*pFunc)(PARAMS)) { return new C_METHOD_DELEGATE(base, pFunc); } template class I_EVENT { public: typedef I_DELEGATE IDelegate; typedef std::list DelegateList; DelegateList delegates; void Clear() { for(DelegateList::iterator it = delegates.begin(); it != delegates.end(); ++it) { delete (*it); } delegates.clear(); } void Remove(CDelegate* del) { for(DelegateList::iterator it = delegates.begin(); it != delegates.end(); ++it) { if(del == (*it)) { delete (*it); delegates.erase(it); break; } } } void AddDelegate(IDelegate* pDelegate) { if(pDelegate) { delegates.push_back(pDelegate); } } void Invoke(PARAMS) { for(DelegateList::iterator it = delegates.begin(); it != delegates.end(); ++it) { (*it)->Invoke(ARGS); } } I_EVENT& operator =(IDelegate* pDelegate) { Clear(); AddDelegate(pDelegate); return *this; } I_EVENT& operator +=(IDelegate* pDelegate) { AddDelegate(pDelegate); return *this; } I_EVENT& operator +=(CDelegate* pDelegate) { AddDelegate((IDelegate*)pDelegate); return *this; } };