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