如何构建一个通用的CECA(事件条件动作)系统实现?

摘要:可以在此基础上改进,监听的时候记录监听者所在线程,触发的时候把数据传递给监听者线程由监听者线程执行动作函数,这样就可以实现监听者线程内无锁执行。 AI提示词 using eca_cond = bool(*)(...); using eca_
可以在此基础上改进,监听的时候记录监听者所在线程,触发的时候把数据传递给监听者线程由监听者线程执行动作函数,这样就可以实现监听者线程内无锁执行。 AI提示词 using eca_cond = bool(*)(...); using eca_action = void(*)(...); class eca_info { public: eca_cond m_cond; eca_action m_action; void* m_handler_owner; }; using eca_infos = std::vector<eca_info>; void listen(const std::string& key, eca_action action, void* handler_owner = nullptr); void listen(const std::string& key, eca_cond cond, eca_action action, void* handler_owner = nullptr); const eca_infos& get_infos(const std::string& key); template<typename... Args> inline void trigger(const std::string& key, Args ...args) { auto infos get_infos(key); for (auto& info : infos) { if (info.m_cond && !info.m_cond(...args)) { continue; } if (info.handler_owner) { // 调用对象方法 (info.handler_owner)->info.m_action()...args); } else { // 调用全局函数 info.m_action(...args); } } } 补全上面的功能 修改后的ECA系统:eca.h #pragma once #include <cstdint> #include <string> #include <vector> #include <unordered_map> // 定义条件和动作的类型 using eca_cond = bool(*)(...); using eca_action = void(*)(...); // 事件信息结构体,包含条件、动作和事件处理者的所有者 class eca_info { public: eca_cond m_cond; // 条件函数 eca_action m_action; // 动作函数 void* m_handler_owner; // 事件处理者的所有者,用于对象方法调用 }; // 使用向量存储事件信息,以便管理多个事件 using eca_infos = std::vector<eca_info>; // 模拟的全局存储,用于保存不同键对应的事件信息列表 using eca_map = std::unordered_map<std::string, eca_infos>; inline eca_map& get_eca_map() { static eca_map eca_map_; return eca_map_; } // 监听事件,注册动作 void listen(const std::string& key, eca_action action, void* handler_owner = nullptr) { get_eca_map()[key].push_back({nullptr, action, handler_owner}); } // 监听事件,注册条件和动作 void listen(const std::string& key, eca_cond cond, eca_action action, void* handler_owner = nullptr) { get_eca_map()[key].push_back({cond, action, handler_owner}); } // 获取特定事件键对应的事件信息列表 const eca_infos& get_infos(const std::string& key) { static const eca_infos empty; // 空列表用于未找到的情况 auto map = get_eca_map(); return map.count(key) ? map[key] : empty; } // 触发事件 template<typename... Args> inline void trigger(const std::string& key, Args... args) { auto& infos = get_infos(key); // 获取对应事件的所有信息 for (auto& info : infos) { // 如果存在条件函数且条件不满足,则跳过此动作 if (info.m_cond && !info.m_cond(args...)) { continue; } // 判断是否有事件处理者的所有者(对象方法调用) if (info.m_handler_owner) { // 调用对象方法,假设动作函数是该对象的成员函数 // 注意:这里可能需要调整,以正确调用成员函数 (static_cast<void(*)(void*, Args...)>(info.m_action))(info.m_handler_owner, args...); } else { // 调用全局函数或静态函数 info.m_action(args...); } } }