1 /*
2 OpenLieroX
3
4 event class
5
6 created on 27-05-2008 by Albert Zeyer
7 code under LGPL
8 */
9
10 #ifndef __EVENT_H__
11 #define __EVENT_H__
12
13 #include <list>
14 #include <SDL.h>
15 #include "types.h"
16 #include "Ref.h"
17 #include "SmartPointer.h"
18 #include "EventQueue.h"
19 #include "Utils.h" // for isSameType
20
21 struct EventData {
ownerEventData22 EventData(void* own = NULL) : owner(own) {}
23
24 void* owner;
25 };
26
27
28 class _Event {};
29
30 /*
31 This is an Event class, which represents a possible event.
32 It handles all the event handlers.
33
34 _Data should provide at least an owner field like EventData
35 */
36 template< typename _Data = EventData >
37 class Event : public _Event {
38 public:
39 class Handler {
40 public:
41 typedef _Data Data;
~Handler()42 virtual ~Handler() {}
43 virtual void operator()(_Data data) = 0;
44 virtual bool operator==(const Handler& hndl) = 0;
45 virtual Handler* copy() const = 0;
46 };
47
48 typedef std::list< Ref<Handler> > HandlerList;
49
50 protected:
51 class HandlerAccessor {
52 private:
53 Event* base;
54 public:
HandlerAccessor(Event * b)55 HandlerAccessor(Event* b) : base(b) {}
56 HandlerAccessor& operator=(const Ref<Handler>& h) { base->m_handlers.clear(); if(h.isSet()) base->m_handlers.push_back(h); return *this; }
57 HandlerAccessor& operator=(Null) { base->m_handlers.clear(); return *this; }
58 HandlerAccessor& operator+=(const Ref<Handler>& h) { if(h.isSet()) base->m_handlers.push_back(h); return *this; }
59 HandlerAccessor& operator-=(const Ref<Handler>& h) {
60 for(typename Event::HandlerList::iterator i = base->m_handlers.begin(); i != base->m_handlers.end(); ++i)
61 if(i->get() == h.get()) {
62 base->m_handlers.erase(i);
63 break;
64 }
65 return *this;
66 }
67
get()68 const typename Event::HandlerList& get() { return base->m_handlers; }
69 };
70
71 private:
72 friend class HandlerAccessor;
73 HandlerList m_handlers;
74
75 public:
Event()76 Event() { handler() = null; }
~Event()77 ~Event() { if (mainQueue) mainQueue->removeCustomEvents(this); }
Event(const Event & e)78 Event(const Event& e) { (*this) = e; }
79 Event& operator=(const Event& e) { m_handlers = e.m_handlers; return *this; }
handler()80 HandlerAccessor handler() { return HandlerAccessor(this); }
81
pushToMainQueue(_Data data)82 void pushToMainQueue(_Data data) { if(mainQueue) mainQueue->push(new EventThrower<_Data>(this, data)); }
83
occurred(_Data data)84 void occurred(_Data data) {
85 callHandlers(m_handlers, data);
86 }
callHandlers(HandlerList & handlers,_Data data)87 static void callHandlers(HandlerList& handlers, _Data data) {
88 for(typename HandlerList::iterator i = handlers.begin(); i != handlers.end(); ++i)
89 i->get()(data);
90 }
91 };
92
93
94 template< typename _Base, typename _Data = EventData >
95 class MemberFunction : public Event<_Data>::Handler {
96 public:
97 typedef void (_Base::*Function) (_Data data);
98 private:
99 _Base* m_obj;
100 Function m_fct;
101 public:
MemberFunction(_Base * obj,Function fct)102 MemberFunction(_Base* obj, Function fct) : m_obj(obj), m_fct(fct) {}
MemberFunction(const MemberFunction & other)103 MemberFunction(const MemberFunction& other) : m_obj(other.m_obj), m_fct(other.m_fct) {}
104
operator()105 virtual void operator()(_Data data) { (*m_obj.*m_fct)(data); }
106 virtual bool operator==(const typename Event<_Data>::Handler& hndl) {
107 const MemberFunction* hPtr = dynamic_cast<const MemberFunction*>(&hndl);
108 if(hPtr == NULL) return false;
109 return hPtr->m_obj == m_obj && hPtr->m_fct == m_fct;
110 }
copy()111 virtual typename Event<_Data>::Handler* copy() const { return new MemberFunction(m_obj, m_fct); }
112 };
113
114
115 template< typename _Data = EventData >
116 class StaticFunction : public Event<_Data>::Handler {
117 public:
118 typedef void (*Function) (_Data data);
119 private:
120 Function m_fct;
121 public:
StaticFunction(Function fct)122 StaticFunction(Function fct) : m_fct(fct) {}
StaticFunction(const StaticFunction & other)123 StaticFunction(const StaticFunction& other) : m_fct(other.m_fct) {}
124
operator()125 virtual void operator()(_Data data) { (m_fct)(data); }
126 virtual bool operator==(const typename Event<_Data>::Handler& hndl) {
127 const StaticFunction* hPtr = dynamic_cast<const StaticFunction*>(&hndl);
128 if(hPtr == NULL) return false;
129 return hPtr->m_fct == m_fct;
130 }
copy()131 virtual typename Event<_Data>::Handler* copy() const { return new StaticFunction(m_fct); }
132 };
133
134
135 template< typename _Base, typename _Data >
getEventHandler(_Base * obj,void (_Base::* fct)(_Data data))136 Ref<class Event<_Data>::Handler> getEventHandler( _Base* obj, void (_Base::*fct) (_Data data) ) {
137 return new MemberFunction<_Base,_Data>( obj, fct );
138 }
139
140 template< typename _Data >
getEventHandler(void (* fct)(_Data data))141 Ref<class Event<_Data>::Handler> getEventHandler( void (*fct) (_Data data) ) {
142 return new StaticFunction<_Data>( fct );
143 }
144
145 #endif
146