事件引擎

//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;
	}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值