BWAPI
SPAR/AIModule/SparAIModule/PerceptualState/Locations/Static/PrimitiveLocationBase.h
Go to the documentation of this file.
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 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines