I am working on an event manager where events are represented by a key out of a string and an integer. That means that an event is not represented by a class or object. This way components can communicate through events but stay independent. It is an important guideline for the event manager that events don’t need to be registered but everyone can just listen to them or fire them.
(The integer part of the event key is for grouping phases of contentual the same event. E.g. a grenade triggers the events for throwing, flying, landing, exploding. They should be represented as “Grenade” 0, “Grenade” 1, … “Grenade” 4.)
Optionally events can contain a void pointer to send data referring the event. That could be the velocity of a crash, the id of the killed player.
Every component contains a pointer to the event namager named Event. I want to let them register methods or delegates to events.
// 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){ ... });
Firing events would ideally work similar.
Event.Fire("eventname", 0);
Event.Fire("eventname", 0, Data);
// fires events "eventname" 0, "eventname" 1, ... "eventname" 5
Event.FireRange("eventname", 0, 5);
The event manager holds a list of the events. That means the event key and a vector of all registered functions.
typedef unordered_map<pair<string, int>, vector<function>> ListEvent;
ListEvent List;
The vector stores all functions registered to a specific event. I tried using function pointers, member function pointers and std::functions. But nothing worked the way I wanted. Here are some of my questions related to this event manager: 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.
It is important for a listening function to have access to the member of it’s class. And I would like to register lambda functions in one line of code.
Do you have any idea or technique to approach coding such an event manager?
I tried to present my problem in a general manner but if you need additional explanation or code please feel free to comment.
Here is quick working sketch:
Conceptually it roughly does what you need but you should think of ownership policy here. Check my question above.
EDIT: if you say that ownership is not an issue then this may work: