BWAPI
|
00001 #pragma once 00002 #include "SafeList.h" 00003 #include "EventHandler.h" 00004 00009 struct EventBase 00010 { 00011 virtual ~EventBase() {} 00012 00013 #ifdef _DEBUG_COMPONENT 00014 virtual void onOwnerDeleted(Component* owner) = 0; 00015 #endif 00016 }; 00017 00022 template <class Arguments = boost::tuple<>> 00023 class Event : public EventBase 00024 { 00025 public: 00029 typedef EventHandlerT<Arguments> EventHandlerType; 00033 class SubscriberID 00034 { 00035 public: 00036 SubscriberID() 00037 : m_isValid(false) 00038 {} 00039 SubscriberID(typename SafeList<std::pair<EventHandlerType*, void*>>::iterator id) 00040 : m_id(id) 00041 , m_isValid(true) 00042 {} 00043 bool isValid() const 00044 { 00045 return m_isValid; 00046 } 00047 protected: 00048 friend class Event; 00052 bool m_isValid; 00056 typename SafeList<std::pair<EventHandlerType*, void*>>::iterator m_id; 00057 }; 00058 00059 #ifndef _DEBUG_COMPONENT 00060 virtual ~Event() {} 00061 #else 00062 virtual void onOwnerDeleted(Component* owner) 00063 { 00064 struct DeleteIfInvalidOwner 00065 { 00066 DeleteIfInvalidOwner(const Component* owner) 00067 : m_owner(owner) 00068 { 00069 } 00070 SafeListBase::FunctionReturn operator()(const std::pair<EventHandlerType*, void*>& p) const 00071 { 00072 bool shouldDelete = (&p.first->m_owner == m_owner); 00073 return SafeListBase::FunctionReturn(shouldDelete, false); 00074 } 00075 private: 00076 const Component* const m_owner; 00077 }; 00078 00079 m_subscribers.for_each(DeleteIfInvalidOwner(owner)); 00080 } 00081 00082 virtual ~Event() 00083 { 00084 struct Notify 00085 { 00086 Notify(Event* ev) 00087 : m_event(ev) 00088 {} 00089 SafeListBase::ConstFunctionReturn operator()(const std::pair<EventHandlerType*, void*>& p) const 00090 { 00091 p.first->m_owner.onEventDeleted(p.first, m_event); 00092 return SafeListBase::ConstFunctionReturn(); 00093 } 00094 private: 00095 Event* const m_event; 00096 }; 00097 00098 m_subscribers.for_each(Notify(this)); 00099 } 00100 #endif 00101 00108 SubscriberID subscribe(EventHandlerType* eventHandler, void* data) 00109 { 00110 #ifdef _DEBUG_COMPONENT 00111 eventHandler->m_owner.onEventSubscribe(eventHandler, this); 00112 #endif 00113 return SubscriberID(m_subscribers.add(std::make_pair(eventHandler, data))); 00114 } 00115 00120 void unsubscribe(SubscriberID& id) 00121 { 00122 if (id.m_isValid) 00123 { 00124 #ifdef _DEBUG_COMPONENT 00125 std::pair<EventHandlerType*, void*>& pair = *id.m_id; 00126 pair.first->m_owner.onEventUnsubscribe(pair.first, this); 00127 #endif 00128 m_subscribers.erase(id.m_id); 00129 id.m_isValid = false; 00130 } 00131 } 00132 00137 void internalRaise(Arguments& arguments) 00138 { 00139 struct RaiseOnEvent 00140 { 00141 RaiseOnEvent(Arguments& args) : m_args(args) { } 00142 typename SafeList<std::pair<EventHandlerType*, void*>>::FunctionReturn 00143 operator()(std::pair<EventHandlerType*, void*>& pair) 00144 { 00145 pair.first->onEvent(pair.second, m_args); 00146 return typename SafeList<std::pair<EventHandlerType*, void*>>::FunctionReturn(); 00147 } 00148 private: 00149 Arguments& m_args; 00150 }; 00151 00152 m_subscribers.for_each(RaiseOnEvent(arguments)); 00153 } 00154 00155 protected: 00159 SafeList<std::pair<EventHandlerType*, void*>> m_subscribers; 00160 }; 00161 00162 class Event0 : public Event<boost::tuple<>> 00163 { 00164 public: 00165 void raise() 00166 { 00167 internalRaise(boost::make_tuple()); 00168 } 00169 }; 00170 00171 template <class T1> 00172 class Event1 : public Event<boost::tuple<T1>> 00173 { 00174 public: 00175 void raise(T1 t1) 00176 { 00177 internalRaise(boost::make_tuple(t1)); 00178 } 00179 }; 00180 00181 template <class T1, class T2> 00182 class Event2 : public Event<boost::tuple<T1,T2>> 00183 { 00184 public: 00185 void raise(T1 t1, T2 t2) 00186 { 00187 internalRaise(boost::make_tuple(t1,t2)); 00188 } 00189 }; 00190 00191 template <class T1, class T2, class T3> 00192 class Event3 : public Event<boost::tuple<T1,T2,T3>> 00193 { 00194 public: 00195 void raise(T1 t1, T2 t2, T3 t3) 00196 { 00197 internalRaise(boost::make_tuple(t1,t2,t3)); 00198 } 00199 }; 00200 00201 template <class T1, class T2, class T3, class T4> 00202 class Event4 : public Event<boost::tuple<T1,T2,T3,T4>> 00203 { 00204 public: 00205 void raise(T1 t1, T2 t2, T3 t3, T4 t4) 00206 { 00207 internalRaise(boost::make_tuple(t1,t2,t3,t4)); 00208 } 00209 }; 00210 00211 template <class T1, class T2, class T3, class T4, class T5> 00212 class Event5 : public Event<boost::tuple<T1,T2,T3,T4,T5>> 00213 { 00214 public: 00215 void raise(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) 00216 { 00217 internalRaise(boost::make_tuple(t1,t2,t3,t4,t5)); 00218 } 00219 }; 00220 00221 #define DECLARE_EVENT(Name) \ 00222 class Name : public Event0 \ 00223 { \ 00224 public: \ 00225 virtual ~Name() {} \ 00226 }; 00227 00228 #define DECLARE_EVENT1(Name, T1) \ 00229 class Name : public Event1<T1> \ 00230 { \ 00231 public: \ 00232 virtual ~Name() {} \ 00233 }; 00234 00235 #define DECLARE_EVENT2(Name, T1, T2) \ 00236 class Name : public Event2<T1,T2> \ 00237 { \ 00238 public: \ 00239 virtual ~Name() {} \ 00240 }; 00241 00242 #define DECLARE_EVENT3(Name, T1, T2, T3) \ 00243 class Name : public Event3<T1,T2,T3> \ 00244 { \ 00245 public: \ 00246 virtual ~Name() {} \ 00247 }; 00248 00249 #define DECLARE_EVENT4(Name, T1, T2, T3, T4) \ 00250 class Name : public Event4<T1,T2,T3,T4> \ 00251 { \ 00252 public: \ 00253 virtual ~Name() {} \ 00254 }; 00255 00256 #define DECLARE_EVENT5(Name, T1, T2, T3, T4, T5) \ 00257 class Name : public Event5<T1,T2,T3,T4,T5> \ 00258 { \ 00259 public: \ 00260 virtual ~Name() {} \ 00261 }; 00262 00263 #define EVENT(Name) \ 00264 mutable Name