消息机4
/******************************************************************** author : Clark/陈泽丹 created : 2013-9-10 purpose : 计数释放 *********************************************************************/ #pragma once class AutoRelease { public: AutoRelease(void){ m_count = 0; } virtual ~AutoRelease(void){} AutoRelease* GetPointClone() { ++m_count; return this; } void Release() { m_count = m_count - 1; if( m_count <= 0) delete this; } private: long m_count; };
/******************************************************************** author : Clark/陈泽丹 created : 2013-9-10 purpose : 消息处理器 *********************************************************************/ #pragma once #include <string> #include <map> using namespace std; typedef map< string, void* > LST_EVT_TYPE; class IMsgListener { public: virtual ~IMsgListener(){}; virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt ) = 0; };
/******************************************************************** author : Clark/陈泽丹 created : 2013-9-10 purpose : 消息关联项 *********************************************************************/ #pragma once #include "IMsgListener.h" class IMsgServerItem { public: virtual ~IMsgServerItem(){} virtual bool AddListener( string _msg, IMsgListener* _p_lst ) = 0; virtual void RemoveListener( string _msg, IMsgListener* _p_lst ) = 0; virtual void UpdataListener() = 0; virtual bool DispatchEvt( string _msg, LST_EVT_TYPE* _evt ) = 0; };
/******************************************************************** author : Clark/陈泽丹 created : 2013-9-10 purpose : 消息处理器 *********************************************************************/ #pragma once #include "AutoRelease.h" #include "IMsgListener.h" #include "MsgServer4.h" #include <iostream> using namespace std; class VoteTest:public IMsgListener { public: virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt ) { cout<<"VoteTest"<<endl; return false; } }; class InitTest:public IMsgListener { public: virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt ) { cout<<"InitTest"<<endl; return true; } }; class ActTest:public IMsgListener { public: virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt ) { cout<<"ActTest"<<endl; return true; } }; class UninitTest:public IMsgListener { public: virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt ) { cout<<"UninitTest"<<endl; return true; } }; class EvtHelper: public AutoRelease { public: virtual bool Init() = 0; virtual void UnInit() = 0; }; template< class _LST_TYPE > class ComEvtHelper: public EvtHelper { public: ComEvtHelper( MsgServer4* _msg_svr, string _msg, int _lst_type ) { m_msg_svr = _msg_svr; m_type = _lst_type; m_msg = _msg; } ~ComEvtHelper(){} bool Init(){ return m_msg_svr->AddListener( m_msg, m_type, &m_evt_handle ); } void UnInit(){ m_msg_svr->RemoveListener( m_msg, m_type, &m_evt_handle ); } private: _LST_TYPE m_evt_handle; MsgServer4* m_msg_svr; int m_type; string m_msg; }; template< class _LST_TYPE > class ComEvtHelperEx: public EvtHelper { public: ComEvtHelperEx( MsgServer4* _msg_svr, string _msg, int _lst_type, LST_EVT_TYPE _evt ):m_evt_handle(_evt) { m_msg_svr = _msg_svr; m_type = _lst_type; m_msg = _msg; } ~ComEvtHelperEx(){} bool Init(){ return m_msg_svr->AddListener( m_msg, m_type, &m_evt_handle ); } void UnInit(){ m_msg_svr->RemoveListener( m_msg, m_type, &m_evt_handle ); } private: /* author : Clark purpose : 以下代码是希望实现一个可以针对参数进行监听功能,但是实现得相当糟糕,而目前未想出优雅的方案解决。 “模块继承”是个不错的方法:有时侯你不希望把虚函数留给终端结点于处理, 而是希望不管提供出去后外部怎么处理, 最后总是决定权会回到你手里。(配后的类型统一问题可以通过基类指针解决)。 */ class LST_TYPE_EX: public _LST_TYPE { public: LST_TYPE_EX( LST_EVT_TYPE _evt_condition ){ m_evt_condition = _evt_condition; } virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt ) { LST_EVT_TYPE::iterator it = m_evt_condition.begin(); while( m_evt_condition.end() != it ) { LST_EVT_TYPE::iterator tmp = _evt->find( it->first ); if( _evt->end() == tmp || tmp->second != it->second ) return false; it++; } return _LST_TYPE::OnEvt(_msg, _evt); } private: LST_EVT_TYPE m_evt_condition; }; LST_TYPE_EX m_evt_handle; MsgServer4* m_msg_svr; int m_type; string m_msg; };
/******************************************************************** author : Clark/陈泽丹 created : 2013-9-10 purpose : 消息关联中心 *********************************************************************/ #pragma once #include "IMsgListener.h" #include "IMsgServerItem.h" #include "MsgSvrItem.h" #include <vector> #include <string> using namespace std; class MsgServer4 { public: MsgServer4(void); virtual ~MsgServer4(void); void PushSvr( int _sign, IMsgServerItem* _msg_svr ); void Clear(); bool AddListener( string _msg, int _lst_type, IMsgListener* _p_lst ); void RemoveListener( string _msg, int _lst_type, IMsgListener* _p_lst ); void DispatchEvt( string _msg, LST_EVT_TYPE* _evt ); private: typedef pair<int, IMsgServerItem*> SVR_TYPE; vector<SVR_TYPE> mvct_msg_svr; }; class MsgServer4Helper { public: enum MSG_SVR_TYPE { VOTE = 1, INIT = 2, ACTION = 3, UNINIT = 4, }; void Init(); void UnInit(); MsgServer4* GetSvr(); LST_EVT_TYPE* GetPar(); private: MsgServer4 g_msg_svr4; LST_EVT_TYPE g_evt; IMsgServerItem* p_vote_svr; IMsgServerItem* p_init_svr; IMsgServerItem* p_action_svr; IMsgServerItem* p_uninit_svr; };
#include "MsgServer4.h" MsgServer4::MsgServer4() { } MsgServer4::~MsgServer4(void) { Clear(); } void MsgServer4::PushSvr( int _sign, IMsgServerItem* _msg_svr ) { SVR_TYPE tmp = make_pair(_sign, _msg_svr); mvct_msg_svr.push_back(tmp); _msg_svr = 0; } void MsgServer4::Clear() { mvct_msg_svr.clear(); } bool MsgServer4::AddListener( string _msg, int _lst_type, IMsgListener* _p_lst ) { if( _lst_type >= 0 && _lst_type <= mvct_msg_svr.size() ) { long len = mvct_msg_svr.size(); for( int i=0; i<len; i++ ) { if( mvct_msg_svr[i].first == _lst_type ) { return mvct_msg_svr[i].second->AddListener(_msg, _p_lst); } } } return false; } void MsgServer4::RemoveListener( string _msg, int _lst_type, IMsgListener* _p_lst ) { if( _lst_type >= 0 && _lst_type <= mvct_msg_svr.size() ) { long len = mvct_msg_svr.size(); for( int i=0; i<len; i++ ) { if( mvct_msg_svr[i].first == _lst_type ) { mvct_msg_svr[i].second->RemoveListener(_msg, _p_lst); return; } } } } void MsgServer4::DispatchEvt( string _msg, LST_EVT_TYPE* _evt ) { int len = mvct_msg_svr.size(); for( int i=0; i<len; i++) { if( true == mvct_msg_svr[i].second->DispatchEvt(_msg,_evt) ) return; } } void MsgServer4Helper::Init() { p_vote_svr = new VoteMsgSvrItem(); p_init_svr = new ActionMsgSvrItem(); p_action_svr = new ActionMsgSvrItem(); p_uninit_svr = new ActionMsgSvrItem(); g_msg_svr4.PushSvr( MSG_SVR_TYPE::VOTE, p_vote_svr ); g_msg_svr4.PushSvr( MSG_SVR_TYPE::INIT, p_init_svr ); g_msg_svr4.PushSvr( MSG_SVR_TYPE::ACTION, p_action_svr ); g_msg_svr4.PushSvr( MSG_SVR_TYPE::UNINIT, p_uninit_svr ); } void MsgServer4Helper::UnInit() { g_msg_svr4.Clear(); delete p_vote_svr; delete p_init_svr; delete p_action_svr; delete p_uninit_svr; } MsgServer4* MsgServer4Helper::GetSvr() { return &g_msg_svr4; } LST_EVT_TYPE* MsgServer4Helper::GetPar() { return &g_evt; }
/******************************************************************** author : Clark/陈泽丹 created : 2013-9-10 purpose : 消息关联项实例 *********************************************************************/ #pragma once #include "IMsgServerItem.h" #include <vector> #include <map> #include <string> using namespace std; class BaseMsgSvrItem: public IMsgServerItem { public: BaseMsgSvrItem(); virtual ~BaseMsgSvrItem(); virtual bool AddListener( string _msg, IMsgListener* _p_lst ); virtual void RemoveListener( string _msg, IMsgListener* _p_lst ); virtual void UpdataListener(); virtual bool DispatchEvt( string _msg, LST_EVT_TYPE* _evt ) = 0; protected: typedef vector< IMsgListener* > LIST_TYPE; typedef map< string, LIST_TYPE* > LST_MAP_TYPE; typedef pair< string, IMsgListener* > REMOVE_TYPE; LST_MAP_TYPE m_map_lst; private: vector< REMOVE_TYPE > m_vct_remove; }; class VoteMsgSvrItem: public BaseMsgSvrItem { public: virtual bool DispatchEvt( string _msg, LST_EVT_TYPE* _evt ); }; class ActionMsgSvrItem: public BaseMsgSvrItem { public: virtual bool DispatchEvt( string _msg, LST_EVT_TYPE* _evt ); };
#include "MsgSvrItem.h" BaseMsgSvrItem::BaseMsgSvrItem() { } BaseMsgSvrItem::~BaseMsgSvrItem() { LST_MAP_TYPE::iterator it = m_map_lst.begin(); while( it != m_map_lst.end() ) { LIST_TYPE* p_items = it->second; it->second = 0; it++; delete p_items; } m_map_lst.clear(); m_vct_remove.clear(); } bool BaseMsgSvrItem::AddListener( string _msg, IMsgListener* _p_lst ) { LST_MAP_TYPE::iterator it = m_map_lst.find(_msg); if( m_map_lst.end() == it ) { m_map_lst[_msg] = new vector<IMsgListener*>(); m_map_lst[_msg]->push_back(_p_lst); return true; } else { LIST_TYPE items = *(it->second); long len = items.size(); for( long i=0; i<len; i++ ) { if( items[i] == _p_lst ) return false; } items.push_back(_p_lst); return true; } } void BaseMsgSvrItem::RemoveListener( string _msg, IMsgListener* _p_lst ) { m_vct_remove.push_back( make_pair(_msg, _p_lst) ); } void BaseMsgSvrItem::UpdataListener() { long len = m_vct_remove.size(); for( int i=0; i<len; i++ ) { REMOVE_TYPE tmp = m_vct_remove[i]; LST_MAP_TYPE::iterator it = m_map_lst.find( tmp.first ); if( m_map_lst.end() != it ) { LIST_TYPE* p_items = (it->second); long len = p_items->size(); for( long i=0; i<len; i++ ) { if( (*p_items)[i] == tmp.second ) { for( long j=i+1; i<len-1; i++ ) { (*p_items)[j-1] = (*p_items)[j]; } p_items->pop_back(); } } } } } bool VoteMsgSvrItem::DispatchEvt( string _msg, LST_EVT_TYPE* _evt ) { UpdataListener(); bool ret = false; LST_MAP_TYPE::iterator it = m_map_lst.find( _msg ); if( m_map_lst.end() != it ) { LIST_TYPE* p_items = (it->second); long len = p_items->size(); for( long i=0; i<len; i++ ) { if( true == (*p_items)[i]->OnEvt(_msg, _evt) ) { ret = true; break; } } } UpdataListener(); return ret; } bool ActionMsgSvrItem::DispatchEvt( string _msg, LST_EVT_TYPE* _evt ) { UpdataListener(); LST_MAP_TYPE::iterator it = m_map_lst.find( _msg ); if( m_map_lst.end() != it ) { LIST_TYPE* p_items = (it->second); long len = p_items->size(); for( long i=0; i<len; i++ ) { (*p_items)[i]->OnEvt(_msg, _evt); } } UpdataListener(); return false; }
#include <iostream> #include "MsgListener.h" #include "MsgSvrItem.h" #include "MsgServer4.h" using namespace std; void main() { MsgServer4Helper g_msg_svr4; g_msg_svr4.Init(); LST_EVT_TYPE condition; condition["1"] = (void*)1; EvtHelper* p_vote = new ComEvtHelperEx<VoteTest>( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::VOTE, condition); EvtHelper* p_init = new ComEvtHelper<InitTest>( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::INIT ); EvtHelper* p_act = new ComEvtHelper<ActTest>( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::ACTION ); EvtHelper* p_uninit = new ComEvtHelper<UninitTest>( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::UNINIT ); p_vote->Init(); p_init->Init(); p_act->Init(); p_uninit->Init(); LST_EVT_TYPE* par = g_msg_svr4.GetPar(); (*par)["1"] = (void*)1; (*par)["2"] = (void*)2; (*par)["3"] = (void*)3; g_msg_svr4.GetSvr()->DispatchEvt("123", g_msg_svr4.GetPar()); p_uninit->UnInit(); p_act->UnInit(); g_msg_svr4.GetSvr()->DispatchEvt("123", g_msg_svr4.GetPar()); p_init->UnInit(); p_vote->UnInit(); system("pause"); g_msg_svr4.UnInit(); p_vote->Release(); p_init->Release(); p_act->Release(); p_uninit->Release(); }