BWAPI
|
00001 #pragma once 00002 #include "StaticLocationBase.h" 00003 #include "../../../UnitManager.h" 00004 #include "../../../../Utils/Functors.hpp" 00005 #include <boost/iterator/transform_iterator.hpp> 00006 #include <boost/iterator/filter_iterator.hpp> 00007 #include <hash_map> 00008 //#include <list> 00009 00010 // Can't use boost::unordered_multimap since resizing it apparently invalidates all iterators 00011 00012 class PrimitiveLocation; 00013 class StaticLocation; 00014 00018 class PrimitiveLocationBase : public virtual StaticLocationBase 00019 { 00020 private: 00021 class BaseUnitWrapper 00022 { 00023 public: 00024 BaseUnitWrapper(UnitLocationData* unit) 00025 : m_unit(unit) 00026 {} 00027 protected: 00028 friend class PrimitiveLocation; 00029 UnitLocationData* const m_unit; 00033 UnitManager::OnIndividualUnitEvade::SubscriberID m_unitEvadeID; 00034 UnitManager::OnIndividualUnitDestroy::SubscriberID m_unitDestroyID; 00035 UnitManager::OnIndividualUnitMorph::SubscriberID m_unitMorphID; 00036 UnitManager::OnIndividualUnitRenegade::SubscriberID m_unitRenegadeID; 00037 }; 00038 template <class UnitType> 00039 class UnitWrapper; 00043 template <class UnitType> 00044 class UnitWrapper : public BaseUnitWrapper 00045 { 00046 public: 00047 UnitWrapper(UnitType* unit) 00048 : BaseUnitWrapper(unit) 00049 {} 00050 UnitType* getUnit() { return static_cast<UnitType*>(m_unit); } 00051 const UnitType* getUnit() const { return static_cast<const UnitType*>(m_unit); } 00052 00056 typename stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<UnitType>>::const_iterator m_posInContainer; 00057 }; 00058 protected: 00059 friend class PrimitiveLocation; 00060 friend class StaticLocation; 00061 00062 template <class UnitType> 00063 struct extract_unit : std::unary_function<UnitWrapper<UnitType>, UnitType*> 00064 { 00065 UnitType* operator()(UnitWrapper<UnitType>& unitWrapper) const 00066 { 00067 return unitWrapper.getUnit(); 00068 } 00069 }; 00070 template <class UnitType> 00071 struct extract_unit_const : std::unary_function<UnitWrapper<UnitType>, const UnitType*> 00072 { 00073 extract_unit_const() {} 00074 extract_unit_const(const extract_unit<UnitType>&) {} 00075 00076 const UnitType* operator()(const UnitWrapper<UnitType>& unitWrapper) const 00077 { 00078 return unitWrapper.getUnit(); 00079 } 00080 }; 00081 00082 // Should be generalized to any container (at the moment it works on maps)... but I don't feel like doing it. 00083 template <class FirstLevelIterator, class SecondLevelIterator> 00084 class multi_level_iterator : public std::iterator<std::forward_iterator_tag, 00085 typename SecondLevelIterator::value_type, 00086 std::ptrdiff_t, 00087 typename SecondLevelIterator::pointer, 00088 typename SecondLevelIterator::reference> 00089 { 00090 public: 00091 multi_level_iterator() {} 00092 multi_level_iterator(FirstLevelIterator inputIt, FirstLevelIterator endInputIt) 00093 : m_currentInputIt(inputIt) 00094 , m_endInputIt(endInputIt) 00095 { 00096 if (m_currentInputIt != m_endInputIt) 00097 { 00098 m_currentOutputIt = SecondLevelIterator(m_currentInputIt->second.begin()); 00099 findNext(); 00100 } 00101 } 00102 template <class OtherFirstLevelIterator, class OtherSecondLevelIterator> 00103 multi_level_iterator(const multi_level_iterator<OtherFirstLevelIterator, OtherSecondLevelIterator>& other) 00104 : m_currentInputIt(other.m_currentInputIt) 00105 , m_endInputIt(other.m_endInputIt) 00106 , m_currentOutputIt(other.m_currentOutputIt) 00107 { 00108 } 00109 typename SecondLevelIterator::reference operator*() const 00110 { 00111 return *m_currentOutputIt; 00112 } 00113 multi_level_iterator& operator++() 00114 { 00115 ++m_currentOutputIt; 00116 findNext(); 00117 return *this; 00118 } 00119 multi_level_iterator operator++(int) 00120 { 00121 multi_level_iterator copy(*this); 00122 ++(*this); 00123 return copy; 00124 } 00125 bool operator== (const multi_level_iterator& other) const 00126 { 00127 assert(other.m_currentInputIt == other.m_endInputIt); // other must be end() 00128 00129 return (m_currentInputIt == other.m_currentInputIt); 00130 } 00131 bool operator!= (const multi_level_iterator& other) const 00132 { 00133 assert(other.m_currentInputIt == other.m_endInputIt); // other must be end() 00134 00135 return (m_currentInputIt != other.m_currentInputIt); 00136 } 00137 multi_level_iterator& operator=(const multi_level_iterator& other) 00138 { 00139 m_endInputIt = other.m_endInputIt; 00140 m_currentInputIt = other.m_currentInputIt; 00141 m_currentOutputIt = other.m_currentOutputIt; 00142 return *this; 00143 } 00144 private: 00145 template <class OtherFirstLevelIterator, class OtherSecondLevelIterator> friend class multi_level_iterator; 00146 bool findNext() 00147 { 00148 bool found = false; 00149 if (m_currentOutputIt != SecondLevelIterator(m_currentInputIt->second.end())) 00150 { 00151 found = true; 00152 } 00153 else 00154 { 00155 while (!found && ++m_currentInputIt != m_endInputIt) 00156 { 00157 m_currentOutputIt = SecondLevelIterator(m_currentInputIt->second.begin()); 00158 if (m_currentOutputIt != SecondLevelIterator(m_currentInputIt->second.end())) 00159 found = true; 00160 } 00161 } 00162 return found; 00163 } 00164 00165 FirstLevelIterator m_endInputIt; 00166 FirstLevelIterator m_currentInputIt; 00167 SecondLevelIterator m_currentOutputIt; 00168 }; 00169 00170 struct WrapperIsBuilding 00171 { 00172 template <class UnitWrapperType> 00173 bool operator()(const UnitWrapperType& wrapper) const 00174 { 00175 return wrapper.getUnit()->getType().isBuilding(); 00176 } 00177 }; 00178 00179 typedef boost::transform_iterator<extract_pair_second<stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<OwnUnit>>::iterator::value_type>, 00180 stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<OwnUnit>>::iterator> 00181 own_unit_wrapper_iterator; 00182 typedef boost::transform_iterator<extract_unit<OwnUnit>, 00183 own_unit_wrapper_iterator> 00184 own_unit_iterator; 00185 typedef boost::transform_iterator<extract_pair_second_const<stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<OwnUnit>>::const_iterator::value_type>, 00186 stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<OwnUnit>>::const_iterator> 00187 own_unit_wrapper_const_iterator; 00188 typedef boost::transform_iterator<extract_unit_const<OwnUnit>, 00189 own_unit_wrapper_const_iterator> 00190 own_unit_const_iterator; 00191 typedef own_unit_const_iterator 00192 own_unit_type_const_iterator; 00193 typedef boost::filter_iterator<IsBuilding<OwnUnit>, own_unit_const_iterator> 00194 own_building_const_iterator; 00195 00196 typedef boost::transform_iterator<extract_pair_second<stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<EnemyUnit>>::iterator::value_type>, 00197 stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<EnemyUnit>>::iterator> 00198 enemy_unit_wrapper_iterator; 00199 typedef boost::filter_iterator<WrapperIsBuilding, enemy_unit_wrapper_iterator> 00200 enemy_building_wrapper_iterator; 00201 typedef boost::transform_iterator<extract_unit<EnemyUnit>, 00202 enemy_unit_wrapper_iterator> 00203 enemy_unit_iterator; 00204 typedef enemy_unit_iterator 00205 enemy_unit_type_iterator; 00206 typedef boost::transform_iterator<extract_unit<EnemyUnit>, enemy_building_wrapper_iterator> 00207 enemy_building_iterator; 00208 typedef boost::transform_iterator<extract_pair_second_const<stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<EnemyUnit>>::const_iterator::value_type>, 00209 stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<EnemyUnit>>::const_iterator> 00210 enemy_unit_wrapper_const_iterator; 00211 typedef boost::filter_iterator<WrapperIsBuilding, enemy_unit_wrapper_const_iterator> 00212 enemy_building_wrapper_const_iterator; 00213 typedef boost::transform_iterator<extract_unit_const<EnemyUnit>, 00214 enemy_unit_wrapper_const_iterator> 00215 enemy_unit_const_iterator; 00216 typedef enemy_unit_const_iterator 00217 enemy_unit_type_const_iterator; 00218 typedef boost::transform_iterator<extract_unit_const<EnemyUnit>, enemy_building_wrapper_const_iterator> 00219 enemy_building_const_iterator; 00220 00221 typedef boost::transform_iterator<extract_pair_second<stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<NeutralUnit>>::iterator::value_type>, 00222 stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<NeutralUnit>>::iterator> 00223 neutral_unit_wrapper_iterator; 00224 typedef boost::filter_iterator<WrapperIsBuilding, neutral_unit_wrapper_iterator> 00225 neutral_building_wrapper_iterator; 00226 typedef boost::transform_iterator<extract_unit<NeutralUnit>, 00227 neutral_unit_wrapper_iterator> 00228 neutral_unit_iterator; 00229 typedef neutral_unit_iterator 00230 neutral_unit_type_iterator; 00231 typedef boost::transform_iterator<extract_unit<NeutralUnit>, neutral_building_wrapper_iterator> 00232 neutral_building_iterator; 00233 typedef boost::transform_iterator<extract_pair_second_const<stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<NeutralUnit>>::const_iterator::value_type>, 00234 stdext::hash_multimap<BWAPI::UnitType, UnitWrapper<NeutralUnit>>::const_iterator> 00235 neutral_unit_wrapper_const_iterator; 00236 typedef boost::filter_iterator<WrapperIsBuilding, neutral_unit_wrapper_const_iterator> 00237 neutral_building_wrapper_const_iterator; 00238 typedef boost::transform_iterator<extract_unit_const<NeutralUnit>, 00239 neutral_unit_wrapper_const_iterator> 00240 neutral_unit_const_iterator; 00241 typedef neutral_unit_const_iterator 00242 neutral_unit_type_const_iterator; 00243 typedef boost::transform_iterator<extract_unit_const<NeutralUnit>, neutral_building_wrapper_const_iterator> 00244 neutral_building_const_iterator; 00245 };