BWAPI
|
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