消息槽

//IEntityServer

/消息投票sink///
struct IMessageVoteSink
{
	virtual bool				OnVote(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen) = NULL;
};

/消息执行sink///
struct IMessageExecuteSink
{
	virtual void				OnExecute(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen) = NULL;
};

//MessageSlot.h
struct IMessageVoteSink;
struct IMessageExecuteSink;

// 定义
class CMessageSlot
{
	///
	// 一个投票订阅sink信息
	struct SVoteSinkInfo
	{
		// 否决sink
		IMessageVoteSink *				pSink;

		// 订阅描述
		char							szDesc[32];	

		SVoteSinkInfo(void)
		{
			memset(this, 0, sizeof(SVoteSinkInfo));
		}

		~SVoteSinkInfo(void)
		{
			memset(this, 0, sizeof(SVoteSinkInfo));
		}

		SVoteSinkInfo(IMessageVoteSink * pVoteSink, LPCSTR pszDesc)
		{
			// 否决sink
			pSink = pVoteSink;

			// 订阅描述
			lstrcpyn(szDesc, pszDesc, sizeof(szDesc));
		}

		void Clean(void)
		{
			memset(this, 0, sizeof(SVoteSinkInfo));
		}
	};

	// 一个消息的所有投票订阅sink
	typedef list< SVoteSinkInfo >		TLIST_VOTESINK;

	// 所有消息的所有投票订阅sink
	struct SVoteSinkList
	{
		// 投票订阅者sink
		TLIST_VOTESINK		listVoteSink;

		// 是否在轮询过程中,有删除节点发生
		bool				bRemoveFlag;

		SVoteSinkList(void)
		{
			// 投票订阅者sink
			listVoteSink.clear();

			// 是否在轮询过程中,有删除节点发生
			bRemoveFlag = false;
		}

		~SVoteSinkList(void)
		{
			// 投票订阅者sink
			listVoteSink.clear();

			// 是否在轮询过程中,有删除节点发生
			bRemoveFlag = false;
		}
	};
	typedef vector< SVoteSinkList >	TVECTOR_VOTESINK;

	///
	// 一个执行订阅sink信息
	struct SExecuteSinkInfo
	{
		// 执行sink
		IMessageExecuteSink *			pSink;

		// 订阅描述
		char							szDesc[32];

		// 不允许循环发送消息,比如发送A消息,回调还未返回,又发送A送消息
		int								nEndFlag;

		SExecuteSinkInfo(void)
		{
			memset(this, 0, sizeof(SExecuteSinkInfo));
		}

		SExecuteSinkInfo(IMessageExecuteSink * pExecuteSink, LPCSTR pszDesc)
		{
			// 执行sink
			pSink = pExecuteSink;

			// 订阅描述
			lstrcpyn(szDesc, pszDesc, sizeof(szDesc));

			// 缺省为0
			nEndFlag = 0;
		}

		~SExecuteSinkInfo(void)
		{
			memset(this, 0, sizeof(SExecuteSinkInfo));
		}

		void Clean(void)
		{
			memset(this, 0, sizeof(SExecuteSinkInfo));
		}
	};
	// 所有消息的所有投票订阅sink
	typedef vector< SExecuteSinkInfo >	TVECTOR_EXECUTESINK;

public:
	bool				Subscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink, LPCSTR pszDesc);

	bool				UnSubscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink);

	bool				Subscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink, LPCSTR pszDesc);

	bool				UnSubscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink);

	void				Fire(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen);

	void				Init(DWORD dwInitOpenSize);

	CMessageSlot(void);

	virtual ~CMessageSlot(void);

private:

	void				ResizeVector(void);

private:
	// 消息码映射表
	int					m_nMsgIDSinkTable[MSG_ACTION_MAXID];

	// 投票订阅sink
	TVECTOR_VOTESINK	m_vectorVoteSink;

	// 否决订阅sink
	TVECTOR_EXECUTESINK	m_vectorExecuteSink;

	// vector最大开放
	int					m_nVectorOpenSize;

	// 当前vector分配到何个位置了
	int					m_nVectorCurAllot;
};


//MessageSlot.cpp

CMessageSlot::CMessageSlot(void)
{
	// 消息码映射表
	memset(m_nMsgIDSinkTable, -1, sizeof(m_nMsgIDSinkTable));

	// 投票订阅sink
	m_vectorVoteSink.clear();

	// 否决订阅sink
	m_vectorExecuteSink.clear();

	// vector最大开放
	m_nVectorOpenSize = 0;

	// 当前vector分配到何个位置了
	m_nVectorCurAllot = 0;
}

CMessageSlot::~CMessageSlot(void)
{
	// 投票订阅sink
	m_vectorVoteSink.clear();

	// 否决订阅sink
	m_vectorExecuteSink.clear();
}

void CMessageSlot::Init(DWORD dwInitOpenSize)
{
	// vector最大开放
	m_nVectorOpenSize = dwInitOpenSize;

	// 设置投票订阅sink vector大小
	m_vectorVoteSink.resize(m_nVectorOpenSize);

	// 设置否决订阅sink vector大小
	m_vectorExecuteSink.resize(m_nVectorOpenSize);
}

bool CMessageSlot::Subscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink, LPCSTR pszDesc)
{
	if(dwMsgID < 0 || dwMsgID >= MSG_ACTION_MAXID || pVoteSink == NULL || pszDesc == NULL)
	{
		return false;
	}

	int nThisLoc = m_nMsgIDSinkTable[dwMsgID];
	if(nThisLoc == -1)
	{
		m_nVectorCurAllot++;
		if(m_nVectorCurAllot >= m_nVectorOpenSize)
		{
			ResizeVector();
		}

		m_nMsgIDSinkTable[dwMsgID] = m_nVectorCurAllot;
		nThisLoc = m_nVectorCurAllot;

		// 压入	
		SVoteSinkInfo votesinkinfo(pVoteSink, pszDesc);

		SVoteSinkList votesinklist;
		votesinklist.listVoteSink.push_back(votesinkinfo);	
		m_vectorVoteSink[nThisLoc] = votesinklist;
	}
	else
	{
		// 查找是否重复订阅
		SVoteSinkList * pVoteSinkList = &m_vectorVoteSink[nThisLoc];
		TLIST_VOTESINK * plistVoteSink = &pVoteSinkList->listVoteSink;
		if(plistVoteSink != NULL)
		{
			TLIST_VOTESINK::iterator itL = plistVoteSink->begin();
			for( ; itL != plistVoteSink->end(); ++itL)
			{
				SVoteSinkInfo * pVoteSinkInfo = &(*itL);
				if(pVoteSinkInfo->pSink == pVoteSink)
				{
					return false;
				}
			}

			SVoteSinkInfo votesinkinfo(pVoteSink, pszDesc);
			plistVoteSink->push_back(votesinkinfo);			
		}
	}	

	return true;
}

bool CMessageSlot::UnSubscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink)
{
	if(dwMsgID < 0 || dwMsgID >= MSG_ACTION_MAXID || pVoteSink == NULL)
	{
		return false;
	}

	int nThisLoc = m_nMsgIDSinkTable[dwMsgID];
	if(nThisLoc == -1)
	{
		return true;
	}

	SVoteSinkList * pVoteSinkList = &m_vectorVoteSink[nThisLoc];
	TLIST_VOTESINK * plistVoteSink = &pVoteSinkList->listVoteSink;
	if(plistVoteSink != NULL)
	{
		TLIST_VOTESINK::iterator itL = plistVoteSink->begin();
		for( ; itL != plistVoteSink->end(); ++itL)
		{
			SVoteSinkInfo * pVoteSinkInfo = &(*itL);
			if(pVoteSinkInfo->pSink == pVoteSink)
			{
				pVoteSinkInfo->Clean();
				pVoteSinkList->bRemoveFlag = true;

				return true;
			}
		}
	}

	return true;
}

bool CMessageSlot::Subscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink, LPCSTR pszDesc)
{
	if(dwMsgID < 0 || dwMsgID >= MSG_ACTION_MAXID || pExecuteSink == NULL || pszDesc == NULL)
	{
		return false;
	}

	int nThisLoc = m_nMsgIDSinkTable[dwMsgID];
	if(nThisLoc == -1)
	{
		m_nVectorCurAllot++;
		if(m_nVectorCurAllot >= m_nVectorOpenSize)
		{
			ResizeVector();
		}

		m_nMsgIDSinkTable[dwMsgID] = m_nVectorCurAllot;
		nThisLoc = m_nVectorCurAllot;

		// 压入
		SExecuteSinkInfo executesinkinfo(pExecuteSink, pszDesc);
		m_vectorExecuteSink[nThisLoc] = executesinkinfo;
	}
	else
	{
		// 查找是否重复订阅
		SExecuteSinkInfo * pExecuteSinkInfo = &m_vectorExecuteSink[nThisLoc];
		if(pExecuteSinkInfo->pSink == NULL)
		{
			// 执行sink
			pExecuteSinkInfo->pSink = pExecuteSink;

			// 订阅描述
			lstrcpyn(pExecuteSinkInfo->szDesc, pszDesc, sizeof(pExecuteSinkInfo->szDesc/*, pszDesc*/));

			return true;
		}
		else
		{
			Warning("重复订阅执行消息,消息码 = " << dwMsgID << ", 描述 = " << pszDesc << endl);				
			return false;
		}
	}	

	return true;
}

bool CMessageSlot::UnSubscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink)
{
	if(dwMsgID < 0 || dwMsgID >= MSG_ACTION_MAXID || pExecuteSink == NULL)
	{
		return false;
	}

	int nThisLoc = m_nMsgIDSinkTable[dwMsgID];
	if(nThisLoc == -1)
	{
		return true;
	}

	// 查找是否重复订阅
	SExecuteSinkInfo * pExecuteSinkInfo = &m_vectorExecuteSink[nThisLoc];
	if(pExecuteSinkInfo->pSink != NULL)
	{
		pExecuteSinkInfo->Clean();
	}

	return true;
}

void CMessageSlot::Fire(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen)
{
	if(dwMsgID < 0 || dwMsgID >= MSG_ACTION_MAXID)
	{
		return;
	}

	// 如果没人订阅投票或者执行消息,直接返回
	int nThisLoc = m_nMsgIDSinkTable[dwMsgID];
	if(nThisLoc == -1)
	{
		return;
	}

	// 如果同样的消息ID还没结束,不允许再次发同样的消息
	SExecuteSinkInfo * pExecuteSinkInfo = &m_vectorExecuteSink[nThisLoc];
	if(pExecuteSinkInfo == NULL || pExecuteSinkInfo->nEndFlag == 1)
	{
		Warning("本次消息尚未轮询完毕,不能再发同样消息,消息码 = " << dwMsgID << endl);
		
		return;
	}
	pExecuteSinkInfo->nEndFlag = 1;

	// 先发送投票消息
	SVoteSinkList * pVoteSinkList = &m_vectorVoteSink[nThisLoc];
	if(pVoteSinkList != NULL)
	{
		// 置在轮询过程中,有删除节点发生
		pVoteSinkList->bRemoveFlag = false;

		// 轮询
		bool bResult = true;
		bool bOldTimeRemove = false; // 有一些节点并不是轮询过程删除的,而是轮询前删除的
		TLIST_VOTESINK::iterator it = pVoteSinkList->listVoteSink.begin();
		for( ; it != pVoteSinkList->listVoteSink.end(); ++it)
		{
			if((*it).pSink != NULL)
			{
				try
				{
					if(!(*it).pSink->OnVote(dwMsgID, pGameMsgHead, pszMsg, nLen))
					{
						bResult = false;

						break;
					}
				}
				catch (...)
				{
					Error("发送投票消息非法,消息码 = " << dwMsgID << ", 描述 = " << (*it).szDesc << endl);
								
					return;					
				}				
			}
			else
			{
				bOldTimeRemove = true;
			}
		}

		// 如果在轮询过程中,有删节点发生
		if(pVoteSinkList->bRemoveFlag || bOldTimeRemove)
		{
			it = pVoteSinkList->listVoteSink.begin();
			for( ; it != pVoteSinkList->listVoteSink.end(); )
			{
				if((*it).pSink == NULL)
				{
					it = pVoteSinkList->listVoteSink.erase(it);
				}	
				else
				{
					++it;
				}
			}

			pVoteSinkList->bRemoveFlag = false;
		}

		// 如果有否决sink要截止
		if(!bResult)
		{
			// 轮询结束
			pExecuteSinkInfo->nEndFlag = 0;

			return;
		}
	}

	// 发送执行消息
	if(pExecuteSinkInfo->pSink != NULL)
	{
		try
		{
			pExecuteSinkInfo->pSink->OnExecute(dwMsgID, pGameMsgHead, pszMsg, nLen);
		}
		catch (...)
		{
			Error("发送执行消息非法,消息码 = " << dwMsgID << ", 描述 = " << pExecuteSinkInfo->szDesc << endl);

			return;					
		}		
	}

	// 轮询结束
	pExecuteSinkInfo->nEndFlag = 0;
}

void CMessageSlot::ResizeVector(void)
{
	m_nVectorOpenSize += 20;
	if(m_nVectorOpenSize >= MSG_ACTION_MAXID)
	{
		m_nVectorOpenSize = MSG_ACTION_MAXID;
	}

	// 设置投票订阅sink vector大小
	m_vectorVoteSink.resize(m_nVectorOpenSize);

	// 设置否决订阅sink vector大小
	m_vectorExecuteSink.resize(m_nVectorOpenSize);
}



//CPerson.h

class CPerson
{
public:
	virtual bool				Subscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink, LPCSTR pszDesc);

	virtual bool				UnSubscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink);

	virtual bool				Subscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink, LPCSTR pszDesc);

	virtual bool				UnSubscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink);

	virtual void				OnMessage(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen);
private:
		// 信号槽
	CMessageSlot				m_MessageSlot;
};

//CPerson.cpp

bool CPerson::Create(void)
{
	// 信号槽
	m_MessageSlot.Init(MSG_ACTION_MAXID);
}

void CPerson::OnMessage(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen)
{
	// 转到消息槽中
	m_MessageSlot.Fire(dwMsgID, pGameMsgHead, pszMsg, nLen);
}

bool CPerson::Subscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink, LPCSTR pszDesc)
{
	return m_MessageSlot.Subscibe(dwMsgID, pVoteSink, pszDesc);
}

bool CPerson::UnSubscibe(DWORD dwMsgID, IMessageVoteSink * pVoteSink)
{
	return m_MessageSlot.UnSubscibe(dwMsgID, pVoteSink);
}

bool CPerson::Subscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink, LPCSTR pszDesc)
{
	return m_MessageSlot.Subscibe(dwMsgID, pExecuteSink, pszDesc);
}

bool CPerson::UnSubscibe(DWORD dwMsgID, IMessageExecuteSink * pExecuteSink)
{
	return m_MessageSlot.UnSubscibe(dwMsgID, pExecuteSink);
}

//CPersonMovePart.h
class CPersonMovePart : public IMessageExecuteSink
{
public:
	IMessageExecuteSink

	virtual void				OnExecute(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen);
};


//CPersonMovePart.cpp

bool CPersonMovePart::Create(IEntity * pMaster, LPCSTR pszData, int nLen, bool bDBImport)
{
	// 订阅移动的消息
	if(!m_pMaster->Subscibe(MSG_ACTION_MOVE,
		static_cast<IMessageExecuteSink *>(this),
		"CPersonMovePart::Create"))
	{
		return false;
	}

	return true;
}

void CPersonMovePart::OnExecute(DWORD dwMsgID, SGameMsgHead * pGameMsgHead, LPCSTR pszMsg, int nLen)
{
	switch(dwMsgID)
	{
	case MSG_ACTION_MOVE:
		{

		}
		break;
	default:
		break;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值