日志服
/********************************************************************* 文件名: Bind_Par.h* 文件描述: 参数绑定器* 创建人: 陈泽丹 ,2012年10月25日 * 版本号: 1.0* 备注: 每次打包参数以做网络通讯的传递太麻烦了, 所以封装绑定参数的操作。 其中利用模板参和偏特化无关联的特性,让使用者可采用参数来区分,而不是采用模板名不同来区分********************************************************************/#pragma once#define RETURN_IF_NULL( _buf ) if( NULL == _buf ) return#define TYPELIST_1(T1) \Typelist<T1, NullType>#define TYPELIST_2(T1, T2) \Typelist<T1, TYPELIST_1(T2) >#define TYPELIST_3(T1, T2, T3) \Typelist<T1, TYPELIST_2(T2, T3) >#define TYPELIST_4(T1, T2, T3, T4) \Typelist<T1, TYPELIST_3(T2, T3, T4) >#define TYPELIST_5(T1, T2, T3, T4, T5) \Typelist<T1, TYPELIST_4(T2, T3, T4, T5) >class NullType {}; template <class T, class U> struct Typelist { typedef T Head; typedef U Tail; }; template <class TList>struct Bind_Par;template <class _P1>struct Bind_Par< TYPELIST_1(_P1) >{public:typedef _P1 Parm1;Parm1 par1;Bind_Par< TYPELIST_1(Parm1) >( Parm1 _par1): par1(_par1){}};template <class _P1, class _P2>struct Bind_Par< TYPELIST_2(_P1, _P2) >{public:typedef _P1 Parm1;typedef _P2 Parm2;Parm1 par1;Parm2 par2;Bind_Par< TYPELIST_2(Parm1, Parm2) >( Parm1 _par1, Parm2 _par2): par1(_par1), par2(_par2){}};template <class _P1, class _P2, class _P3>struct Bind_Par< TYPELIST_3(_P1, _P2, _P3) >{public:typedef _P1 Parm1;typedef _P2 Parm2;typedef _P3 Parm3;Parm1 par1;Parm2 par2;Parm3 par3;Bind_Par< TYPELIST_3(Parm1, Parm2, Parm3) >( Parm1 _par1, Parm2 _par2, Parm3 _par3): par1(_par1), par2(_par2), par3(_par3){}};template <class _P1, class _P2, class _P3, class _P4>struct Bind_Par< TYPELIST_4(_P1, _P2, _P3, _P4) >{public:typedef _P1 Parm1;typedef _P2 Parm2;typedef _P3 Parm3;typedef _P4 Parm4;Parm1 par1;Parm2 par2;Parm3 par3;Parm4 par4;Bind_Par< TYPELIST_4(Parm1, Parm2, Parm3, Parm4) >( Parm1 _par1, Parm2 _par2, Parm3 _par3, Parm4 _par4): par1(_par1), par2(_par2), par3(_par3), par4(_par4){}};template <class _P1, class _P2, class _P3, class _P4, class _P5>struct Bind_Par< TYPELIST_5(_P1, _P2, _P3, _P4, _P5) >{public:typedef _P1 Parm1;typedef _P2 Parm2;typedef _P3 Parm3;typedef _P4 Parm4;typedef _P5 Parm5;Parm1 par1;Parm2 par2;Parm3 par3;Parm4 par4;Parm5 par5;Bind_Par< TYPELIST_5(Parm1, Parm2, Parm3, Parm4, Parm5) >( Parm1 _par1, Parm2 _par2, Parm3 _par3, Parm4 _par4, Parm5 _par5): par1(_par1), par2(_par2), par3(_par3), par4(_par4), par5(_par5){}};
/********************************************************************* 文件名: Server.h* 文件描述: 网络游戏模拟* 创建人: 陈泽丹 ,2012年9月6日 * 版本号: 1.0* 修改记录:********************************************************************/#pragma once#include <iostream>#include <vector>#include <map>#include <algorithm>//--风格:编译期类型有大写, 执行期类型用小写using namespace std;namespace Evt_Server_Space{//消息class Msg_Head{public:Msg_Head(const long _sub_id, void* _sub_buf):m_data(_sub_id, _sub_buf){};//类似树结点,不管有无后续都有一个next指针,这样类型结构统一//所以这里也不分是否共用同一事件,都需按id取值template<class _TYPE>void get_sub_buf(const long _sub_id, _TYPE*& _p_buf){if( m_data.first == _sub_id)_p_buf = (_TYPE*) m_data.second;else_p_buf = NULL;}virtual ~Msg_Head(){}private:pair<const long, void*> m_data;};// 事件决策者订阅者接口template< class _TMsg = Msg_Head >struct IPass_Event_Listener{ typedef _TMsg Msg;virtual bool on_pass(Msg *_p_msg) = 0; };// 事件否决者订阅者接口template< class _TMsg = Msg_Head >struct IVote_Event_Listener{ typedef _TMsg Msg;virtual bool on_vote(Msg *_p_msg) = 0; };// 行为执行者订阅者接口template< class _TMsg = Msg_Head >struct IAction_Event_Listener{ typedef _TMsg Msg;virtual void on_action(Msg *_p_msg) = 0; };// 事件响应者订阅者接口template< class _TMsg = Msg_Head >struct IResponse_Event_Listener{ typedef _TMsg Msg;virtual void on_response(Msg *_p_msg) = 0; };// 事件服务器 -- 事件驱动,消息处理template< class _TEvt, class _TMsg >class IEvt_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 = Msg_Head >class Evt_Server: public IEvt_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 Evt_Server< _TEvt, _TMsg >LOCAL_TYPE;//---------------------------------------------------------------------Evt_Server():pass_manager(this),vote_manager(this),action_manager(this),response_manager(this){}virtual bool add_listener(const _TEvt _event, PASS_EVENT_LISTENER* _p_listener){ return pass_manager.add_listener(_event, _p_listener); }virtual void remove_listener(const _TEvt _event, PASS_EVENT_LISTENER* _p_listener){ pass_manager.remove_listener(_event, _p_listener); }virtual bool add_listener(const _TEvt _event, VOTE_EVENT_LISTENER* _p_listener){ return vote_manager.add_listener(_event, _p_listener); }virtual void remove_listener(const _TEvt _event, VOTE_EVENT_LISTENER* _p_listener){ vote_manager.remove_listener(_event, _p_listener); }virtual bool add_listener(const _TEvt _event, ACTION_EVENT_LISTENER* _p_listener){ return action_manager.add_listener(_event, _p_listener); }virtual void remove_listener(const _TEvt _event, ACTION_EVENT_LISTENER* _p_listener){ action_manager.remove_listener(_event, _p_listener); }virtual bool add_listener(const _TEvt _event, RESPONSE_EVENT_LISTENER* _p_listener){ return response_manager.add_listener(_event, _p_listener); }virtual void remove_listener(const _TEvt _event, RESPONSE_EVENT_LISTENER* _p_listener){ response_manager.remove_listener(_event, _p_listener); }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 ]);//防止遍历过程中出现删除操作造成的问题,所以遍历拷贝数据V_PASS_EVENT_LISTENER copy_v = *pv;for( V_PASS_EVENT_LISTENER::const_iterator pass_it = copy_v.begin(); copy_v.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 ]);//防止遍历过程中出现删除操作造成的问题,所以遍历拷贝数据V_VOTE_EVENT_LISTENER copy_v = *pv;for( V_VOTE_EVENT_LISTENER::const_iterator vote_it = copy_v.begin(); copy_v.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 ]);//防止遍历过程中出现删除操作造成的问题,所以遍历拷贝数据V_ACTION_EVENT_LISTENER copy_v = *pv;for_each(copy_v.begin(), copy_v.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 ]);//防止遍历过程中出现删除操作造成的问题,所以遍历拷贝数据V_RESPONSE_EVENT_LISTENER copy_v = *pv;for_each(copy_v.begin(), copy_v.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(const _TEvt _event, _TEVENT_LISTENER_P _p_listener) 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(const _TEvt _event, _TEVENT_LISTENER_P _p_listener) {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;};Msg_Manager<PASS_EVENT_LISTENER*>pass_manager;Msg_Manager<VOTE_EVENT_LISTENER*>vote_manager;Msg_Manager<ACTION_EVENT_LISTENER*>action_manager;Msg_Manager<RESPONSE_EVENT_LISTENER*>response_manager;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_LISTENERm_pass_event_listeners;M_VOTE_EVENT_LISTENERm_vote_event_listeners;M_ACTION_EVENT_LISTENERm_action_event_listeners;M_RESPONSE_EVENT_LISTENERm_response_event_listeners;template<class _TMSG_LISTENER>friend struct Get_Listeners;};}
/********************************************************************* 文件名: Server.h* 文件描述: 网络游戏模拟* 创建人: 陈泽丹 ,2012年11月16日 * 版本号: 1.0* 修改记录:********************************************************************/#pragma once#include "Evt_Server.h"#include "Map_Par_Binder.h"using namespace Evt_Server_Space;class Log_Server{private:Evt_Server<> output_server;class Log_Trace: public IAction_Event_Listener<>{public:Log_Trace(Evt_Server<>* _p_output_server):mp_output_server(_p_output_server){}//打开输出开关void open(long _sign, const char* _title){ RETURN_IF_NULL(_title);mp_output_server->add_listener(_sign, this ); map_title[_sign] = _title;}//关闭输出开关void close(long _sign){ mp_output_server->remove_listener(_sign, this ); }//输出调试语句void print(long _sign, char* _p_text){ mp_output_server->dispatch_vote_msg( _sign, &Msg_Head( 1,&Bind_Par< TYPELIST_2(long,char*) >(_sign,_p_text) ) ); }private:// 事件响应者订阅者接口virtual void on_action(Msg *_p_msg){Bind_Par< TYPELIST_2(long, char*) >* p_buf = NULL;_p_msg->get_sub_buf(1, p_buf);RETURN_IF_NULL( p_buf );cout<<map_title[p_buf->par1]<<": "<<p_buf->par2<<endl;mp_output_server->remove_listener(p_buf->par1, this ); }map<long, const char*> map_title;Evt_Server<>* mp_output_server;}; public:Log_Server(void):trace(&output_server){}virtual ~Log_Server(void){}Log_Trace trace;};
#include <iostream>#include "Log_Server.h"void main(){Log_Server log_server;log_server.trace.open(1, "Test Trace");log_server.trace.print(1,"main");log_server.trace.print(1,"main1");log_server.trace.close(1);system("pause");};