UGDK  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
eventhandler.h
Go to the documentation of this file.
1 #ifndef UGDK_SYSTEM_EVENTHANDLER_H_
2 #define UGDK_SYSTEM_EVENTHANDLER_H_
3 
4 #include <ugdk/system/engine.h>
5 
6 #include <typeinfo>
7 #include <typeindex>
8 #include <functional>
9 #include <forward_list>
10 #include <memory>
11 #include <unordered_map>
12 #include <algorithm>
13 #include <cassert>
14 
15 namespace ugdk {
16 namespace system {
17 
18 class IListener { public: virtual ~IListener() {} };
19 
20 template <class Event>
21 class Listener : public virtual IListener {
22  public:
23  virtual void Handle(const Event& ev) = 0;
24 };
25 
26 template <class Event>
27 class FunctionListener : public Listener<Event> {
28  public:
29  template<typename Handler>
30  FunctionListener(Handler handler) : handler_(handler) {}
31 
32  void Handle(const Event& ev) override {
33  handler_(ev);
34  }
35 
36  private:
37  std::function<void (const Event&)> handler_;
38 };
39 
40 class EventHandler {
41  public:
42  EventHandler() : dispatch_as_global_(false) {}
44 
45  // Add listeners
46 
47  template<class Event, class Handler>
48  IListener* AddListener(Handler handler) {
49  return AddRawListener(typeid(Event), std::make_shared<FunctionListener<Event>>(handler));
50  }
51 
52  template<class Event>
53  IListener* AddListener(void (*handler)(const Event&)) {
54  return AddRawListener(typeid(Event), std::make_shared<FunctionListener<Event>>(handler));
55  }
56 
57  IListener* AddRawListener(const std::type_index& type, const std::shared_ptr<IListener>& listener) {
58  event_handlers_[type].push_front(listener);
59  return listener.get();
60  }
61 
68  void AddObjectListener(IListener* listener) {
69  object_listeners_.push_front(listener);
70  }
71 
72  // Remove listeners
73 
74  void RemoveListener(const std::type_index& type, IListener* listener) {
75  auto handlers = event_handlers_.find(type);
76  if(handlers == event_handlers_.end()) return;
77 
78  handlers->second.remove_if([listener](const std::shared_ptr<IListener>& val) {
79  return val.get() == listener;
80  });
81  }
82 
83  template<class Event>
84  void RemoveListener(IListener* listener) {
85  RemoveListener(typeid(Event), listener);
86  }
87 
88  void RemoveObjectListener(IListener* listener) {
89  object_listeners_.remove(listener);
90  }
91 
93  void set_dispatch_as_global(bool flag) {
94  dispatch_as_global_ = flag;
95  }
96 
98 
101  template<class Event>
102  static void RaiseGlobalEvent(const Event& ev) {
103  static bool processing_global_event = false;
104  if (processing_global_event) return;
105 
106  processing_global_event = true;
109  processing_global_event = false;
110  }
111 
112  // Raising events
113  template<class Event>
114  void RaiseEvent(const Event& ev) const {
115  if (dispatch_as_global_)
116  RaiseGlobalEvent(ev);
117 
118  auto handlers = event_handlers_.find(typeid(Event));
119  if (handlers != event_handlers_.end())
120  for (const auto& listener : handlers->second) {
121  Listener<Event>* specific_listener = dynamic_cast<Listener<Event>*>(listener.get());
122  assert(specific_listener);
123  specific_listener->Handle(ev);
124  }
125 
126  for (IListener* listener : object_listeners_) {
127  if (Listener<Event>* specific_listener = dynamic_cast<Listener<Event>*>(listener)) {
128  specific_listener->Handle(ev);
129  }
130  }
131  }
132 
133  private:
134  typedef std::forward_list< std::shared_ptr<IListener> > ListenerVector;
135 
136  std::unordered_map<std::type_index, ListenerVector> event_handlers_;
137  std::forward_list<IListener*> object_listeners_;
138  bool dispatch_as_global_;
139 };
140 
141 } // namespace system
142 } // namespace ugdk
143 
144 #endif // UGDK_SYSTEM_EVENTHANDLER_H_
virtual ~IListener()
Definition: eventhandler.h:18
IListener * AddListener(void(*handler)(const Event &))
Definition: eventhandler.h:53
void RemoveObjectListener(IListener *listener)
Definition: eventhandler.h:88
IListener * AddListener(Handler handler)
Definition: eventhandler.h:48
void RaiseEvent(const Event &ev) const
Definition: eventhandler.h:114
EventHandler & GetCurrentSceneEventHandler()
Returns the EventHandler for the current scene.
void RemoveListener(const std::type_index &type, IListener *listener)
Definition: eventhandler.h:74
void RemoveListener(IListener *listener)
Definition: eventhandler.h:84
static void RaiseGlobalEvent(const Event &ev)
Dispatches a global event.
Definition: eventhandler.h:102
Definition: animation.h:11
void Handle(const Event &ev) override
Definition: eventhandler.h:32
EventHandler()
Definition: eventhandler.h:42
Definition: eventhandler.h:40
void AddObjectListener(IListener *listener)
Definition: eventhandler.h:68
void set_dispatch_as_global(bool flag)
If true, events raised on this handler will be raised as global events.
Definition: eventhandler.h:93
Definition: eventhandler.h:21
FunctionListener(Handler handler)
Definition: eventhandler.h:30
IListener * AddRawListener(const std::type_index &type, const std::shared_ptr< IListener > &listener)
Definition: eventhandler.h:57
Definition: eventhandler.h:18
EventHandler & GlobalEventHandler()
Returns the global EventHandler.
virtual void Handle(const Event &ev)=0
~EventHandler()
Definition: eventhandler.h:43
Definition: eventhandler.h:27