• c++事件总线模型


    什么是事件总线,它是发布-订阅模式的一种实现。最近从事的工作中,就用到一种事件总线机制。

    事件发送者将事件发布到一个总线上(抛出事件),订阅者通过在总线上注册(监听总线),达到订阅总线事件的目的。这种模型允许不同的组件或者模块之间以较低的耦合进行通信。

     C++实现的简化版如下:

    1. template <typename EventClass>
    2. class EventBus {
    3. public:
    4. EventBus() = default;
    5. ~EventBus() = default;
    6. static void Register(std::weak_ptr<EventClass> event) {
    7. for (auto& ev : events_) {
    8. auto ev_ptr = ev.lock();
    9. auto event_ptr = event.lock();
    10. if (ev_ptr == event_ptr) {
    11. INFO("skip exist event!");
    12. return;
    13. }
    14. }
    15. events_.emplace_back(event);
    16. }
    17. static void Unregister(std::weak_ptr<EventClass> event) {
    18. for (auto ev_it = events_.begin(); ev_it != events_.end(); ++ev_it) {
    19. auto ev_ptr = ev_it->lock();
    20. auto event_ptr = event.lock();
    21. if (ev_ptr == event_ptr) {
    22. events_.erase(ev_it);
    23. return;
    24. }
    25. }
    26. }
    27. template<typename EventFun, typename... EventArgs>
    28. static void OnEvent(EventFun fun, EventArgs&&... args) {
    29. for (const auto& ev : events_) {
    30. auto ptr = ev.lock();
    31. if (!ptr) {
    32. ERROR("skip not exist event!");
    33. continue;
    34. }
    35. auto obj = ptr.get();
    36. (obj->*fun)(args...);
    37. }
    38. }
    39. private:
    40. static std::list<std::weak_ptr<EventClass>> events_;
    41. };
    42. template <typename EventClass>
    43. std::list<std::weak_ptr<EventClass>> EventBus<EventClass>::events_;

    其中Register与Unregister接口供监听者向总线上注册监听,OnEvent接口供事件发送者抛出事件,测试demo如下:

    1. class Base {
    2. public:
    3. virtual void print(int a) = 0;
    4. };
    5. class Test_One : public std::enable_shared_from_this<Test_One>,
    6. public Base {
    7. public:
    8. virtual void print(int a) override {
    9. printf("This Is Test Print: %d !\n", a);
    10. }
    11. };
    12. class Test_Two : public std::enable_shared_from_this<Test_Two>,
    13. public Base {
    14. public:
    15. virtual void print(int a) override {
    16. printf("This Is Test2 Print: %d !\n", a);
    17. }
    18. };
    19. int main(int argc, char *argv[])
    20. {
    21. auto ptr1 = std::make_shared<Test_One>();
    22. auto weak_ptr1 = std::weak_ptr<Base>(ptr1);
    23. auto ptr2 = std::make_shared<Test_Two>();
    24. auto weak_ptr2 = std::weak_ptr<Base>(ptr2);
    25. EventBus<Base>::Register(weak_ptr1);
    26. EventBus<Base>::Register(weak_ptr2);
    27. EventBus<Base>::OnEvent(&Base::print, 123);
    28. INFO("unregister ptr1");
    29. EventBus<Base>::Unregister(weak_ptr1);
    30. EventBus<Base>::OnEvent(&Base::print, 123);
    31. INFO("unregister ptr2");
    32. EventBus<Base>::Unregister(weak_ptr2);
    33. EventBus<Base>::OnEvent(&Base::print, 123);
    34. return 0;
    35. }

    运行结果:

    可以看到在总线上注册的模块,当事件发生时,能够执行该事件对应的动作,这就是简单的总线模型。

    附:

    源码:GitHub - Fireplusplus/event_bus: simple event bus for c++

  • 相关阅读:
    RustDay06------Exercise[81-90]
    Azure Terraform(十一)Azure DevOps Pipeline 内的动态临时变量的使用
    添加用户并配置读写权限(阁瑞钛伦特软件-九耶实训)
    [运维|数据库] mysql的charset与PostgreSQL的encoding
    计算机网络(HTTPS)
    三极管高温工作下额定功率计算
    独立站运营的核心——推广分享
    html网页制作期末大作业成品:基于HTML+CSS+JavaScript简洁汽车网站(7页)
    [python] Python日志记录库loguru使用指北
    1688商品详情技术贴:提升点击率和转化率的优化指南
  • 原文地址:https://blog.csdn.net/qq_33724710/article/details/125529929