BWAPI
|
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 }