BWAPI
SPAR/AIModule/SparAIModule/DecisionMaking/Layer2Actions/Interface/Actions/GroupTacticalAction.h
Go to the documentation of this file.
00001 #pragma once
00002 #include "TacticalAction.h"
00003 #include "../Layer2UnitData.h"
00004 #include "../../../../PersistentUnitGroup.h"
00005 #include "../../../../Utils/GroupProcess.h"
00006 
00007 class UnitManager;
00008 
00009 namespace layer2
00010 {
00014   class GroupTacticalAction : public GroupProcess, public virtual TacticalAction
00015   {
00016   public:
00017     GroupTacticalAction(unsigned int priority)
00018       : GroupProcess(NULL, new PersistentUnitGroup("Action-group"))
00019       , Process(Spar)
00020       , TacticalAction(priority)
00021       , m_initialGroup(&PersistentUnitGroup::EmptyGroup, *this)
00022       , m_initialUnitAddedEventHandler(*this)
00023       , m_initialUnitRemovedEventHandler(*this)
00024     {
00025       for (PersistentUnitGroup::const_iterator it = m_initialGroup->begin(); it != m_initialGroup->end(); ++it)
00026       {
00027         group()->insert(*it);
00028       }
00029       m_initialUnitAddedID = m_initialGroup->getUnitAddedEvent().subscribe(&m_initialUnitAddedEventHandler, NULL);
00030       m_initialUnitRemovedID = m_initialGroup->getUnitRemovedEvent().subscribe(&m_initialUnitRemovedEventHandler, NULL);
00031     }
00032 
00033     GroupTacticalAction(unsigned int priority, const PersistentUnitGroup* initialGroup)
00034       : GroupProcess(NULL, new PersistentUnitGroup("Action-group"))
00035       , Process(Spar)
00036       , TacticalAction(priority)
00037       , m_initialGroup(initialGroup, *this)
00038       , m_initialUnitAddedEventHandler(*this)
00039       , m_initialUnitRemovedEventHandler(*this)
00040     {
00041       for (PersistentUnitGroup::const_iterator it = m_initialGroup->begin(); it != m_initialGroup->end(); ++it)
00042       {
00043         group()->insert(*it);
00044       }
00045       m_initialUnitAddedID = m_initialGroup->getUnitAddedEvent().subscribe(&m_initialUnitAddedEventHandler, NULL);
00046       m_initialUnitRemovedID = m_initialGroup->getUnitRemovedEvent().subscribe(&m_initialUnitRemovedEventHandler, NULL);
00047     }
00048 
00049     ~GroupTacticalAction()
00050     {
00051       m_initialGroup->getUnitAddedEvent().unsubscribe(m_initialUnitAddedID);
00052       m_initialGroup->getUnitRemovedEvent().unsubscribe(m_initialUnitRemovedID);
00053     }
00054 
00055     void onUnitAddedToInitialGroup(void*, BWAPI::Unit* unit)
00056     {
00057       group()->insert(unit);
00058     }
00059 
00060     void onUnitRemovedFromInitialGroup(void*, BWAPI::Unit* unit)
00061     {
00062       group()->remove(unit);
00063     }
00064 
00065     bool addUnit(BWAPI::Unit* unit, bool force = false)
00066     {
00067       bool success = true;
00068       if (isWaitingToExecute())
00069       {
00070         success = group()->insert(unit);
00071       }
00072       else if (isExecuting())
00073       {
00074         success = addActionToUnit(unit, force);
00075         if (success)
00076         {
00077           group()->insert(unit);
00078         }
00079       }
00080       return success;
00081     }
00082 
00083     static int transfer(GroupTacticalAction* source, GroupTacticalAction* destination, const int n);
00084 
00086     // GUI //
00088     virtual std::set<BWAPI::Unit*> getCommandedUnits() const
00089     {
00090       return std::set<BWAPI::Unit*>(getGroup()->begin(), getGroup()->end());
00091     }
00092 
00093   protected:
00094     friend class Layer2UnitData;
00095 
00096     virtual void output(std::ostream& out) const
00097     {
00098       TacticalAction::output(out);
00099     }
00100 
00101     void removeUnit(BWAPI::Unit* unit)
00102     {
00103       // Condition instead?
00104      
00105       if (isWaitingToExecute())
00106       {
00107         group()->remove(unit);
00108       }
00109       else if (isExecuting())
00110       {
00111         removeActionFromUnit(unit);
00112         group()->remove(unit);
00113       }
00114     }
00115 
00116     virtual void executeImpl()
00117     {
00118       // Don't call GroupProcess::executeImpl() as it will be called in executeCommonImpl()
00119       TacticalAction::executeImpl();
00120     }
00121 
00122     virtual void executeCommonImpl()
00123     {
00124       TacticalAction::executeCommonImpl();
00125 
00126       m_initialGroup->getUnitAddedEvent().unsubscribe(m_initialUnitAddedID);
00127       m_initialGroup->getUnitRemovedEvent().unsubscribe(m_initialUnitRemovedID);
00128       for (PersistentUnitGroup::iterator it = group()->begin(); it != group()->end(); )
00129       {
00130         BWAPI::Unit* initialUnit = *it;
00131         PersistentUnitGroup::iterator next = ++PersistentUnitGroup::iterator(it);
00132         if (!addActionToUnit(initialUnit, false))
00133         {
00134           group()->remove(it);
00135         }
00136         it = next;
00137       }
00138 
00139       GroupProcess::executeImpl();
00140       // At this point the reference to initialGroup could be released
00141 #ifdef _DEBUG
00142       for (PersistentUnitGroup::const_iterator it = getGroup()->begin(); it != getGroup()->end(); ++it)
00143       {
00144         assert(dynamic_cast<Layer2UnitData&>(Spar->getUnitManager().getUnitData(*it)).getCurrentAction() == this);
00145       }
00146 #endif
00147     }
00148     
00149     virtual void terminateImpl()
00150     {
00151       // Don't call GroupProcess::terminateImpl() as it will be called in terminateCommonImpl()
00152       TacticalAction::terminateImpl();
00153     }
00154 
00155     virtual void terminateCommonImpl()
00156     {
00157       TacticalAction::terminateCommonImpl();
00158 
00159       GroupProcess::terminateImpl();
00160 
00161       for (PersistentUnitGroup::iterator it = group()->begin(); it != group()->end(); )
00162       {
00163         PersistentUnitGroup::iterator next = ++PersistentUnitGroup::iterator(it);
00164         removeActionFromUnit(*it);
00165         group()->remove(it);
00166         it = next;
00167       }
00168       //assert(getGroup()->empty());
00169     }
00170 
00171   private:
00172     PersistentUnitGroup* group() const
00173     {
00174       // To remove the const_cast, the PersistentUnitGroup would have to be declared on the stack!
00175       return const_cast<PersistentUnitGroup*>(GroupProcess::getGroup());
00176     }
00177 
00178     bool addActionToUnit(BWAPI::Unit* unit, bool force)
00179     {
00180       return dynamic_cast<Layer2UnitData&>(Spar->getUnitManager().getUnitData(unit)).proposeAction(this, force);
00181     }
00182 
00183     void removeActionFromUnit(BWAPI::Unit* unit)
00184     {
00185       dynamic_cast<Layer2UnitData&>(Spar->getUnitManager().getUnitData(unit)).removeAction(this);
00186     }
00187 
00188     EVENT_HANDLER1(GroupTacticalAction, onUnitAddedToInitialGroup, BWAPI::Unit*) m_initialUnitAddedEventHandler;
00189     PersistentUnitGroup::OnUnitAdded::SubscriberID m_initialUnitAddedID;
00190     EVENT_HANDLER1(GroupTacticalAction, onUnitRemovedFromInitialGroup, BWAPI::Unit*) m_initialUnitRemovedEventHandler;
00191     PersistentUnitGroup::OnUnitRemoved::SubscriberID m_initialUnitRemovedID;
00192 
00193     // Initial units sent to action
00194     AutoPtr<const PersistentUnitGroup> m_initialGroup;
00195   };
00196 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines