• 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++

  • 相关阅读:
    java(事务和批处理)
    Dockerfile - ARG 指令详解
    机器学习常识:初学者应该知道的10 大机器学习算法
    Spring Boot(六十八):SpringBoot 整合Apache tika 实现文档内容解析
    职场必备的30套报表模板,满足95%的报表需求,一键套用无需代码
    timm模型无法联网下载采用本地读取
    Android12之报错 error: BUILD_COPY_HEADERS is obsolete(一百六十七)
    一文解决动态规划~详解
    像散 zemax示例(基本概念、子午面弧矢面)
    内存泄漏,内存溢出,抽象类和接口,netstat、ping、ifconfig的区别
  • 原文地址:https://blog.csdn.net/qq_33724710/article/details/125529929