/********************************************************************
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, _LST_TYPE& _p_evt_hd, LST_EVT_TYPE* _p_evt_cdt = 0 ):m_evt_handle(_p_evt_hd, _p_evt_cdt)
{
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:
class ComEvtHandle: public IMsgListener
{
public:
ComEvtHandle( _LST_TYPE& _p_evt_hd, LST_EVT_TYPE* _p_evt_cdt )
{
mp_evt_hd = _p_evt_hd;
_p_evt_hd = 0;
if( 0 != _p_evt_cdt )
mp_evt_cdt = *_p_evt_cdt;
}
virtual ~ComEvtHandle()
{
delete mp_evt_hd;
mp_evt_hd = 0;
}
virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt )
{
LST_EVT_TYPE::iterator it = mp_evt_cdt.begin();
while( mp_evt_cdt.end() != it )
{
LST_EVT_TYPE::iterator tmp = _evt->find( it->first );
if( _evt->end() == tmp || tmp->second != it->second )
return false;
it++;
}
return mp_evt_hd->OnEvt(_msg, _evt);
}
private:
_LST_TYPE mp_evt_hd;
LST_EVT_TYPE mp_evt_cdt;
};
ComEvtHandle m_evt_handle;
MsgServer4* m_msg_svr;
int m_type;
string m_msg;
};
typedef bool (*ON_EVT_TYPE)(string, LST_EVT_TYPE*);
template<>
class ComEvtHelper< ON_EVT_TYPE >: public EvtHelper
{
public:
ComEvtHelper( MsgServer4* _msg_svr, string _msg, int _lst_type, ON_EVT_TYPE& _evt_hd, LST_EVT_TYPE* _p_evt_cdt = 0 ):m_evt_handle(_evt_hd, _p_evt_cdt)
{
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:
class ComEvtHandle: public IMsgListener
{
public:
ComEvtHandle( ON_EVT_TYPE& _evt_hd, LST_EVT_TYPE* _p_evt_cdt )
{
mp_evt_hd = _evt_hd;
if( 0 != _p_evt_cdt )
mp_evt_cdt = *_p_evt_cdt;
}
virtual bool OnEvt( string _msg, LST_EVT_TYPE* _evt )
{
LST_EVT_TYPE::iterator it = mp_evt_cdt.begin();
while( mp_evt_cdt.end() != it )
{
LST_EVT_TYPE::iterator tmp = _evt->find( it->first );
if( _evt->end() == tmp || tmp->second != it->second )
return false;
it++;
}
return mp_evt_hd(_msg, _evt);
}
private:
ON_EVT_TYPE mp_evt_hd;
LST_EVT_TYPE mp_evt_cdt;
};
ComEvtHandle m_evt_handle;
MsgServer4* m_msg_svr;
int m_type;
string m_msg;
};
template< class _LST_TYPE >
EvtHelper* CreateComEvtHelper( MsgServer4* _msg_svr, string _msg, int _lst_type, _LST_TYPE _p_evt_hd, LST_EVT_TYPE* _p_evt_cdt = 0 )
{
return new ComEvtHelper<_LST_TYPE>( _msg_svr, _msg, _lst_type, _p_evt_hd, _p_evt_cdt );
}
/********************************************************************
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;
bool OnEvtTest( string _msg, LST_EVT_TYPE* _evt )
{
cout<<"OnEvtTest"<<endl;
return false;
}
void main()
{
MsgServer4Helper g_msg_svr4;
g_msg_svr4.Init();
LST_EVT_TYPE condition;
condition["1"] = (void*)1;
EvtHelper* p_vote = CreateComEvtHelper( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::VOTE, new VoteTest(),&condition);
EvtHelper* p_init = CreateComEvtHelper( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::INIT, OnEvtTest, &condition );
EvtHelper* p_act = CreateComEvtHelper( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::ACTION, OnEvtTest, &condition );
EvtHelper* p_uninit = CreateComEvtHelper( g_msg_svr4.GetSvr(), "123", MsgServer4Helper::UNINIT, OnEvtTest, &condition );
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();
}