//EventEngineT
// 发送最大层数
#define FIRE_MAX_LAYERNUM 20
// 引用最大层数
#define REF_MAX_LAYERNUM 5
// 事件key
struct __EventKey
{
DWORD dwSrcID; // 发送源标识(UID中"序列号"部份)
BYTE bSrcType; // 发送源类型
WORD wEventID; // 事件ID
BYTE bReserve; // 保留
};
struct SEventKey
{
union
{
__EventKey _key;
LONGLONG _value;
};
SEventKey(void)
{
_value = 0;
}
bool operator == (const SEventKey &eventkey) const
{
return _value == eventkey._value;
}
bool operator < (const SEventKey &eventkey) const
{
return _value < eventkey._value;
}
};
// 特化hash函数
namespace stdext
{
inline size_t hash_value(const SEventKey &eventkey)
{
DWORD k1 = (eventkey._key.dwSrcID & 0xFFFF) << 16;
DWORD k2 = (eventkey._key.wEventID & 0xFF) << 8;
DWORD k3 = eventkey._key.bSrcType;
return k1 + k2 + k3;
}
}
// 事件引擎模板
template< class TSink, class TOnEventObject >
class TEventEngine
{
private:
struct SSubscibeInfo
{
TSink * pSink;
char szDesc[32];
int nCallCount;
bool bRemoveFlag;
SSubscibeInfo(TSink * pPrameSink, LPCSTR pDesc)
{
pSink = pPrameSink;
nCallCount = 0;
bRemoveFlag = false;
if(pDesc != NULL)
{
lstrcpyn(szDesc, pDesc, sizeof(szDesc));
}
else
{
szDesc[0] = '\0';
}
}
void Add(void)
{
nCallCount++;
}
void Sub(void)
{
nCallCount--;
}
};
// 一个事件KEY的订阅者列表
typedef std::list< SSubscibeInfo > TLIST_SUBSCIBEINFO;
// 所有事件KEY的订阅者列表
typedef stdext::hash_map<SEventKey, TLIST_SUBSCIBEINFO > TMAP_SAFESINK;
public:
TEventEngine()
{
m_nFireLayerNum = 0;
}
virtual ~TEventEngine()
{
typename TMAP_SAFESINK::iterator it = m_mapSafeSink.begin();
for( ; it != m_mapSafeSink.end(); ++it)
{
TLIST_SUBSCIBEINFO * plisSubscibeInfo = &((*it).second);
plisSubscibeInfo->clear();
}
m_mapSafeSink.clear();
}
bool Subscibe(TSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc)
{
if(pSink == NULL)
{
return false;
}
// 事件KEY
SEventKey eventkey;
eventkey._key.wEventID = wEventID;
eventkey._key.bSrcType = bSrcType;
eventkey._key.dwSrcID = dwSrcID;
// 订阅者信息
SSubscibeInfo subscibeinfo(pSink, pszDesc);
// 加入到订阅列表
typename TMAP_SAFESINK::iterator it = m_mapSafeSink.find(eventkey);
if(it == m_mapSafeSink.end())
{
TLIST_SUBSCIBEINFO listSubscibeInfo;
listSubscibeInfo.push_front(subscibeinfo);
// 加入到订阅列表
m_mapSafeSink.insert(TMAP_SAFESINK::value_type(eventkey, listSubscibeInfo));
}
else
{
TLIST_SUBSCIBEINFO * plistSubscibeInfo = &((*it).second);
plistSubscibeInfo->push_front(subscibeinfo);
}
return true;
}
bool UnSubscibe(TSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID)
{
if(pSink == NULL)
{
return false;
}
SEventKey eventkey;
eventkey._key.wEventID = wEventID;
eventkey._key.bSrcType = bSrcType;
eventkey._key.dwSrcID = dwSrcID;
typename TMAP_SAFESINK::iterator it = m_mapSafeSink.find(eventkey);
if(it != m_mapSafeSink.end())
{
TLIST_SUBSCIBEINFO * plistSubscibeInfo = &((*it).second);
typename TLIST_SUBSCIBEINFO::iterator itList = plistSubscibeInfo->begin();
for( ; itList != plistSubscibeInfo->end(); ++itList)
{
SSubscibeInfo * pSubscibeInfo = &(*itList);
if(pSubscibeInfo->pSink == pSink)
{
if(pSubscibeInfo->nCallCount == 0)
{
plistSubscibeInfo->erase(itList);
}
else
{
pSubscibeInfo->bRemoveFlag = true;
}
break;
}
}
}
return true;
}
bool Fire(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
SEventKey eventkey;
eventkey._key.wEventID = wEventID;
eventkey._key.bSrcType = bSrcType;
// 先发送有源指针的
eventkey._key.dwSrcID = dwSrcID;
if(eventkey._key.dwSrcID != 0)
{
bool bResult = Fire(eventkey, wEventID, bSrcType, dwSrcID, pszContext, nLen);
if(!bResult)
{
return false;
}
}
// 然后发送源指针的
eventkey._key.dwSrcID = 0;
bool bResult = Fire(eventkey, wEventID, bSrcType, dwSrcID, pszContext, nLen);
if(!bResult)
{
return false;
}
return true;
}
private:
bool Fire(SEventKey &eventkey, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
m_nFireLayerNum++;
if(m_nFireLayerNum >= FIRE_MAX_LAYERNUM)
{
Error("事件服务器非法!死循环调用 EVENTID = " << wEventID << "SRCTYPE = " << bSrcType << endl);
memcpy(NULL, NULL, -1);
m_nFireLayerNum--;
return false;
}
typename TMAP_SAFESINK::iterator itMap = m_mapSafeSink.find(eventkey);
if(itMap != m_mapSafeSink.end())
{
TLIST_SUBSCIBEINFO * plistSubscibeInfo = &((*itMap).second);
typename TLIST_SUBSCIBEINFO::iterator itList = plistSubscibeInfo->begin();
for( ; itList != plistSubscibeInfo->end(); )
{
SSubscibeInfo * pSubscibeInfo = &(*itList);
if(pSubscibeInfo->nCallCount >= REF_MAX_LAYERNUM)
{
Error("事件服务器内同一事件循环调用!严重问题!EVENTID = " << wEventID << "描述 = " << pSubscibeInfo->szDesc << endl);
m_nFireLayerNum--;
return false;
}
if(!pSubscibeInfo->bRemoveFlag)
{
bool bResult = false;
try
{
pSubscibeInfo->Add();
bResult = m_FireEventObject(pSubscibeInfo->pSink, wEventID, bSrcType, dwSrcID, pszContext, nLen);
pSubscibeInfo->Sub();
}
catch(...)
{
Error("事件服务器非法!EVENTID = " << wEventID << "描述 = " << pSubscibeInfo->szDesc << endl);
return false;
}
if(pSubscibeInfo->bRemoveFlag && pSubscibeInfo->nCallCount == 0)
{
itList = plistSubscibeInfo->erase(itList);
}
else
{
++itList;
}
if(!bResult)
{
m_nFireLayerNum--;
return false;
}
}
else
{
if(pSubscibeInfo->nCallCount == 0)
{
itList = plistSubscibeInfo->erase(itList);
}
else
{
++itList;
}
}
}
}
m_nFireLayerNum--;
return true;
}
private:
// 事件发送对像
TOnEventObject m_FireEventObject;
// 事件对像列表
TMAP_SAFESINK m_mapSafeSink;
// 发送层数
int m_nFireLayerNum;
};
//IEventEngine
/// 投票事件sink
struct IEventVoteSink
{
virtual bool OnVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;
};
/// 执行事件sink
struct IEventExecuteSink
{
virtual void OnExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;
};
/// 事件引擎
struct IEventEngine
{
virtual void Release(void) = 0;
virtual bool FireVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;
virtual void FireExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;
virtual bool Subscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc) = 0;
virtual bool Subscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc) = 0;
virtual bool UnSubscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID) = 0;
virtual bool UnSubscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID) = 0;
};
//EventEngine.h
struct OnVoteObject
{
bool operator() (IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
if(pSink == NULL)
{
return false;
}
return pSink->OnVote(wEventID, bSrcType, dwSrcID, pszContext, nLen);
}
};
struct OnExecuteObject
{
bool operator() (IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
if(pSink == NULL)
{
return false;
}
pSink->OnExecute(wEventID, bSrcType, dwSrcID, pszContext, nLen);
return true;
}
};
class CEventEngine : public IEventEngine
{
typedef TEventEngine< IEventVoteSink, OnVoteObject > TCENTER_VOTE;
typedef TEventEngine< IEventExecuteSink, OnExecuteObject > TCENTER_EXECUTE;
public:
IEventEngine///
virtual void Release(void);
virtual bool FireVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen);
virtual void FireExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen);
virtual bool Subscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc);
virtual bool Subscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc);
virtual bool UnSubscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID);
virtual bool UnSubscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID);
CEventEngine///
bool Create(void);
CEventEngine(void);
virtual ~CEventEngine(void);
private:
// 投票中心
TCENTER_VOTE m_VoteCenter;
// 执行中心
TCENTER_EXECUTE m_ExecuteCenter;
};
extern CEventEngine * g_pEventEngine;
//EventEngine.cpp
CEventEngine * g_pEventEngine = NULL;
CEventEngine::CEventEngine(void)
{
}
CEventEngine::~CEventEngine(void)
{
}
void CEventEngine::Release(void)
{
delete this;
//全局变量是魔鬼!
assert(this == g_pEventEngine);
g_pEventEngine = NULL;
}
bool CEventEngine::Create(void)
{
return true;
}
bool CEventEngine::FireVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
return m_VoteCenter.Fire(wEventID, bSrcType, dwSrcID, pszContext, nLen);
}
void CEventEngine::FireExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
m_ExecuteCenter.Fire(wEventID, bSrcType, dwSrcID, pszContext, nLen);
}
bool CEventEngine::Subscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc)
{
return m_VoteCenter.Subscibe(pSink, wEventID, bSrcType, dwSrcID, pszDesc);
}
bool CEventEngine::Subscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc)
{
return m_ExecuteCenter.Subscibe(pSink, wEventID, bSrcType, dwSrcID, pszDesc);
}
bool CEventEngine::UnSubscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID)
{
return m_VoteCenter.UnSubscibe(pSink, wEventID, bSrcType, dwSrcID);
}
bool CEventEngine::UnSubscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID)
{
return m_ExecuteCenter.UnSubscibe(pSink, wEventID, bSrcType, dwSrcID);
}
API_EXPORT IEventEngine * CreateEventEngine(void)
{
// 如果创建了,则直接返回
if(g_pEventEngine != NULL)
{
return g_pEventEngine;
}
// 实例化
g_pEventEngine = new CEventEngine();
if(!g_pEventEngine)
{
return NULL;
}
// 创建
if(!g_pEventEngine->Create())
{
SAFE_DELETE(g_pEventEngine);
return NULL;
}
return g_pEventEngine;
}
//CPersonMovePart.h
class CPersonComposeSkepPart : public IEventExecuteSink,
public IEventVoteSink
{
public:
/IEventExecuteSink//
virtual void OnExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen);
/IEventVoteSink//
virtual bool OnVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen);
};
//CPersonMovePart.cpp
bool CPersonComposeSkepPart::Create(IEntity * pMaster, LPCSTR pszData, int nLen, bool bDBImport)
{
// 订阅 EVENT_SKEP_ADDGOODS 执行事件
if( !g_pEventEngine->Subscibe(static_cast<IEventExecuteSink *>(this), EVENT_SKEP_ADDGOODS,
SOURCE_TYPE_SKEP, m_pSkep->GetSkepID(), "CPersonComposeSkepPart::Create") )
{
return false;
}
// 订阅 EVENT_SKEP_REMOVEGOODS 投票事件
if( !g_pEventEngine->Subscibe(static_cast<IEventVoteSink *>(this), EVENT_SKEP_REMOVEGOODS,
SOURCE_TYPE_SKEP, m_pSkep->GetSkepID(), "CPersonComposeSkepPart::Create") )
{
return false;
}
return true;
}
void CPersonComposeSkepPart::OnExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
switch(wEventID)
{
case EVENT_SKEP_ADDGOODS:
{
}
break;
default:
break;
}
}
bool CPersonComposeSkepPart::OnVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen)
{
switch(wEventID)
{
case EVENT_SKEP_REMOVEGOODS:
{
return OnVoteRemoveGoods(pszContext, nLen);
}
break;
default:break;
}
return true;
}
// 投票移除物品
SEventSkepRemoveGoods_S eventremovegoods;
if(!g_pEventEngine.FireVote(EVENT_SKEP_REMOVEGOODS,
SOURCE_TYPE_SKEP,
pMsgLink->dwSrcSkepID,
(LPCSTR)&eventremovegoods,
sizeof(eventremovegoods)))
{
return false;
}