2

我正在开发一个事件管理器,其中事件由字符串和整数中的键表示。这意味着事件不是由类或对象表示的。这样组件可以通过事件进行通信,但保持独立。事件管理器的一个重要准则是事件不需要注册,但每个人都可以只听它们或触发它们。

(事件键的整数部分用于对内容相同事件的阶段进行分组。例如,手榴弹触发投掷、飞行、着陆、爆炸等事件。它们应表示为“手榴弹”0、“手榴弹”1、.. . “手榴弹” 4.)

可选地,事件可以包含一个空指针来发送引用该事件的数据。这可能是崩溃的速度,被杀玩家的 id。

每个组件都包含一个指向名为 的事件命名器的指针Event。我想让他们注册事件的方法或委托。

// 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);

事件管理器保存事件列表。这意味着事件键和所有已注册函数的向量。

typedef unordered_map<pair<string, int>, vector<function>> ListEvent;
ListEvent List;

向量存储注册到特定事件的所有函数。我尝试使用函数指针、成员函数指针和std::functions. 但没有什么能按我想要的方式工作。以下是我与此事件管理器相关的一些问题:检查两个 std::function 是否相等存储指向任何成员函数的函数指针检查对象的类型是否继承自特定的类

对于监听函数来说,能够访问其类的成员是很重要的。我想在一行代码中注册 lambda 函数。

你有什么想法或技术来编写这样一个事件管理器吗?

我试图以一般方式提出我的问题,但如果您需要额外的解释或代码,请随时发表评论。

4

1 回答 1

2

这是快速工作草图:

#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) {...}
于 2012-10-20T17:47:03.997 回答