什么是事件总线,它是发布-订阅模式的一种实现。
事件发送者将事件发布到一个总线上(抛出事件),订阅者通过在总线上注册(监听总线),达到订阅总线事件的目的。这种模型允许不同的组件或者模块之间以较低的耦合进行通信。
C++实现的简化版如下:
template <typename EventClass>
class EventBus {
public:
EventBus() = default;
~EventBus() = default;
static void Register(std::weak_ptr<EventClass> event) {
for (auto& ev : events_) {
auto ev_ptr = ev.lock();
auto event_ptr = event.lock();
if (ev_ptr == event_ptr) {
INFO("skip exist event!");
return;
}
}
events_.emplace_back(event);
}
static void Unregister(std::weak_ptr<EventClass> event) {
for (auto ev_it = events_.begin(); ev_it != events_.end(); ++ev_it) {
auto ev_ptr = ev_it->lock();
auto event_ptr = event.lock();
if (ev_ptr == event_ptr) {
events_.erase(ev_it);
return;
}
}
}
template<typename EventFun, typename... EventArgs>
static void OnEvent(EventFun fun, EventArgs&&... args) {
for (const auto& ev : events_) {
auto ptr = ev.lock();
if (!ptr) {
ERROR("skip not exist event!");
continue;
}
auto obj = ptr.get();
(obj->*fun)(args...);
}
}
private:
static std::list<std::weak_ptr<EventClass>> events_;
};
template <typename EventClass>
std::list<std::weak_ptr<EventClass>> EventBus<EventClass>::events_;
其中Register与Unregister接口供监听者向总线上注册监听,OnEvent接口供事件发送者抛出事件,测试demo如下:
class Base {
public:
virtual void print(int a) = 0;
};
class Test_One : public std::enable_shared_from_this<Test_One>,
public Base {
public:
virtual void print(int a) override {
printf("This Is Test Print: %d !\n", a);
}
};
class Test_Two : public std::enable_shared_from_this<Test_Two>,
public Base {
public:
virtual void print(int a) override {
printf("This Is Test2 Print: %d !\n", a);
}
};
int main(int argc, char *argv[])
{
auto ptr1 = std::make_shared<Test_One>();
auto weak_ptr1 = std::weak_ptr<Base>(ptr1);
auto ptr2 = std::make_shared<Test_Two>();
auto weak_ptr2 = std::weak_ptr<Base>(ptr2);
EventBus<Base>::Register(weak_ptr1);
EventBus<Base>::Register(weak_ptr2);
EventBus<Base>::OnEvent(&Base::print, 123);
INFO("unregister ptr1");
EventBus<Base>::Unregister(weak_ptr1);
EventBus<Base>::OnEvent(&Base::print, 123);
INFO("unregister ptr2");
EventBus<Base>::Unregister(weak_ptr2);
EventBus<Base>::OnEvent(&Base::print, 123);
return 0;
}
运行结果:
可以看到在总线上注册的模块,当事件发生时,能够执行该事件对应的动作,这就是简单的总线模型。
附:
源码:GitHub - Fireplusplus/event_bus: simple event bus for c++