在C++中实现带参数的事件总线(Event Bus)
- 作者: 刘杰
- 来源: 技术那些事
- 阅读:264
- 发布: 2025-06-21 09:47
- 最后更新: 2025-08-23 06:56
场景
在C++中,可以通过创建一个类来封装带参数的事件总线(Event Bus)。以下是一个简单的例子,展示了如何实现这个功能。
类图
%%{
init: {
'theme': 'base',
'themeVariables': {
'primaryColor': '#99ff99',
'primaryTextColor': 'black'
}
}
}%%
classDiagram
direction LR
class EventHandlerInterface {
<<interface>>
+ handle(IEvent&);
}
class TestListener {
+ handler(IEvent&);
}
class IEvent {
<<interface>>
- string name;
- T target;
+ string getName();
+ T getTarget();
}
class TestEvent {
+ getName()
+ getTarget()
}
class EventBus {
+ registerListener(const IEvent&, EventHandlerInterface*)
+ tigger(const IEvent&);
- map<string, EventHandlerInterface*> m_listeners;
}
EventBus --> EventHandlerInterface
EventBus --> IEvent
TestEvent --|> IEvent
TestListener --|> EventHandlerInterface
实现
c++
#include <iostream>
#include <functional>
#include <map>
template<typename Target>
class IEvent {
public:
IEvent(const string& name,const Target& t)
:m_name(name), m_target(t)
{}
string getName() {
return m_name;
}
Target getTarget() {
return m_target;
}
operator <(const IEvent& ev) {
return m_name < ev.m_name;
}
virtual ~IEvent() {}
private:
string m_name;
Target m_target;
}
template <>
class TestEvent<int> : public IEvent
{
TestEvent(const string& name, int t): IEvent(name, t) {}
}
class EventHandlerInterface {
public:
template<typename Target>
virtual handle(IEvent<Target>) = 0;
virtual ~EventHandlerInterface() {}
}
class TestListener : EventHandlerInterface {
public:
template<>
handle(IEvent<int> e) {
auto fd = e->getTarget();
std::string name = e->getName();
// @todo
std::cout << "listener handle:";
std::cout << "name->" << name;
std::cout << "fd->"<< fd << std::endl;
}
}
// 事件总线类
template<typename Target>
class EventBus {
public:
// 注册监听器
void registerListener(const IEvent<Target>& e, const EventHandlerInterface& listener)
{
m_listeners[e->getName()].push_back(listener);
}
void removeListener(const EventHandlerInterface& handler)
{
for (const auto& vec : m_listeners) {
for (auto it = vec.begin(); it != vec.end(); ++it) {
if (*it == handler) {
it = vec.erase(it);
--it;
}
}
}
}
// 触发事件
void trigger(const IEvent& event) {
for (const auto& listener : m_listeners[event->getName()]) {
listener(event);
}
}
private:
std::map<IEvent<Target>, std::vector<EventHandlerInterface>> m_listeners;
};
// 使用示例
int main() {
EventBus<int> bus;
// 注册监听器
TestListener listener;
TestEvent<int> e1("event1", 1);
TestEvent<int> e2("event2", 2);
bus.registerListener(e1, listener);
bus.registerListener(e2, listener);
// 触发事件
bus.trigger(e1);
bus.trigger(e2);
return 0;
}