BWAPI
SPAR/AIModule/SparAIModule/Utils/Event.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines