BWAPI
|
00001 #pragma once 00002 #ifdef _DEBUG_COMPONENT 00003 #include "Logger.h" 00004 #include "EventHandler.h" 00005 #include "Event.h" 00006 #include "Task.h" 00007 #include <set> 00008 #include <BWAPI.h> 00009 #endif 00010 00016 class Component 00017 { 00018 public: 00019 Component() {} 00020 00021 #ifndef _DEBUG_COMPONENT 00022 00023 virtual ~Component() {} 00024 00025 #else 00026 00027 Component(const Component&) 00028 : m_pendingSubscriptions() 00029 , m_pendingTasks() 00030 {} 00031 00035 struct Subscription 00036 { 00037 Subscription(const EventHandlerBase* eventHandler, EventBase* ev) 00038 : m_eventHandler(eventHandler) 00039 , m_event(ev) 00040 , m_eventHandlerTypeInfo(typeid(*eventHandler)) 00041 , m_eventTypeInfo(typeid(*ev)) 00042 {} 00043 const EventHandlerBase* m_eventHandler; 00044 EventBase* m_event; 00045 const type_info& m_eventHandlerTypeInfo; 00046 const type_info& m_eventTypeInfo; 00047 00048 friend bool operator< (const Subscription& subscription1, const Subscription& subscription2) 00049 { 00050 if (subscription1.m_eventHandler < subscription2.m_eventHandler) 00051 return true; 00052 else if (subscription1.m_eventHandler == subscription2.m_eventHandler) 00053 return subscription1.m_event < subscription2.m_event; 00054 else 00055 return false; 00056 } 00057 }; 00058 00062 struct Task 00063 { 00064 Task(const RunnableTask* task) 00065 : m_task(task) 00066 //, m_taskTypeName(typeid(*task).name()) 00067 {} 00068 const RunnableTask* const m_task; 00069 //const char* const m_taskTypeName; 00070 00071 friend bool operator< (const Task& task1, const Task& task2) 00072 { 00073 return task1.m_task < task2.m_task; 00074 } 00075 }; 00076 00081 virtual ~Component() 00082 { 00083 verifyPendingSubscriptions("ERROR Component::~Component(): Make sure to unsubscribe EventHandler \"%s\" from event \"%s\" before its owner is deleted."); 00084 verifyPendingTasks("ERROR Component::~Component(): Make sure to deactivate task \"%s\" before its owner is deleted."); 00085 00086 for (std::multiset<Subscription>::const_iterator it = m_pendingSubscriptions.begin(); it != m_pendingSubscriptions.end(); ++it) 00087 { 00088 it->m_event->onOwnerDeleted(this); 00089 } 00090 } 00094 void verifyPendingSubscriptions(const char* error) const 00095 { 00096 for (std::multiset<Subscription>::const_iterator it = m_pendingSubscriptions.begin(); it != m_pendingSubscriptions.end(); ++it) 00097 { 00098 SPAR_LOG(LogTypes::GENERAL_ERROR, error, 00099 it->m_eventHandlerTypeInfo.name(), it->m_eventTypeInfo.name()); 00100 } 00101 } 00105 void verifyPendingTasks(const char* error) const 00106 { 00107 for (std::set<Task>::const_iterator it = m_pendingTasks.begin(); it != m_pendingTasks.end(); ++it) 00108 { 00109 SPAR_LOG(LogTypes::GENERAL_ERROR, error, 00110 typeid(*it->m_task).name()); 00111 } 00112 // Does not work since tasks are removed from the owner upon destruction but stay in the scheduler 00113 // (this was done to keep the same behavior in both debug and release). 00114 //if (m_pendingTasks.empty()) 00115 //{ 00116 // assert(!ownsAtLeastOneActiveTask()); 00117 //} 00118 } 00124 void onEventSubscribe(const EventHandlerBase* eventHandler, EventBase* ev) const 00125 { 00126 m_pendingSubscriptions.insert(Subscription(eventHandler, ev)); 00127 } 00133 void onEventUnsubscribe(const EventHandlerBase* eventHandler, EventBase* ev) const 00134 { 00135 std::multiset<Subscription>::iterator it = m_pendingSubscriptions.find(Subscription(eventHandler, ev)); 00136 if (it == m_pendingSubscriptions.end()) 00137 { 00138 SPAR_LOG(LogTypes::GENERAL_ERROR, "ERROR Component::onEventUnsubscribe(): EventHandler \"%\" has not yet subscribed to event \"%s\"", 00139 typeid(*eventHandler).name(), typeid(*ev).name()); 00140 } 00141 else 00142 { 00143 m_pendingSubscriptions.erase(it); 00144 } 00145 } 00152 void onEventDeleted(const EventHandlerBase* eventHandler, EventBase* ev) const 00153 { 00154 m_pendingSubscriptions.erase(Subscription(eventHandler, ev)); 00155 } 00160 void onActivateTask(const RunnableTask* task) const 00161 { 00162 std::pair<std::set<Task>::iterator, bool> it = m_pendingTasks.insert(Task(task)); 00163 if (!it.second) 00164 { 00165 SPAR_LOG(LogTypes::GENERAL_ERROR, "ERROR Component::onActivateTask(): Task \"%s\" has already been activated", 00166 typeid(*task).name()); 00167 } 00168 } 00173 void onDeactivateTask(const RunnableTask* task) const 00174 { 00175 size_t n = m_pendingTasks.erase(Task(task)); 00176 if (n == 0) 00177 { 00178 SPAR_LOG(LogTypes::GENERAL_ERROR, "ERROR Component::onDeactivateTask(): Task \"%s\" has not yet been activated", 00179 typeid(*task).name()); 00180 } 00181 } 00182 00183 void onDeleteTask(const RunnableTask* task) const 00184 { 00185 m_pendingTasks.erase(Task(task)); 00186 } 00187 00188 protected: 00189 bool ownsAtLeastOneActiveTask() const; 00190 00195 mutable std::multiset<Subscription> m_pendingSubscriptions; 00200 mutable std::set<Task> m_pendingTasks; 00201 #endif 00202 };