BWAPI
SPAR/AIModule/SparAIModule/Utils/ProcessContainer.h
Go to the documentation of this file.
00001 #pragma once
00002 #include "Process.h"
00003 #include "SafeList.h"
00004 #include "../SparAIContainer.h"
00005 
00013 template <class ProcessType, bool ZombifyOnTerminate=true>
00014 class ProcessContainer : public EventHandler
00015 {
00016 public:
00017   ProcessContainer(const Component& owner)
00018     : EventHandler(owner)
00019     , m_process(NULL)
00020   {
00021   }
00022   ProcessContainer(const Component& owner, ProcessType* process)
00023     : EventHandler(owner)
00024     , m_process(NULL)
00025   {
00026     setProcess(process);
00027   }
00028   ~ProcessContainer()
00029   {
00030     if (m_process != NULL)
00031     {
00032       m_process->getTerminateEvent().unsubscribe(m_id);
00033       if (ZombifyOnTerminate)
00034         delete m_process;
00035     }
00036   }
00037   void setProcess(ProcessType* process)
00038   {
00039     if (m_process != process)
00040     {
00041       if (m_process != NULL)
00042       {
00043         m_process->getTerminateEvent().unsubscribe(m_id);
00044       }
00045       m_process = process;
00046       if (m_process != NULL)
00047       {
00048         if (ZombifyOnTerminate)
00049           Process::zombifyOnTerminate(m_process);
00050 
00051         m_id = m_process->getTerminateEvent().subscribe(this, m_process);
00052       }
00053     }
00054   }
00055   virtual void onEvent(void* data, boost::tuple<>&)
00056   {
00057     const ProcessType* process = reinterpret_cast<const ProcessType*>(data);
00058     if (m_process == process)
00059     {
00060       // m_process just ended
00061       m_process = NULL;
00062     }
00063   }
00064   ProcessContainer& operator=(ProcessType* process)
00065   {
00066     setProcess(process);
00067     return *this;
00068   }
00069   ProcessType* getProcess() { return m_process; }
00070   const ProcessType* getProcess() const { return m_process; }
00071   operator ProcessType*() { return m_process; }
00072   operator const ProcessType*() const { return m_process; }
00073   ProcessType* operator->() { return m_process; }
00074   const ProcessType* operator->() const { return m_process; }
00075   ProcessType& operator*() { return *m_process; }
00076   const ProcessType& operator*() const { return *m_process; }
00077 private:
00078   ProcessType* m_process;
00079   Process::OnTerminate::SubscriberID m_id;
00080 };
00081 
00089 template <class ProcessType, bool ZombifyOnTerminate=true>
00090 class ProcessContainerList : public EventHandler
00091 {
00092 private:
00093   struct ProcessWrapper
00094   {
00095     ProcessWrapper(ProcessType* process)
00096       : m_process(process)
00097     {}
00098     typename SafeList<ProcessWrapper>::iterator m_posInList;
00099     ProcessType* m_process;
00100     Process::OnTerminate::SubscriberID m_id;
00101   };
00102 
00103 public:
00104   ProcessContainerList(const Component& owner)
00105     : EventHandler(owner)
00106   {
00107   }
00108   ~ProcessContainerList()
00109   {
00110     if (ZombifyOnTerminate)
00111     {
00112       struct DeleteProcess
00113       {
00114         DeleteProcess(ProcessContainerList& list)
00115           : m_list(list)
00116         {}
00117         SafeListBase::FunctionReturn operator()(ProcessWrapper& processWrapper) const
00118         {
00119           processWrapper.m_process->getTerminateEvent().unsubscribe(processWrapper.m_id);
00120           delete processWrapper.m_process;
00121           //m_list.m_processes.erase(processWrapper.m_posInList);
00122   
00123           return SafeListBase::FunctionReturn();
00124         }
00125       private:
00126         ProcessContainerList& m_list;
00127       };
00128       m_processes.for_each(DeleteProcess(*this));
00129     }
00130   }
00131   void add(ProcessType* process)
00132   {
00133     assert(process != NULL);
00134 
00135     SafeList<ProcessWrapper>::iterator it = m_processes.add(ProcessWrapper(process));
00136     ProcessWrapper& processWrapper = *it;
00137     processWrapper.m_posInList = it;
00138     processWrapper.m_id = process->getTerminateEvent().subscribe(this, &processWrapper);
00139     if (ZombifyOnTerminate)
00140       Process::zombifyOnTerminate(process);
00141   }
00142   virtual void onEvent(void* data, boost::tuple<>&)
00143   {
00144     ProcessWrapper* processWrapper = reinterpret_cast<ProcessWrapper*>(data);
00145 #ifdef _DEBUG_COMPONENT
00146     processWrapper->m_process->getTerminateEvent().unsubscribe(processWrapper->m_id);
00147 #endif
00148     m_processes.erase(processWrapper->m_posInList);
00149   }
00150   template <class Function>
00151   Function for_each_process(Function function)
00152   {
00153     struct InnerFunction
00154     {
00155       InnerFunction(Function function)
00156         : m_function(function)
00157       {}
00158       SafeListBase::FunctionReturn operator()(ProcessWrapper& processWrapper)
00159       {
00160         return m_function(processWrapper.m_process);
00161       }
00162       SafeListBase::ConstFunctionReturn operator()(const ProcessWrapper& processWrapper)
00163       {
00164         return m_function(processWrapper.m_process);
00165       }
00166     private:
00167       Function m_function;
00168     };
00169     return m_processes.for_each(InnerFunction(function));
00170   }
00171   size_t size() const
00172   {
00173     return m_processes.size();
00174   }
00175   bool empty() const
00176   {
00177     return m_processes.empty();
00178   }
00179 private:
00180   SafeList<ProcessWrapper> m_processes;
00181 };
00182 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines