mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Refactor goal removal from resource manager queue
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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()); | ||||
|   | ||||
| @@ -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)) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user