]> git.tdb.fi Git - libs/game.git/blob - source/game/eventsource.h
Cosmetic tweaks
[libs/game.git] / source / game / eventsource.h
1 #ifndef MSP_GAME_EVENTSOURCE_H_
2 #define MSP_GAME_EVENTSOURCE_H_
3
4 #include "eventbus.h"
5 #include "eventobserver.h"
6
7 namespace Msp::Game {
8
9 class EventObserver;
10
11 class EventSourceBase
12 {
13 protected:
14         EventBus &bus;
15
16 public:
17         EventSourceBase(EventBus &b): bus(b) { }
18
19         virtual void remove_observer(EventObserver &) = 0;
20 };
21
22
23 template<typename... E>
24 class EventSource: public EventSourceBase, private EventDispatcher<E>...
25 {
26 public:
27         EventSource(EventBus &b): EventSourceBase(b) { }
28         ~EventSource() { (cancel_observation<E>(), ...); }
29
30         template<typename T>
31         void add_observer(EventObserver &obs, std::function<void(const T &)> cb)
32         { static_cast<EventDispatcher<T> &>(*this).add_observer(obs, std::move(cb)); }
33
34         void remove_observer(EventObserver &obs) override
35         { (static_cast<EventDispatcher<E> &>(*this).remove_observer(&obs), ...); }
36
37 private:
38         template<typename T>
39         void cancel_observation();
40
41 public:
42         template<typename T, typename... Args>
43         void emit(Args &&...) const;
44 };
45
46
47 template<typename... E>
48 template<typename T>
49 inline void EventSource<E...>::cancel_observation()
50 {
51         for(const auto &h: static_cast<EventDispatcher<T> &>(*this).handlers)
52                 h.observer->remove_source(*this);
53 }
54
55 template<typename... E>
56 template<typename T, typename... Args>
57 inline void EventSource<E...>::emit(Args &&... args) const
58 {
59         T event(std::forward<Args>(args)...);
60         static_cast<const EventDispatcher<T> &>(*this).dispatch(event);
61         bus.dispatch(event);
62 }
63
64 } // namespace Msp::Game
65
66 #endif