我正在开发一个事件管理器,其中事件由字符串和整数中的键表示。这意味着事件不由类或对象表示。这样,组件可以通过事件进行通信,但保持独立。对于事件管理者来说,这是一个重要的指导方针:事件不需要注册,但每个人都可以监听它们或触发它们。
(事件键的整数部分用于对同一事件的内容进行分组。例如,手榴弹会触发 throw 、飞行、着陆、爆炸等事件。它们应表示为“Grenade”0、“Grenade”1 ,...“手榴弹”4.)
事件可以包含一个空指针来发送引用该事件的数据(可选)。这可能是崩溃的速度、被杀玩家的 ID。
每个组件都包含一个指向名为Event
的事件命名器的指针。我想让他们注册方法或事件委托(delegate)。
// ideally registering for an event would look like that
Event.Listen("eventname", 0, this->Method);
Event.Listen("eventname", 0, [](){ ... });
// receiving data is optional
Event.Listen("eventname", 0, [](void* Data){ ... });
理想情况下,触发事件的工作方式类似。
Event.Fire("eventname", 0);
Event.Fire("eventname", 0, Data);
// fires events "eventname" 0, "eventname" 1, ... "eventname" 5
Event.FireRange("eventname", 0, 5);
事件管理器保存事件列表。这意味着事件键和所有注册函数的 vector 。
typedef unordered_map<pair<string, int>, vector<function>> ListEvent;
ListEvent List;
vector 存储注册到特定事件的所有函数。我尝试使用函数指针、成员函数指针和 std::function 。但一切都没有按照我想要的方式进行。以下是我与此事件管理器相关的一些问题:Check if two std::function are Equal , Store Function Pointers to any Member Function , Check if the Type of an Object is inherited from a specific Class .
对于监听函数来说,访问其类的成员非常重要。我想在一行代码中注册 lambda 函数。
您有任何想法或技术来编写这样的事件管理器吗?
我尝试以一般方式提出我的问题,但如果您需要其他解释或代码,请随时发表评论。
最佳答案
这是快速工作草图:
#include <vector>
#include <functional>
#include <iostream>
typedef std::function<void(int param)> callback;
struct Event {
std::vector<callback> subs;//criptions
void subscribe(callback cb) { subs.push_back(cb); }
void fire(int param = 0) { for(callback& cb : subs) cb(param); }
};
void some_free_func(int param) { std::cout << "some_free_func got signal" << std::endl; }
int main(int argc, char* argv[])
{
Event evt0;
evt0.subscribe(some_free_func);
evt0.subscribe([](int p) { std::cout << "some_lambda got signal" << std::endl; } );
evt0.fire();
return 0;
}
从概念上讲,它大致可以满足您的需要,但您应该在这里考虑所有权政策。检查我上面的问题。
编辑:如果您说所有权不是问题,那么这可能有效:
void my_object::firstCry() {
evt0.subscribe([=](int p) { this->got_signal(p); }); // inst/method thunk
}
void my_object::got_signal(int param) {...}
关于c++ - 用 C++ 编写基于字符串的事件管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12990707/