1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Compile fixes, refactoring

This commit is contained in:
DjWarmonger 2013-11-24 15:30:17 +00:00
parent 27a30b5ff9
commit b0bdfff117
4 changed files with 35 additions and 62 deletions

View File

@ -851,3 +851,15 @@ void CGoal<T>::accept (VCAI * ai)
{
ai->tryRealize(static_cast<T&>(*this)); //casting enforces template instantiation
}
//TODO: find out why the following are not generated automatically on MVS?
void CGoal<Win>::accept (VCAI * ai)
{
ai->tryRealize(static_cast<Win&>(*this));
}
void CGoal<Build>::accept (VCAI * ai)
{
ai->tryRealize(static_cast<Build&>(*this));
}

View File

@ -100,10 +100,11 @@ public:
static TSubgoal tryRecruitHero();
virtual TSubgoal whatToDoToAchieve() = 0;
///Visitor pattern
//TODO: make accept work for shared_ptr... somehow
virtual void accept (VCAI * ai); //unhandled goal will report standard error
virtual bool operator== (AbstractGoal &g) //TODO: virtualize - comparison returns true only for same subclasses
virtual bool operator== (AbstractGoal &g)
{
return false;
}
@ -195,7 +196,6 @@ class Build : public CGoal<Build>
public:
Build() : CGoal (Goals::BUILD){};
TSubgoal whatToDoToAchieve() override;
void accept (const VCAI *);
};
class Explore : public CGoal<Explore>
{

View File

@ -1703,28 +1703,42 @@ void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
if (ultimateGoal->invalid())
return;
//we are looking for abstract goals
auto abstractGoal = striveToGoalInternal (ultimateGoal, false);
if (abstractGoal->invalid())
return;
//we received abstratc goal, need to find concrete goals
striveToGoalInternal (abstractGoal, true);
//TODO: save abstract goals not related to hero
}
Goals::TSubgoal VCAI::striveToGoalInternal(Goals::TSubgoal ultimateGoal, bool onlyAbstract)
{
Goals::TSubgoal abstractGoal = sptr(Goals::Invalid());
while(1)
{
Goals::TSubgoal goal = ultimateGoal; //FIXME: preserve subclass of goal
Goals::TSubgoal goal = ultimateGoal;
logAi->debugStream() << boost::format("Striving to goal of type %s") % ultimateGoal->name();
int maxGoals = 100; //preventing deadlock for mutually dependent goals
//FIXME: do not try to realize goal when loop didn't suceed
while(!goal->isElementar && !goal->isAbstract && maxGoals)
while(!goal->isElementar && maxGoals && (onlyAbstract || !goal->isAbstract))
{
logAi->debugStream() << boost::format("Considering goal %s") % goal->name();
try
{
boost::this_thread::interruption_point();
goal = goal->whatToDoToAchieve(); //FIXME: why it calls always base class?
goal = goal->whatToDoToAchieve();
--maxGoals;
}
catch(std::exception &e)
{
logAi->debugStream() << boost::format("Goal %s decomposition failed: %s") % goal->name() % e.what();
//setGoal (goal.hero, INVALID); //test: if we don't know how to realize goal, we should abandon it for now
return;
return sptr(Goals::Invalid());
}
}
@ -1770,7 +1784,7 @@ void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
{
completeGoal (goal);
if (fulfillsGoal (goal, ultimateGoal) || maxGoals > 98) //completed goal was main goal //TODO: find better condition
return;
return sptr(Goals::Invalid());
}
catch(std::exception &e)
{
@ -1779,61 +1793,7 @@ void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
break;
}
}
//TODO: save abstract goals not related to hero
//TODO: refactor, duplicated code
if (!abstractGoal->invalid()) //try to realize our one goal
{
while (1)
{
std::shared_ptr<Goals::AbstractGoal> goal(abstractGoal);
goal->setisAbstract(false);
int maxGoals = 50;
while (!goal->isElementar && maxGoals) //find elementar goal and fulfill it
{
try
{
boost::this_thread::interruption_point();
goal = goal->whatToDoToAchieve();
--maxGoals;
}
catch(std::exception &e)
{
logAi->debugStream() << boost::format("Goal %s decomposition failed: %s") % goal->name() % e.what();
//setGoal (goal.hero, INVALID);
return;
}
}
try
{
boost::this_thread::interruption_point();
if (!maxGoals)
{
std::runtime_error e("Too many subgoals, don't know what to do");
throw (e);
}
goal->accept(this);
boost::this_thread::interruption_point();
}
catch(boost::thread_interrupted &e)
{
logAi->debugStream() << boost::format("Player %d: Making turn thread received an interruption!") % playerID;
throw; //rethrow, we want to truly end this thread
}
catch(goalFulfilledException &e)
{
completeGoal (goal); //FIXME: deduce that we have realized GET_OBJ goal
if (fulfillsGoal (goal, abstractGoal) || maxGoals > 98) //completed goal was main goal
return;
}
catch(std::exception &e)
{
logAi->debugStream() << boost::format("Failed to realize subgoal of type %s (greater goal type was %s), I will stop.") % goal->name() % ultimateGoal->name();
logAi->debugStream() << boost::format("The error message was: %s") % e.what();
break;
}
}
}
return abstractGoal;
}
void VCAI::striveToQuest (const QuestInfo &q)

View File

@ -233,6 +233,7 @@ public:
void buildArmyIn(const CGTownInstance * t);
void striveToGoal(Goals::TSubgoal ultimateGoal);
Goals::TSubgoal striveToGoalInternal(Goals::TSubgoal ultimateGoal, bool onlyAbstract);
void endTurn();
void wander(HeroPtr h);
void setGoal(HeroPtr h, Goals::TSubgoal goal);