I made this simple event system:
template<typename Func, typename Args>
class Event
{
public:
static void dispatch(Args args) noexcept
{
for (auto listener : listeners)
listener.second(args);
}
static void attach(const std::string& id, Func func) noexcept
{
listeners.insert({ id, func });
}
static void dettach(const std::string& id) noexcept
{
listeners.erase(id);
}
private:
static std::unordered_map<std::string, Func> listeners;
};
template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;
What I wanted to do is to let me create any sort of event without needing to do a lot more code.
so for example in this code, if I want to add a KeyEvent
, for example, I could do this:
struct KeyArguments {
Pointint point;key;
int someInt;state;
};
class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};
And to use such code:
PointKeyArguments tempPoint{args;
args.key 1,2= };Key::A;
args.state = State::KeyUp;
KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";});"The
args.pointkey =that tempPoint;
was pressed is " << args.someIntkey;}); = 20;
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);
I also wanted to make the design reachable from anywhere in the code, this is why I used static
keyword, and this is the part that doesn't really "feel" good.
Should I really be using static in this case? Is there any cons in using such design?
I feel like using template
for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?
EDIT: The design goal was to create an event system that anyone could attach to and get notified when the specific event has happened.
For example in a game we would like to distribute an event for KeyPress
, so the event system (in the engine) would let the game programmer attach the Player::input
function to it, and if he would like, Menu::input
as well. Both of them will get notified when a KeyPress
event has happened.