#ifndef __XDELEGATE_H__
#define __XDELEGATE_H__
#define DelegateCombination(T_, Func_, Instance_) (XDelegate::registerMethod<T_, &T_::Func_>(Instance_))
class IArgs
{
public:
virtual ~IArgs() {}
};
class XDelegate
{
public:
XDelegate()
: object_ptr(0)
, stub_ptr(0)
{}
template <class T, bool (T::*TMethod)(IArgs *, void *)>
static XDelegate registerMethod(T* object_ptr)
{
XDelegate d;
d.object_ptr = object_ptr;
d.stub_ptr = &method_stub<T, TMethod>; // #1
return d;
}
bool operator()(IArgs *pargs, void *arg) const
{
if (object_ptr == NULL)
{
return false;
}
return stub_ptr(object_ptr, pargs, arg);
}
private:
typedef bool (*stub_type)(void* object_ptr, IArgs *, void *arg);
void* object_ptr;
stub_type stub_ptr;
template <class T, bool (T::*TMethod)(IArgs *, void *)>
static bool method_stub(void* object_ptr, IArgs *pargs, void *arg)
{
T* ptr = static_cast<T*>(object_ptr);
//invocation here as fast as direct method invocation (because its value is known at compile time)
return (ptr->*TMethod)(pargs, arg);
}
};
#endif //__XDELEGATE_H__
上面代码实现了一个委托代理
下面是代码是使用方法及案例
#include "xdelegate.hpp"
#include <iostream>
enum ActionDefine
{
Action_Invalid = -1,
Action_Idle = 0,
Action_Move,
Action_Jump,
Action_Fall,
Action_Max
};
class ActionArgs : public IArgs
{
public:
static uint64_t s_token;
protected:
ActionDefine _eDefine;
uint64_t _token;
IArgs* _args;
public:
ActionArgs(ActionDefine define, IArgs * args)
: _eDefine(define), _args(args)
{
_token = s_token++;
}
virtual ~ActionArgs() { }
inline ActionDefine ArgsDefine() { return _eDefine; }
inline IArgs* Args() { return _args; }
inline uint64_t GetToken() const { return _token; }
inline void SetToken(uint64_t token) { _token = token; }
};
uint64_t ActionArgs::s_token = 0;
class Actor
{
public:
Actor()
{
age = 10;
}
public:
int age;
};
class Component
{
public:
Component(int _data)
{
data = _data;
memset(_actionMap, NULL, sizeof(XDelegate*) * Action_Max);
}
~Component()
{
for (int i = 0; i < Action_Max; i++)
{
if (!_actionMap[i])
continue;
delete _actionMap[i];
_actionMap[i] = NULL;
}
}
void RegisterAction(ActionDefine action, XDelegate handler)
{
if (action < 0 || action >= Action_Max)
return;
if (!_actionMap[action])
{
_actionMap[action] = new XDelegate;
}
*_actionMap[action] = handler;
}
bool OnMove(IArgs* pargs, void*)
{
Actor* actor = (Actor*)(((ActionArgs*)pargs)->Args());
std::cout << "OnMove called with age: " << actor->age << std::endl;
return true;
}
bool OnJump(IArgs* pargs, void*)
{
std::cout << "OnJump called with data: " << data << std::endl;
return true;
}
void ActionSubscribe()
{
RegisterAction(Action_Move, DelegateCombination(Component, OnMove, this));
RegisterAction(Action_Jump, DelegateCombination(Component, OnJump, this));
}
bool OnReceiveAction(ActionArgs* args)
{
ActionDefine def = args->ArgsDefine();
if (def < 0 || def >= Action_Max)
return false;
return _actionMap[def] ? (*_actionMap[def])(args, nullptr) : false;
}
private:
XDelegate* _actionMap[Action_Max];
int data;
};
int main()
{
Component a(30);
a.ActionSubscribe();
ActionArgs b(Action_Jump,nullptr);
Actor actor;
ActionArgs c(Action_Move, (IArgs*)&actor);
a.OnReceiveAction(&b);
a.OnReceiveAction(&c);
return 0;
}
结果展示