C++代码实现委托代理

本文介绍了一个C++实现的名为XDelegate的委托代理类,展示了如何使用模板和组合方法注册、调用以及在类中应用此委托。实例中通过ActionArgs和Actor/Component类展示了其在事件处理中的应用。
摘要由CSDN通过智能技术生成
#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;
}

结果展示

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值