Программирование менеджера событий на основе строк в переполнении стека

Я работаю над менеджером событий, где события представлены ключом из строки и целым числом. Это означает, что событие не представлено классом или объектом. Таким образом, компоненты могут взаимодействовать через события, но остаются независимыми. Для менеджера событий важно отметить, что события не нужно регистрировать, но каждый может их просто прослушать или запустить.

(Целочисленная часть ключа события предназначена для группировки фаз одного и того же события. Например, граната запускает события для метания, полета, приземления, взрыва. Они должны быть представлены как «Граната» 0, «Граната» 1, .. «Граната» 4.)

При желании события могут содержать указатель void для отправки данных, ссылающихся на событие. Это может быть скорость падения, идентификатор убитого игрока.

Каждый компонент содержит указатель на имя события с именем 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, Сохранить указатели функций на любую функцию-член, Проверьте, унаследован ли тип объекта от определенного класса.

Для функции прослушивания важно иметь доступ к члену своего класса. И я хотел бы зарегистрировать лямбда-функции в одной строке кода.

У вас есть идея или методика, подходящая для кодирования такого менеджера событий?

Я попытался изложить свою проблему в общих чертах, но если вам нужно дополнительное объяснение или код, пожалуйста, не стесняйтесь комментировать.

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) {...}
2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector