消息机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();

}


 

 

posted @ 2013-09-10 21:05  pangbangb  阅读(256)  评论(0编辑  收藏  举报