--- 事件最好不混入在消息内部,因为从概念上讲,事件和消息是两种不同的事物;从实际上讲,使用时事件没必要带上复杂的参数,而获得事件也没必要从消息参数中获得,那样会增加操作.
/********************************************************************
* 文件名: 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){};
virtual ~Msg_Head(){}
//类似树结点,不管有无后续都有一个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;
}
private:
pair<const long, void*> m_data;
};
// 事件决策者订阅者接口
template< class _TMsg = Msg_Head >
struct IPass_Event_Listener
{
virtual ~IPass_Event_Listener<_TMsg>(){};
typedef _TMsg Msg;
virtual bool on_pass(Msg *_p_msg) = 0;
};
// 事件否决者订阅者接口
template< class _TMsg = Msg_Head >
struct IVote_Event_Listener
{
virtual ~IVote_Event_Listener<_TMsg>(){};
typedef _TMsg Msg;
virtual bool on_vote(Msg *_p_msg) = 0;
};
// 行为执行者订阅者接口
template< class _TMsg = Msg_Head >
struct IAction_Event_Listener
{
virtual ~IAction_Event_Listener<_TMsg>(){};
typedef _TMsg Msg;
virtual void on_action(Msg *_p_msg) = 0;
};
// 事件响应者订阅者接口
template< class _TMsg = Msg_Head >
struct IResponse_Event_Listener
{
virtual ~IResponse_Event_Listener<_TMsg>(){};
typedef _TMsg Msg;
virtual void on_response(Msg *_p_msg) = 0;
};
// 事件服务器 -- 事件驱动,消息处理
template< class _TEvt = long, class _TMsg = Msg_Head>
class IEvt_Server
{
public:
virtual ~IEvt_Server(){};
typedef IPass_Event_Listener< _TMsg > PASS_LISTENER_TYPE;
typedef IVote_Event_Listener< _TMsg > VOTE_LISTENER_TYPE;
typedef IAction_Event_Listener< _TMsg > ACTION_LISTENER_TYPE;
typedef IResponse_Event_Listener< _TMsg > RESPONSE_LISTENER_TYPE;
//监控时以事件为要素
virtual bool add_listener(const _TEvt _event, PASS_LISTENER_TYPE* _p_listener) = 0;
virtual void remove_listener(const _TEvt _event, PASS_LISTENER_TYPE* _p_listener) = 0;
virtual bool add_listener(const _TEvt _event, VOTE_LISTENER_TYPE* _p_listener) = 0;
virtual void remove_listener(const _TEvt _event, VOTE_LISTENER_TYPE* _p_listener) = 0;
virtual bool add_listener(const _TEvt _event, ACTION_LISTENER_TYPE* _p_listener) = 0;
virtual void remove_listener(const _TEvt _event, ACTION_LISTENER_TYPE* _p_listener) = 0;
virtual bool add_listener(const _TEvt _event, RESPONSE_LISTENER_TYPE* _p_listener) = 0;
virtual void remove_listener(const _TEvt _event, RESPONSE_LISTENER_TYPE* _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:
virtual bool add_listener(const _TEvt _event, PASS_LISTENER_TYPE* _p_listener){ return m_pass_server.add_listener(_event, _p_listener); }
virtual void remove_listener(const _TEvt _event, PASS_LISTENER_TYPE* _p_listener){ m_pass_server.remove_listener(_event, _p_listener); }
virtual bool add_listener(const _TEvt _event, VOTE_LISTENER_TYPE* _p_listener){ return m_vote_server.add_listener(_event, _p_listener); }
virtual void remove_listener(const _TEvt _event, VOTE_LISTENER_TYPE* _p_listener){ m_vote_server.remove_listener(_event, _p_listener); }
virtual bool add_listener(const _TEvt _event, ACTION_LISTENER_TYPE* _p_listener){ return m_action_server.add_listener(_event, _p_listener); }
virtual void remove_listener(const _TEvt _event, ACTION_LISTENER_TYPE* _p_listener){ m_action_server.remove_listener(_event, _p_listener); }
virtual bool add_listener(const _TEvt _event, RESPONSE_LISTENER_TYPE* _p_listener){ return m_response_server.add_listener(_event, _p_listener); }
virtual void remove_listener(const _TEvt _event, RESPONSE_LISTENER_TYPE* _p_listener){ m_response_server.remove_listener(_event, _p_listener); }
virtual void dispatch_pass_msg(const _TEvt _event, _TMsg *_p_msg)
{
if( m_pass_server.dispatch_msg( _event, _p_msg ) )
{
m_action_server.dispatch_msg( _event, _p_msg );
m_response_server.dispatch_msg( _event, _p_msg );
}
}
virtual void dispatch_vote_msg(const _TEvt _event, _TMsg *_p_msg)
{
if( m_vote_server.dispatch_msg( _event, _p_msg ) )
{
m_action_server.dispatch_msg( _event, _p_msg );
m_response_server.dispatch_msg( _event, _p_msg );
}
}
protected:
//基服
template< typename _LISTENER_TYPE >
class Server
{
public:
typedef vector< _LISTENER_TYPE* > VCT_TYPE;
typedef map<_TEvt, VCT_TYPE > MAP_TYPE;
Server(){ m_delete_sign.out_for(); }
//订阅
bool add_listener(const _TEvt _event, _LISTENER_TYPE* _p_listener)
{
VCT_TYPE& vct = m_evt_listener_table[_event];
VCT_TYPE::iterator it = find( vct.begin(), vct.end(), _p_listener );
if( vct.end() == it)
{
vct.push_back(_p_listener);
return true;
}
return false;
}
//取消
void remove_listener(const _TEvt _event, _LISTENER_TYPE* _p_listener)
{
VCT_TYPE& vct = m_evt_listener_table[_event];
VCT_TYPE::iterator it = find( vct.begin(), vct.end(), _p_listener );
if( vct.end() != it)
{
if( m_delete_sign.is_for() && it == m_nonius )
{
m_nonius = vct.erase(it);
m_delete_sign.delete_in_for();
}
else vct.erase(it);
}
}
//派发消息
virtual bool dispatch_msg(const _TEvt _event, _TMsg *_p_msg) = 0;
protected:
class Delete_Sign
{
public:
inline void in_for(){ operator_state = 1; }
inline void out_for(){ operator_state = 0; }
inline void delete_in_for(){ operator_state = 2;}
inline bool is_for(){ return (operator_state >= 1)? true : false; }
inline bool no_deletion(){ return (2 == operator_state)? false : true; }
private:
byte operator_state;
};
Delete_Sign m_delete_sign;
MAP_TYPE m_evt_listener_table;
typename VCT_TYPE::iterator m_nonius; ;
};
//通过
class Pass_Server: public Server< PASS_LISTENER_TYPE >
{
public:
//派发消息
bool dispatch_msg(const _TEvt _event, _TMsg *_p_msg)
{
bool failed = true;
MAP_TYPE::iterator pass_it = m_evt_listener_table.find( _event );
if( m_evt_listener_table.end() != pass_it)
{
VCT_TYPE& vct = pass_it->second;
for( m_nonius = vct.begin(); vct.end() != m_nonius;)
{
m_delete_sign.in_for();
VCT_TYPE::const_iterator it = m_nonius;
if( (*it)->on_pass(_p_msg) )
{
//有一票通过
failed = true;
break;
}
if( m_delete_sign.no_deletion() )
m_nonius++;
}
}
m_delete_sign.out_for();
if( failed ) return false;
else return true;
}
};
//否决
class Vote_Server: public Server< VOTE_LISTENER_TYPE >
{
public:
//派发消息
bool dispatch_msg(const _TEvt _event, _TMsg *_p_msg)
{
bool ret = true;
MAP_TYPE::iterator vote_it = m_evt_listener_table.find( _event );
if( m_evt_listener_table.end() != vote_it)
{
VCT_TYPE& vct = vote_it->second;
for( m_nonius = vct.begin(); vct.end() != m_nonius;)
{
m_delete_sign.in_for();
VCT_TYPE::const_iterator it = m_nonius;
if( (*it)->on_vote(_p_msg) )
{
//有否决票
ret = false;
break;
}
if( m_delete_sign.no_deletion() )
m_nonius++;
}
}
m_delete_sign.out_for();
return ret;
}
};
//执行
class Action_Server: public Server< ACTION_LISTENER_TYPE >
{
public:
//派发消息
bool dispatch_msg(const _TEvt _event, _TMsg *_p_msg)
{
MAP_TYPE::iterator pass_it = m_evt_listener_table.find( _event );
if( m_evt_listener_table.end() != pass_it)
{
VCT_TYPE& vct = pass_it->second;
for( m_nonius = vct.begin(); vct.end() != m_nonius;)
{
m_delete_sign.in_for();
VCT_TYPE::const_iterator it = m_nonius;
(*it)->on_action(_p_msg);
if( m_delete_sign.no_deletion() )
m_nonius++;
}
}
m_delete_sign.out_for();
return true;
}
};
//响应
class Response_Server: public Server< RESPONSE_LISTENER_TYPE >
{
public:
//派发消息
bool dispatch_msg(const _TEvt _event, _TMsg *_p_msg)
{
MAP_TYPE::iterator pass_it = m_evt_listener_table.find( _event );
if( m_evt_listener_table.end() != pass_it)
{
VCT_TYPE& vct = pass_it->second;
for( m_nonius = vct.begin(); vct.end() != m_nonius;)
{
m_delete_sign.in_for();
VCT_TYPE::const_iterator it = m_nonius;
(*it)->on_response(_p_msg);
if( m_delete_sign.no_deletion() )
m_nonius++;
}
}
m_delete_sign.out_for();
return true;
}
};
Pass_Server m_pass_server;
Vote_Server m_vote_server;
Action_Server m_action_server;
Response_Server m_response_server;
};
}
module("EvtSvr", package.seeall)
--事件
function new_evt( _evt_iid, _evt_uid )
local public = { evt_iid = _evt_iid, evt_uid = _evt_uid }
return public
end
--查找obj位置
function find_obj_pos(_t, _p)
local len = table.getn( _t )
for i=1, len do
if _t[i] == _p then
return i
end
end
return nil
end
--否决事件监听
function new_vote_evt_listener()
local public = {}
function public.on_vote( _t_evt )
myPrint("未实现 new_vote_evt_listener", 1)
return false
end
return public
end
--紧急消息监听
function new_urgency_evt_listener()
local public = {}
function public.on_urgency( _t_evt )
myPrint("未实现 new_urgency_evt_listener", 1)
end
return public
end
--执行消息监听
function new_action_evt_listener()
local public = {}
function public.on_action( _t_evt )
myPrint("未实现 new_action_evt_listener", 1)
end
return public
end
--完毕消息监听
function new_response_evt_listener()
local public = {}
function public.on_response( _t_evt )
myPrint("未实现 new_response_evt_listener", 1)
end
return public
end
--消息处理机
function new_evt_server()
local function new_event_map()
local this_public = {}
this_public.map = {}
function this_public.add_listener(_p_recv, _evt_iid)
if nil == this_public.map[_evt_iid] then
this_public.map[_evt_iid] = {}
end
local t = this_public.map[_evt_iid]
if nil == find_obj_pos(t, _p_recv) then
t[ table.getn(t) + 1 ] = _p_recv
end
end
function this_public.remove_listener(_p_recv, _evt_iid)
if nil ~= this_public.map[_evt_iid] then
local t = this_public.map[_evt_iid]
local id = find_obj_pos(t, _p_recv)
if nil ~= id then
local len = table.getn(t)
t[id] = t[len]
t[len] = nil
end
if table.getn(t) <= 0 then
this_public.map[_evt_iid] = nil
end
end
end
function this_public.clear()
this_public.map = {}
end
return this_public
end
local public = {}
public.vote_map = new_event_map()
public.urgency_map = new_event_map()
public.action_map = new_event_map()
public.response_map = new_event_map()
function public.clear()
public.vote_map.clear()
public.action_map.clear()
public.response_map.clear()
end
function public.dispatch_evt( _t_evt )
--记录当前服,用于回复消息
_t_evt.from_evt_svr = public
--否决
if nil ~= public.vote_map.map[ _t_evt.evt_iid ] then
local t = public.vote_map.map[ _t_evt.evt_iid ]
local len = table.getn( t )
for i=1, len do
if t[i].on_vote( _t_evt ) then
return
end
end
end
--紧急消息
if nil ~= public.urgency_map.map[ _t_evt.evt_iid ] then
local t = public.urgency_map.map[ _t_evt.evt_iid ]
local len = table.getn( t )
for i=1, len do
t[i].on_urgency( _t_evt )
end
end
--触发
if nil ~= public.action_map.map[ _t_evt.evt_iid ] then
local t = public.action_map.map[ _t_evt.evt_iid ]
local len = table.getn( t )
for i=1, len do
t[i].on_action( _t_evt )
end
end
--完毕
if nil ~= public.response_map.map[ _t_evt.evt_iid ] then
local t = public.response_map.map[ _t_evt.evt_iid ]
local len = table.getn( t )
for i=1, len do
t[i].on_response( _t_evt )
end
end
end
return public
end