template<class ARGTYPE>
class Delegate
{
public:
/// constructor
Delegate();
/// invokation operator
void operator()(ARGTYPE arg) const;
/// setup a new delegate from a method call
template<class CLASS, void (CLASS::*METHOD)(ARGTYPE)> static Delegate<ARGTYPE> FromMethod(CLASS* objPtr);
/// setup a new delegate from a function call
template<void(*FUNCTION)(ARGTYPE)> static Delegate<ARGTYPE> FromFunction();
bool IsValid(){return stubPtr != nullptr;}
bool operator==(const Delegate<ARGTYPE> &item){return objPtr==item.objPtr&&stubPtr==item.stubPtr};
private:
/// method pointer typedef
typedef void (*StubType)(void*, ARGTYPE);
/// static method-call stub
template<class CLASS, void(CLASS::*METHOD)(ARGTYPE)> static void MethodStub(void* objPtr, ARGTYPE arg);
/// static function-call stub
template<void(*FUNCTION)(ARGTYPE)> static void FunctionStub(void* dummyPtr, ARGTYPE arg);
void* objPtr;
StubType stubPtr;
};
//------------------------------------------------------------------------------
/**
*/
template<class ARGTYPE>
Delegate<ARGTYPE>::Delegate() :
objPtr(0),
stubPtr(0)
{
// empty
}
//------------------------------------------------------------------------------
/**
*/
template<class ARGTYPE> void
Delegate<ARGTYPE>::operator()(ARGTYPE arg) const
{
(*this->stubPtr)(this->objPtr, arg);
}
//------------------------------------------------------------------------------
/**
*/
template<class ARGTYPE>
template<class CLASS, void (CLASS::*METHOD)(ARGTYPE)>
static Delegate<ARGTYPE>
Delegate<ARGTYPE>::FromMethod(CLASS* objPtr_)
{
Delegate<ARGTYPE> del;
del.objPtr = objPtr_;
del.stubPtr = &MethodStub<CLASS,METHOD>;
return del;
}
//------------------------------------------------------------------------------
/**
*/
template<class ARGTYPE>
template<void(*FUNCTION)(ARGTYPE)>
static Delegate<ARGTYPE>
Delegate<ARGTYPE>::FromFunction()
{
Delegate<ARGTYPE> del;
del.objPtr = 0;
del.stubPtr = &FunctionStub<FUNCTION>;
return del;
}
//------------------------------------------------------------------------------
/**
*/
template<class ARGTYPE>
template<class CLASS, void (CLASS::*METHOD)(ARGTYPE)>
static void
Delegate<ARGTYPE>::MethodStub(void* objPtr_, ARGTYPE arg_)
{
CLASS* obj = static_cast<CLASS*>(objPtr_);
(obj->*METHOD)(arg_);
}
//------------------------------------------------------------------------------
/**
*/
template<class ARGTYPE>
template<void(*FUNCTION)(ARGTYPE)>
static void
Delegate<ARGTYPE>::FunctionStub(void* dummyPtr, ARGTYPE arg_)
{
(*FUNCTION)(arg_);
}
Nebula3委托
最新推荐文章于 2022-01-07 20:57:53 发布