讯息机_第二版

消息机_第二版

--- 事件最好不混入在消息内部,因为从概念上讲,事件和消息是两种不同的事物;从实际上讲,使用时事件没必要带上复杂的参数,而获得事件也没必要从消息参数中获得,那样会增加操作。

 

/********************************************************************
*  文件名:   Server.h
*  文件描述: 网络游戏模拟
*  创建人:   陈泽丹 ,2012年9月6日     
*  版本号:   1.0
*  修改记录:
********************************************************************/


#pragma once

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>


//--风格:编译期类型有大写, 执行期类型用小写
using namespace std;


namespace Server_Lib
{
	//消息
	struct MsgHead
	{
		long	Type;
		void*	Obj;
	};
	// 事件决策者订阅者接口
	template< class _TMsg = MsgHead >
	struct IPass_Event_Listener
	{ 
		typedef _TMsg Msg;
		virtual bool on_pass(Msg *_p_msg) = 0; 
	};

	// 事件否决者订阅者接口
	template< class _TMsg = MsgHead >
	struct IVote_Event_Listener
	{ 
		typedef _TMsg Msg;
		virtual bool on_vote(Msg *_p_msg) = 0; 
	};

	// 行为执行者订阅者接口
	template< class _TMsg = MsgHead >
	struct IAction_Event_Listener
	{ 
		typedef _TMsg Msg;
		virtual void on_action(Msg *_p_msg) = 0; 
	};

	// 事件响应者订阅者接口
	template< class _TMsg = MsgHead >
	struct IResponse_Event_Listener
	{ 
		typedef _TMsg Msg;
		virtual void on_response(Msg *_p_msg) = 0; 
	};

	// 事件服务器 -- 事件驱动,消息处理
	template< class _TEvt, class _TMsg >
	class IMsg_Server
	{
	public:
		typedef IPass_Event_Listener< _TMsg >			PASS_EVENT_LISTENER;
		typedef IVote_Event_Listener< _TMsg >			VOTE_EVENT_LISTENER;
		typedef IAction_Event_Listener< _TMsg >			ACTION_EVENT_LISTENER;
		typedef IResponse_Event_Listener< _TMsg >		RESPONSE_EVENT_LISTENER;
		//监控时以事件为要素
		virtual bool add_listener(const _TEvt _event, PASS_EVENT_LISTENER* _p_listener)			= 0;
		virtual void remove_listener(const _TEvt _event, PASS_EVENT_LISTENER* _p_listener)		= 0;
		virtual bool add_listener(const _TEvt _event, VOTE_EVENT_LISTENER* _p_listener)			= 0;
		virtual void remove_listener(const _TEvt _event, VOTE_EVENT_LISTENER* _p_listener)		= 0;
		virtual bool add_listener(const _TEvt _event, ACTION_EVENT_LISTENER* _p_listener)		= 0;
		virtual void remove_listener(const _TEvt _event, ACTION_EVENT_LISTENER* _p_listener)	= 0;
		virtual bool add_listener(const _TEvt _event, RESPONSE_EVENT_LISTENER* _p_listener)		= 0;
		virtual void remove_listener(const _TEvt _event, RESPONSE_EVENT_LISTENER* _p_listener)	= 0;
		//处理时以消息为要素
		virtual void dispatch_pass_msg(const _TEvt _event, _TMsg *_p_msg) 						= 0;
		virtual void dispatch_vote_msg(const _TEvt _event, _TMsg *_p_msg) 						= 0;
	};


	template< class _TEvt = long, class _TMsg = MsgHead >
	class Msg_Server: public IMsg_Server< _TEvt, _TMsg >
	{
	public:
		typedef vector< PASS_EVENT_LISTENER* >			V_PASS_EVENT_LISTENER;
		typedef vector< VOTE_EVENT_LISTENER* >			V_VOTE_EVENT_LISTENER;
		typedef vector< ACTION_EVENT_LISTENER* >		V_ACTION_EVENT_LISTENER;
		typedef vector< RESPONSE_EVENT_LISTENER* >		V_RESPONSE_EVENT_LISTENER;
		typedef map<_TEvt, V_PASS_EVENT_LISTENER>		M_PASS_EVENT_LISTENER; 
		typedef map<_TEvt, V_VOTE_EVENT_LISTENER>		M_VOTE_EVENT_LISTENER;
		typedef map<_TEvt, V_ACTION_EVENT_LISTENER>		M_ACTION_EVENT_LISTENER;
		typedef map<_TEvt, V_RESPONSE_EVENT_LISTENER>	M_RESPONSE_EVENT_LISTENER;
		typedef Msg_Server< _TEvt, _TMsg >				LOCAL_TYPE;


		//---------------------------------------------------------------------
		virtual bool add_listener(const _TEvt _event, PASS_EVENT_LISTENER* _p_listener){ return Msg_Manager<PASS_EVENT_LISTENER*>(this).add_listener(_p_listener, _event); }
		virtual void remove_listener(const _TEvt _event, PASS_EVENT_LISTENER* _p_listener){  Msg_Manager<PASS_EVENT_LISTENER*>(this).remove_listener(_p_listener, _event); }
		virtual bool add_listener(const _TEvt _event, VOTE_EVENT_LISTENER* _p_listener){ return Msg_Manager<VOTE_EVENT_LISTENER*>(this).add_listener(_p_listener, _event); }
		virtual void remove_listener(const _TEvt _event, VOTE_EVENT_LISTENER* _p_listener){  Msg_Manager<VOTE_EVENT_LISTENER*>(this).remove_listener(_p_listener, _event); }
		virtual bool add_listener(const _TEvt _event, ACTION_EVENT_LISTENER* _p_listener){ return Msg_Manager<ACTION_EVENT_LISTENER*>(this).add_listener(_p_listener, _event); }
		virtual void remove_listener(const _TEvt _event, ACTION_EVENT_LISTENER* _p_listener){  Msg_Manager<ACTION_EVENT_LISTENER*>(this).remove_listener(_p_listener, _event); }
		virtual bool add_listener(const _TEvt _event, RESPONSE_EVENT_LISTENER* _p_listener){ return Msg_Manager<RESPONSE_EVENT_LISTENER*>(this).add_listener(_p_listener, _event); }
		virtual void remove_listener(const _TEvt _event, RESPONSE_EVENT_LISTENER* _p_listener){  Msg_Manager<RESPONSE_EVENT_LISTENER*>(this).remove_listener(_p_listener, _event); }
		virtual void dispatch_pass_msg(const _TEvt _event, _TMsg *_p_msg) 	
		{
			//一票通过处理
			bool failed = true;
			M_PASS_EVENT_LISTENER* p_pass_event_listeners = Get_Listeners<PASS_EVENT_LISTENER*>()(this);
			M_PASS_EVENT_LISTENER::iterator vote_it = p_pass_event_listeners->find( _event );
			if( p_pass_event_listeners->end() != vote_it)
			{
				V_PASS_EVENT_LISTENER *pv = &((*p_pass_event_listeners)[ _event ]);
				for( V_PASS_EVENT_LISTENER::const_iterator pass_it = pv->begin(); pv->end() != pass_it; ++pass_it)
				{
					if( (*pass_it)->on_pass(_p_msg) )
					{
						failed = false;
						break;
					}
				}
			}
			if( failed) return;
			dispatch_msg(_event, _p_msg);
		}
		void dispatch_vote_msg(const _TEvt _event, _TMsg *_p_msg)
		{
			//否决处理
			M_VOTE_EVENT_LISTENER* p_vote_event_listeners = Get_Listeners<VOTE_EVENT_LISTENER*>()(this);
			M_VOTE_EVENT_LISTENER::iterator vote_it = p_vote_event_listeners->find( _event );
			if( p_vote_event_listeners->end() != vote_it)
			{
				V_VOTE_EVENT_LISTENER *pv = &((*p_vote_event_listeners)[ _event ]);
				for( V_VOTE_EVENT_LISTENER::const_iterator vote_it = pv->begin(); pv->end() != vote_it; ++vote_it)
				{
					if( (*vote_it)->on_vote(_p_msg) )
						return;
				}
			}
			dispatch_msg(_event, _p_msg);
		}

	protected:
		void dispatch_msg(const _TEvt _event, _TMsg *_p_msg)
		{
			//执行处理
			M_ACTION_EVENT_LISTENER* p_action_event_listeners = Get_Listeners<ACTION_EVENT_LISTENER*>()(this);
			M_ACTION_EVENT_LISTENER::iterator action_it = p_action_event_listeners->find( _event );
			if( p_action_event_listeners->end() != action_it)
			{
				V_ACTION_EVENT_LISTENER *pv = &((*p_action_event_listeners)[ _event ]);
				for_each(pv->begin(), pv->end(), bind2nd(action_fun(),_p_msg));
			}


			//响应处理
			M_RESPONSE_EVENT_LISTENER* p_response_event_listeners = Get_Listeners<RESPONSE_EVENT_LISTENER*>()(this);
			M_RESPONSE_EVENT_LISTENER::iterator response_it = p_response_event_listeners->find( _event );
			if( p_response_event_listeners->end() != response_it)
			{
				V_RESPONSE_EVENT_LISTENER *pv = &((*p_response_event_listeners)[ _event ]);
				for_each(pv->begin(), pv->end(), bind2nd(response_fun(),_p_msg));
			}
		}
	private:
		struct action_fun: public binary_function<ACTION_EVENT_LISTENER*, _TMsg *, void>{ void operator()(ACTION_EVENT_LISTENER *pIt, _TMsg *_p_msg) const { pIt->on_action(_p_msg); }};
		struct response_fun: public binary_function<RESPONSE_EVENT_LISTENER*, _TMsg *, void>{ void operator()(RESPONSE_EVENT_LISTENER *pIt, _TMsg *_p_msg) const { pIt->on_response(_p_msg); }};
		//----------------------- 管理器 ----------------------
		template< class _TEVENT_LISTENER_P> 
		class Msg_Manager
		{
		public:
			typedef vector< _TEVENT_LISTENER_P >	V_TEVENT_LISTENER;
			typedef map<_TEvt, V_TEVENT_LISTENER>	M_TEVENT_LISTENER;
			Msg_Manager( LOCAL_TYPE *_p_local):mp_local(_p_local){}
			bool add_listener(_TEVENT_LISTENER_P _p_listener, const _TEvt _event) const
			{
				M_TEVENT_LISTENER* p_event_listeners = Get_Listeners<_TEVENT_LISTENER_P>()(mp_local);
				V_TEVENT_LISTENER* pv = &((*p_event_listeners)[_event]);
				V_TEVENT_LISTENER::iterator it = find(pv->begin(), pv->end(), _p_listener);
				if( pv->end() == it)
				{
					pv->push_back(_p_listener);
					return true;
				}
				return false;
			}
			void remove_listener(_TEVENT_LISTENER_P _p_listener, const _TEvt _event) const 
			{
				M_TEVENT_LISTENER* p_event_listeners = Get_Listeners<_TEVENT_LISTENER_P>()(mp_local);
				M_TEVENT_LISTENER::iterator it = p_event_listeners->find(_event);
				if( p_event_listeners->end() != it)
				{
					V_TEVENT_LISTENER* pv = &((*p_event_listeners)[_event]);
					V_TEVENT_LISTENER::iterator v_it = find(pv->begin(), pv->end(), _p_listener);
					if( pv->end() != v_it){ pv->erase(v_it);}
					if( pv->size() <= 0 ){ p_event_listeners->erase(it);}
				}
			}
		private:		LOCAL_TYPE *mp_local;
		};
		template< class _T> 
		struct Get_Listeners;
		template<> 
		struct Get_Listeners<PASS_EVENT_LISTENER*>{ M_PASS_EVENT_LISTENER* operator()(LOCAL_TYPE *_p_local){ return &(_p_local->m_pass_event_listeners); }};
		template<> 
		struct Get_Listeners<VOTE_EVENT_LISTENER*>{ M_VOTE_EVENT_LISTENER* operator()(LOCAL_TYPE *_p_local){ return &(_p_local->m_vote_event_listeners); }};
		template<> 
		struct Get_Listeners<ACTION_EVENT_LISTENER*>{ M_ACTION_EVENT_LISTENER* operator()(LOCAL_TYPE *_p_local){ return &(_p_local->m_action_event_listeners); }};
		template<> 
		struct Get_Listeners<RESPONSE_EVENT_LISTENER*>{ M_RESPONSE_EVENT_LISTENER* operator()(LOCAL_TYPE *_p_local){ return &(_p_local->m_response_event_listeners); }};
		M_PASS_EVENT_LISTENER								m_pass_event_listeners;
		M_VOTE_EVENT_LISTENER								m_vote_event_listeners;
		M_ACTION_EVENT_LISTENER								m_action_event_listeners;
		M_RESPONSE_EVENT_LISTENER							m_response_event_listeners;
		template<class _TMSG_LISTENER>
		friend class Get_Listeners;
	};
}


 

#include <iostream>
#include "Server_Lib.h"


using namespace std;
using namespace Server_Lib;

struct p: public IPass_Event_Listener<>
{
	virtual bool on_pass(Msg *_p_msg)
	{
		cout<<"p"<<endl;
		return true;
	}
};

struct v: public IVote_Event_Listener<>
{
	virtual bool on_vote(Msg *_p_msg)
	{
		cout<<"v"<<endl;
		return false;
	}
};

struct a: public IAction_Event_Listener<>
{
	virtual void on_action(Msg *_p_msg)
	{
		cout<<"a"<<endl;
	}
};

struct r: public IResponse_Event_Listener<>
{
	virtual void on_response(Msg *_p_msg)
	{
		cout<<"r"<<endl;
	}
};

void main()
{
	Msg_Server<> test;
	p p_lst;
	v v_lst;
	a a_lst;
	r r_lst;
	test.add_listener(1, &p_lst);
	test.add_listener(1, &v_lst);
	test.add_listener(1, &a_lst);
	test.add_listener(1, &r_lst);
	MsgHead msg_head;
	test.dispatch_pass_msg(1,&msg_head);
	test.dispatch_vote_msg(1,&msg_head);
	system("pause");
}