1 #ifndef MSP_GAME_EVENTBUS_H_
2 #define MSP_GAME_EVENTBUS_H_
12 struct EventDispatcher
16 EventObserver *observer;
17 std::function<void(const T &)> callback;
20 std::vector<Handler> handlers;
22 void add_observer(EventObserver *obs, std::function<void(const T &)> &&cb)
23 { handlers.emplace_back(obs, std::move(cb)); }
25 void remove_observer(EventObserver *obs)
26 { std::erase_if(handlers, [obs](const Handler &h){ return h.observer==obs; }); }
28 void dispatch(const T &) const;
35 using DeleteFunc = void(void *);
36 using RemoveFunc = void(void *, EventObserver &);
40 void *dispatcher = nullptr;
41 DeleteFunc *deleter = nullptr;
42 RemoveFunc *remover = nullptr;
45 std::vector<Dispatcher> dispatchers;
47 static unsigned get_next_id();
51 static unsigned get_event_id();
55 EventDispatcher<T> &get_emitter();
59 void add_observer(EventObserver &obs, std::function<void(const T &)> cb)
60 { get_emitter<T>().add_observer(&obs, std::move(cb)); }
62 void replace_observer(EventObserver &, EventObserver &);
63 void remove_observer(EventObserver &);
66 void dispatch(const T &) const;
71 void EventDispatcher<T>::dispatch(const T &event) const
73 for(const Handler &h: handlers)
79 inline unsigned EventBus::get_event_id()
81 static unsigned id = get_next_id();
86 inline EventDispatcher<T> &EventBus::get_emitter()
88 unsigned id = get_event_id<T>();
89 if(dispatchers.size()<=id)
90 dispatchers.resize(id+1);
92 Dispatcher &event = dispatchers[id];
95 event.dispatcher = new EventDispatcher<T>;
96 event.deleter = [](void *p){ delete static_cast<EventDispatcher<T> *>(p); };
97 event.remover = [](void *p, EventObserver &o){ static_cast<EventDispatcher<T> *>(p)->remove_observer(&o); };
100 return *static_cast<EventDispatcher<T> *>(event.dispatcher);
104 inline void EventBus::dispatch(const T &event) const
106 unsigned id = get_event_id<T>();
107 if(id<dispatchers.size() && dispatchers[id].dispatcher)
108 static_cast<EventDispatcher<T> *>(dispatchers[id].dispatcher)->dispatch(event);
111 } // namespace Msp::Game