事件引擎

来源:互联网 发布:宁波派双网络 编辑:程序博客网 时间:2024/06/05 05:29
//EventEngineT// 发送最大层数#define FIRE_MAX_LAYERNUM20// 引用最大层数#define REF_MAX_LAYERNUM5// 事件keystruct __EventKey{DWORDdwSrcID;// 发送源标识(UID中"序列号"部份)BYTEbSrcType;// 发送源类型WORDwEventID;// 事件ID BYTEbReserve;// 保留};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;charszDesc[32];intnCallCount;boolbRemoveFlag;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;}// 事件KEYSEventKey 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:// 事件发送对像TOnEventObjectm_FireEventObject;// 事件对像列表TMAP_SAFESINKm_mapSafeSink;// 发送层数intm_nFireLayerNum;};//IEventEngine/// 投票事件sinkstruct IEventVoteSink {virtual boolOnVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;};/// 执行事件sinkstruct IEventExecuteSink {virtual voidOnExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;};/// 事件引擎struct IEventEngine{virtual voidRelease(void) = 0;virtual boolFireVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;virtual voidFireExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen) = 0;virtual boolSubscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc) = 0;virtual boolSubscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc) = 0;virtual boolUnSubscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID) = 0;virtual boolUnSubscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID) = 0;};//EventEngine.hstruct 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 voidRelease(void);virtual boolFireVote(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen);virtual voidFireExecute(WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszContext, int nLen);virtual boolSubscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc);virtual boolSubscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID, LPCSTR pszDesc);virtual boolUnSubscibe(IEventVoteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID);virtual boolUnSubscibe(IEventExecuteSink * pSink, WORD wEventID, BYTE bSrcType, DWORD dwSrcID);////////////////////////CEventEngine///////////////////////////////boolCreate(void);CEventEngine(void);virtual ~CEventEngine(void);private:// 投票中心TCENTER_VOTEm_VoteCenter;// 执行中心TCENTER_EXECUTEm_ExecuteCenter;};extern CEventEngine *g_pEventEngine;//EventEngine.cppCEventEngine *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.hclass 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.cppbool 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;}

0 0
原创粉丝点击