基于C++的事件机制设计 Based on[C++0x]

Since the C++0x supports the variadic function, it's the very time to improve original C++ event system.

The thought is as same as [2.0].

Here is the code list.

The root Object:

	class TObject
	{
	public:
		TObject()
		{
			// Dummy
		}

		virtual ~TObject()
		{

		}
	};

And then Event declaration:

#include "Object.h"
#include <memory>


namespace igame
{
	template<typename T_RET, typename ... PARAMS>
	struct TEventHandler
	{
		typedef T_RET Type;
		typedef T_RET (TObject::*Function)(PARAMS...);

		std::shared_ptr<Object> _target;
		Function _function;

		__inline__ T_RET operator()(PARAMS ...params)
		{
			if (_target != nullptr && _function != nullptr)
				return (_target.get()->*_function)(params...);
		}
	};


	template<typename T_RET, typename ... PARAMS>
	struct Event
	{
		typedef TEventHandler<T_RET, PARAMS...> Handler;
		typedef typename Handler::Function Function;

		Handler _handler;

		template <typename T_F = Function, typename T_ARG>
		__inline__ T_F castFunction(T_ARG arg)
		{
			return (T_F)arg;
		}

		template<typename T_FUNC>
		__inline__ void bind(std::shared_ptr<TObject> tag, T_FUNC func)
		{
			_handler = { tag, castFunction(func) };
		}

		__inline__ T_RET operator()(PARAMS...params)
		{
			return _handler(params...);
		}
	};
} // ns igame

Compared with 2.0, It's more elegant, more lightweight.

Note: under G++, the inline qualifier may not work as your wish.

Now, Let's rock:

        class A : public TObject
	{
	public:
		void foo(int x)
		{
			// cout << "Foo:" << x << endl;
		}

		void foo2(std::function<void (int)> func)
		{
			func(99);
		}

	};

	class B : public TObject
	{
	public:
		using MyEvent = Event<void, int>;
		using MyFuncEvent = Event<void, std::function<void (int)>>;

		MyEvent event;
		MyFuncEvent funcEvent;

		void testEvent(int x)
		{
			cout << "Fxx:" << x << endl;

			event(x);

		}

		void testFuncEvent(std::function<void (int)> func)
		{
			funcEvent([this, func](int x){
				cout<<this->message<<endl;
				func(x);
			});
		}
	};

The following code shows how to use the Event system:

	std::shared_ptr<A> a(new A());
	std::shared_ptr<B> b(new B());

	b->event.bind(a, &A::foo);
	b->funcEvent.bind(a, &A::foo2);

	b->testEvent(100);

  	int x = 101;
  	b->testFuncEvent([&](int val){
  		val = x;
  	});


Actually, this implementation of Event is more like the std::function<> but a little improvement of performance: 23093ms V.s 29146.2ms for calling of 0xEFFFFFFF times in my ASUS Q200E laptop. On the other words,  5.73521ns V.s 7.23853ns for per calling.

And more straightly than std::function<>. After all, the virtual function calling consumes 4.29958ns for per calling.  As a syntactic sugar, my event model works pretty well.





你可能感兴趣的:(C++,event)