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