BWAPI
|
00001 #pragma once 00002 #include "../Utils/ReferenceCounted.h" 00003 #include "Utils/Component.h" 00004 #include "Utils/EventHandler.h" 00005 #include "Utils/Event.h" 00006 #include "Utils/Utils.h" 00007 #include "Utils/GroupBase.h" 00008 #include "SparAIContainer.h" 00009 #include "UnitManager.h" 00010 #include <BWAPI.h> 00011 #include <boost/iterator/transform_iterator.hpp> 00012 #include <utility> 00013 #include <hash_set> 00014 #include <set> 00015 00022 class PersistentUnitGroup : public ReferenceCounted, public Component, public GroupBase<PersistentUnitGroup> 00023 { 00024 protected: 00025 class UnitWrapper; 00026 //typedef std::set<UnitWrapper> UnitWrapperSet; 00027 typedef stdext::hash_set<UnitWrapper, UnitWrapperBaseHashCompare> UnitWrapperSet; 00031 class UnitWrapper : public UnitWrapperBase 00032 { 00033 public: 00034 UnitWrapper(BWAPI::Unit* unit) 00035 : UnitWrapperBase(unit) {} 00036 protected: 00037 friend class PersistentUnitGroup; 00041 mutable UnitManager::OnIndividualUnitDestroy::SubscriberID m_unitDestroyID; 00045 UnitWrapperSet::const_iterator m_unitPosInSet; 00046 }; 00047 public: 00048 //typedef boost::transform_iterator<extract_unit, UnitWrapperSet::const_iterator> const_iterator; 00049 //typedef boost::transform_iterator<extract_unit, UnitWrapperSet::iterator> iterator; 00050 typedef UnitWrapperSet::const_iterator const_iterator; 00051 typedef UnitWrapperSet::iterator iterator; 00052 00057 PersistentUnitGroup(const std::string& name) 00058 : m_name(name) 00059 , m_unitDestroyEventHandler(*this) 00060 { 00061 } 00062 00070 template <class iterator> 00071 PersistentUnitGroup(const std::string& name, iterator begin, iterator end) 00072 : m_name(name) 00073 , m_unitDestroyEventHandler(*this) 00074 { 00075 for (; begin != end; ++begin) 00076 insert(*begin); 00077 } 00078 00082 ~PersistentUnitGroup(); 00083 00090 bool insert(BWAPI::Unit* unit) 00091 { 00092 std::pair<UnitWrapperSet::iterator, bool> p = m_group.insert(UnitWrapper(unit)); 00093 if (p.second) 00094 { 00095 p.first->m_unitPosInSet = p.first; 00096 UnitManager::OnIndividualUnitDestroy::SubscriberID unitManagerID = 00097 Spar->getUnitManager().subscribeIndividualUnitDestroy(unit, &m_unitDestroyEventHandler, &(p.first->m_unitPosInSet)); 00098 p.first->m_unitDestroyID = unitManagerID; 00099 00100 m_unitAddedEvent.raise(unit); 00101 } 00102 return p.second; 00103 } 00104 00105 bool insert(const_iterator hint, BWAPI::Unit* unit) 00106 { 00107 UnitWrapperSet::iterator it = m_group.insert(hint, UnitWrapper(unit)); 00108 00109 it->m_unitPosInSet = it; 00110 UnitManager::OnIndividualUnitDestroy::SubscriberID unitManagerID = 00111 Spar->getUnitManager().subscribeIndividualUnitDestroy(unit, &m_unitDestroyEventHandler, &(it->m_unitPosInSet)); 00112 it->m_unitDestroyID = unitManagerID; 00113 00114 m_unitAddedEvent.raise(unit); 00115 00116 return true; 00117 } 00118 00126 template <class iterator> 00127 size_t insert(iterator begin, iterator end) 00128 { 00129 size_t nb = 0; 00130 for (; begin != end; ++begin) 00131 { 00132 if(insert(*begin)) 00133 ++nb; 00134 } 00135 return nb; 00136 } 00137 00143 bool remove(BWAPI::Unit* unit) 00144 { 00145 const_iterator it = m_group.find(UnitWrapper(unit)); 00146 const bool exists = (it != m_group.end()); 00147 if (exists) 00148 { 00149 remove(it); 00150 } 00151 return exists; 00152 } 00153 00158 void remove(const_iterator pos) 00159 { 00160 BWAPI::Unit* unit = (*pos).getUnit(); 00161 Spar->getUnitManager().unsubscribeIndividualUnitDestroy(unit, (*pos).m_unitDestroyID); 00162 m_group.erase(pos); 00163 m_unitRemovedEvent.raise(unit); 00164 00165 if(m_group.empty()) 00166 { 00167 m_emptyEvent.raise(); 00168 } 00169 } 00170 00174 void clear() 00175 { 00176 iterator it = begin(); 00177 iterator nextIt; 00178 while(it != end()) 00179 { 00180 nextIt = it; 00181 ++nextIt; 00182 remove(it); 00183 it = nextIt; 00184 } 00185 } 00186 00187 00188 00194 bool contains(BWAPI::Unit* unit) const 00195 { 00196 return m_group.find(unit) != m_group.end(); 00197 } 00198 00199 const_iterator find(BWAPI::Unit* unit) const 00200 { 00201 return m_group.find(unit); 00202 } 00203 00207 const_iterator begin() const 00208 { 00209 //return boost::transform_iterator<extract_unit, UnitWrapperSet::const_iterator>(m_group.begin()); 00210 return m_group.begin(); 00211 } 00212 00216 const_iterator end() const 00217 { 00218 //return boost::transform_iterator<extract_unit, UnitWrapperSet::const_iterator>(m_group.end()); 00219 return m_group.end(); 00220 } 00221 00225 iterator begin() 00226 { 00227 //return boost::transform_iterator<extract_unit, UnitWrapperSet::iterator>(m_group.begin()); 00228 return m_group.begin(); 00229 } 00230 00234 iterator end() 00235 { 00236 //return boost::transform_iterator<extract_unit, UnitWrapperSet::iterator>(m_group.end()); 00237 return m_group.end(); 00238 } 00239 00243 size_t size() const 00244 { 00245 return m_group.size(); 00246 } 00247 00251 bool empty() const 00252 { 00253 return m_group.size() == 0; 00254 } 00255 00260 void onUnitDestroy(void* data) 00261 { 00262 UnitWrapperSet::iterator* id = reinterpret_cast<UnitWrapperSet::iterator*>(data); 00263 remove(*id); 00264 } 00265 00266 const std::string& getName() const { return m_name; } 00267 virtual std::string toString() const { return m_name; } 00268 00269 friend std::ostream& operator<<(std::ostream& out, const PersistentUnitGroup& group); 00270 00274 DECLARE_EVENT(OnEmpty); 00275 OnEmpty& getEmptyEvent() const { return m_emptyEvent; } 00276 00281 DECLARE_EVENT(OnGroupDestroyed); 00282 OnGroupDestroyed& getGroupDestroyedEvent() const { return m_groupDestroyedEvent; } 00283 00287 DECLARE_EVENT1(OnUnitAdded, BWAPI::Unit*); 00288 OnUnitAdded& getUnitAddedEvent() const { return m_unitAddedEvent; } 00289 00294 DECLARE_EVENT1(OnUnitRemoved, BWAPI::Unit*); 00295 OnUnitRemoved& getUnitRemovedEvent() const { return m_unitRemovedEvent; } 00296 00300 static const PersistentUnitGroup EmptyGroup; 00301 00302 protected: 00303 PersistentUnitGroup(const PersistentUnitGroup& other); 00304 PersistentUnitGroup& operator=(const PersistentUnitGroup& other) const; 00305 00306 EVENT(OnEmpty) m_emptyEvent; 00307 00308 EVENT(OnGroupDestroyed) m_groupDestroyedEvent; 00309 00310 EVENT(OnUnitAdded) m_unitAddedEvent; 00311 00312 EVENT(OnUnitRemoved) m_unitRemovedEvent; 00313 00314 const std::string m_name; 00315 00316 EVENT_HANDLER(PersistentUnitGroup, onUnitDestroy) m_unitDestroyEventHandler; 00317 00318 UnitWrapperSet m_group; 00319 00320 private: 00321 PersistentUnitGroup(); 00322 };