在公告板风格中,通过移除所有与应用相关的语义,仅使用2个通用操作(发布事件与订阅事件),联结所有实体的公告板变得更加通用
定义事件管理器
class CEventManager
{
public:
typedef bool(*Fn)(void*);
void subscribe(int event, Fn handler);
void unsubscribe(int event, Fn handler);
void unsubscribe(int event);
void publish(int event, void* param);
private:
map<int, list<Fn>> m_EventMap;
};
订阅事件
根据事件类型,注册事件处理器到处理器列表
void CEventManager::subscribe(int event, Fn handler)
{
if (m_EventMap.find(event) == m_EventMap.end())
{
list<Fn> listHandler;
m_EventMap[event] = listHandler;
}
auto* pListHandler = &m_EventMap[event];
if (std::find(pListHandler->begin(), pListHandler->end(), handler) == pListHandler->end())
pListHandler->push_back(handler);
}
取消订阅事件
获取一个事件类型,从处理器列表删除handler
void CEventManager::unsubscribe(int event, Fn handler)
{
if (m_EventMap.find(event) == m_EventMap.end())
{
return;
}
auto* pListHandler = &m_EventMap[event];
for (auto it = pListHandler->begin(); it != pListHandler->end();)
{
if (*it == handler)
{
it = pListHandler->erase(it);
}
else
{
it++;
}
}
}
发布事件
根据事件类型,调用所有注册为该事件类型的处理器
void CEventManager::publish(int event, void* param)
{
if (m_EventMap.find(event) != m_EventMap.end())
{
auto* pListHandler = &m_EventMap[event];
for (auto it = pListHandler->begin(); it != pListHandler->end(); it++)
{
(*it)(param);
}
}
}