浏览代码

Refactor goal removal from resource manager queue

Dydzio 6 年之前
父节点
当前提交
3e1b623fb6
共有 5 个文件被更改,包括 37 次插入32 次删除
  1. 5 0
      AI/VCAI/AIhelper.cpp
  2. 1 0
      AI/VCAI/AIhelper.h
  3. 27 16
      AI/VCAI/ResourceManager.cpp
  4. 2 1
      AI/VCAI/ResourceManager.h
  5. 2 15
      AI/VCAI/VCAI.cpp

+ 5 - 0
AI/VCAI/AIhelper.cpp

@@ -88,6 +88,11 @@ bool AIhelper::hasTasksLeft() const
 	return resourceManager->hasTasksLeft();
 }
 
+bool AIhelper::removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal&)> predicate)
+{
+	return resourceManager->removeOutdatedObjectives(predicate);
+}
+
 bool AIhelper::canAfford(const TResources & cost) const
 {
 	return resourceManager->canAfford(cost);

+ 1 - 0
AI/VCAI/AIhelper.h

@@ -47,6 +47,7 @@ public:
 	Goals::TSubgoal whatToDo() const override;
 	bool containsObjective(Goals::TSubgoal goal) const;
 	bool hasTasksLeft() const override;
+	bool removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate) override;
 
 	bool getBuildingOptions(const CGTownInstance * t) override;
 	BuildingID getMaxPossibleGoldBuilding(const CGTownInstance * t);

+ 27 - 16
AI/VCAI/ResourceManager.cpp

@@ -232,22 +232,12 @@ bool ResourceManager::notifyGoalCompleted(Goals::TSubgoal goal)
 	if (goal->invalid())
 		logAi->warn("Attempt to complete Invalid goal");
 
-	bool removedGoal = false;
-	while (true)
-	{ //unfortunatelly we can't use remove_if on heap
-		auto it = boost::find_if(queue, [goal](const ResourceObjective & ro) -> bool
-		{
-			return ro.goal == goal || ro.goal->fulfillsMe (goal);
-		});
-		if(it != queue.end()) //removed at least one
-		{
-			logAi->debug("Removing goal %s from ResourceManager.", it->goal->name());
-			queue.erase(queue.s_handle_from_iterator(it));
-			removedGoal = true;
-		}
-		else //found nothing more to remove
-			break;
-	}
+	std::function<bool(const Goals::TSubgoal &)> equivalentGoalsCheck = [goal](const Goals::TSubgoal & x) -> bool
+	{
+		return x == goal || x->fulfillsMe(goal);
+	};
+
+	bool removedGoal = removeOutdatedObjectives(equivalentGoalsCheck);
 
 	dumpToLog();
 
@@ -315,6 +305,27 @@ bool ResourceManager::hasTasksLeft() const
 	return !queue.empty();
 }
 
+bool ResourceManager::removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate)
+{
+	bool removedAnything = false;
+	while(true)
+	{ //unfortunately we can't use remove_if on heap
+		auto it = boost::find_if(queue, [&](const ResourceObjective & ro) -> bool
+		{
+			predicate(ro.goal);
+		});
+		if(it != queue.end()) //removed at least one
+		{
+			logAi->debug("Removing goal %s from ResourceManager.", it->goal->name());
+			queue.erase(queue.s_handle_from_iterator(it));
+			removedAnything = true;
+		}
+		else //found nothing more to remove
+			break;
+	}
+	return removedAnything;
+}
+
 TResources ResourceManager::reservedResources() const
 {
 	TResources res;

+ 2 - 1
AI/VCAI/ResourceManager.h

@@ -52,7 +52,7 @@ public:
 	virtual Goals::TSubgoal whatToDo(TResources &res, Goals::TSubgoal goal) = 0;
 	virtual bool containsObjective(Goals::TSubgoal goal) const = 0;
 	virtual bool hasTasksLeft() const = 0;
-private:
+	virtual bool removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate) = 0; //remove ResourceObjectives from queue if ResourceObjective->goal meets specific criteria
 	virtual bool notifyGoalCompleted(Goals::TSubgoal goal) = 0;
 };
 
@@ -82,6 +82,7 @@ public:
 	Goals::TSubgoal whatToDo(TResources & res, Goals::TSubgoal goal); //can we afford this goal or need to CollectRes?
 	bool containsObjective(Goals::TSubgoal goal) const;
 	bool hasTasksLeft() const override;
+	bool removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate) override;
 
 protected: //not-const actions only for AI
 	virtual void reserveResoures(const TResources & res, Goals::TSubgoal goal = Goals::TSubgoal());

+ 2 - 15
AI/VCAI/VCAI.cpp

@@ -446,21 +446,8 @@ void VCAI::objectRemoved(const CGObjectInstance * obj)
 	for(auto goal : ultimateGoalsFromBasic)
 		vstd::erase_if(goal.second, checkRemovalValidity);
 
-	//clear resource manager goal cache - logic copied from ResourceManager::notifyGoalCompleted
-	while(true)
-	{ //unfortunately we can't use remove_if on heap
-		auto & queue = ah->resourceManager->queue;
-		auto iteratorToRemove = boost::find_if(queue, [&](const ResourceObjective & x) -> bool
-		{
-			return checkRemovalValidity(x.goal);
-		});
-		if(iteratorToRemove != queue.end()) //removed at least one
-		{
-			queue.erase(queue.s_handle_from_iterator(iteratorToRemove));
-		}
-		else //found nothing more to remove
-			break;
-	}
+	//clear resource manager goal cache
+	ah->removeOutdatedObjectives(checkRemovalValidity);
 
 	//TODO: Find better way to handle hero boat removal
 	if(auto hero = dynamic_cast<const CGHeroInstance *>(obj))