Selaa lähdekoodia

NKAI: fix headless and compilation

Andrii Danylchenko 1 vuosi sitten
vanhempi
sitoutus
3820f6f78b

+ 5 - 5
AI/Nullkiller/Pathfinding/AINodeStorage.cpp

@@ -116,7 +116,7 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
 
 	//Each thread gets different x, but an array of y located next to each other in memory
 
-	parallel_for(blocked_range<size_t>(0, sizes.x), [&](const blocked_range<size_t>& r)
+	tbb::parallel_for(tbb::blocked_range<size_t>(0, sizes.x), [&](const tbb::blocked_range<size_t>& r)
 	{
 		int3 pos;
 
@@ -431,7 +431,7 @@ public:
 		newChains.reserve(AIPathfinding::NUM_CHAINS);
 	}
 
-	void execute(const blocked_range<size_t>& r)
+	void execute(const tbb::blocked_range<size_t>& r)
 	{
 		std::random_device randomDevice;
 		std::mt19937 randomEngine(randomDevice());
@@ -527,7 +527,7 @@ bool AINodeStorage::calculateHeroChain()
 
 		std::shuffle(data.begin(), data.end(), randomEngine);
 
-		parallel_for(blocked_range<size_t>(0, data.size()), [&](const blocked_range<size_t>& r)
+		tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size()), [&](const tbb::blocked_range<size_t>& r)
 		{
 			//auto r = blocked_range<size_t>(0, data.size());
 			HeroChainCalculationTask task(*this, nodes, data, chainMask, heroChainTurn);
@@ -543,7 +543,7 @@ bool AINodeStorage::calculateHeroChain()
 	}
 	else
 	{
-		auto r = blocked_range<size_t>(0, data.size());
+		auto r = tbb::blocked_range<size_t>(0, data.size());
 		HeroChainCalculationTask task(*this, nodes, data, chainMask, heroChainTurn);
 
 		task.execute(r);
@@ -1178,7 +1178,7 @@ void AINodeStorage::calculateTownPortalTeleportations(std::vector<CGPathNode *>
 
 	if(actorsVector.size() * initialNodes.size() > 1000)
 	{
-		parallel_for(blocked_range<size_t>(0, actorsVector.size()), [&](const blocked_range<size_t> & r)
+		tbb::parallel_for(tbb::blocked_range<size_t>(0, actorsVector.size()), [&](const tbb::blocked_range<size_t> & r)
 			{
 				for(int i = r.begin(); i != r.end(); i++)
 				{

+ 2 - 2
AI/Nullkiller/Pathfinding/AINodeStorage.h

@@ -27,8 +27,8 @@ namespace NKAI
 {
 namespace AIPathfinding
 {
-	const int BUCKET_COUNT = 5;
-	const int BUCKET_SIZE = 6;
+	const int BUCKET_COUNT = 3;
+	const int BUCKET_SIZE = 7;
 	const int NUM_CHAINS = BUCKET_COUNT * BUCKET_SIZE;
 	const int CHAIN_MAX_DEPTH = 4;
 }

+ 1 - 1
AI/Nullkiller/Pathfinding/AIPathfinder.cpp

@@ -154,7 +154,7 @@ void AIPathfinder::updateGraphs(const std::map<const CGHeroInstance *, HeroRole>
 		}
 	}
 
-	parallel_for(blocked_range<size_t>(0, heroesVector.size()), [this, &heroesVector](const blocked_range<size_t> & r)
+	tbb::parallel_for(tbb::blocked_range<size_t>(0, heroesVector.size()), [this, &heroesVector](const tbb::blocked_range<size_t> & r)
 		{
 			for(auto i = r.begin(); i != r.end(); i++)
 				heroGraphs.at(heroesVector[i]->id)->calculatePaths(heroesVector[i], ai);

+ 1 - 0
AI/Nullkiller/Pathfinding/ObjectGraph.cpp

@@ -16,6 +16,7 @@
 #include "../Engine/Nullkiller.h"
 #include "../../../lib/logging/VisualLogger.h"
 #include "Actions/QuestAction.h"
+#include "../pforeach.h"
 
 namespace NKAI
 {

+ 50 - 0
AI/Nullkiller/pforeach.h

@@ -0,0 +1,50 @@
+#pragma once
+
+#include "Engine/Nullkiller.h"
+
+namespace NKAI
+{
+
+template<typename TFunc>
+void pforeachTilePos(const int3 & mapSize, TFunc fn)
+{
+	for(int z = 0; z < mapSize.z; ++z)
+	{
+		tbb::parallel_for(tbb::blocked_range<size_t>(0, mapSize.x), [&](const tbb::blocked_range<size_t> & r)
+			{
+				int3 pos(0, 0, z);
+
+				for(pos.x = r.begin(); pos.x != r.end(); ++pos.x)
+				{
+					for(pos.y = 0; pos.y < mapSize.y; ++pos.y)
+					{
+						fn(pos);
+					}
+				}
+			});
+	}
+}
+
+template<typename TFunc>
+void pforeachTilePaths(const int3 & mapSize, const Nullkiller * ai, TFunc fn)
+{
+	for(int z = 0; z < mapSize.z; ++z)
+	{
+		tbb::parallel_for(tbb::blocked_range<size_t>(0, mapSize.x), [&](const tbb::blocked_range<size_t> & r)
+			{
+				int3 pos(0, 0, z);
+				std::vector<AIPath> paths;
+
+				for(pos.x = r.begin(); pos.x != r.end(); ++pos.x)
+				{
+					for(pos.y = 0; pos.y < mapSize.y; ++pos.y)
+					{
+						ai->pathfinder->calculatePathInfo(paths, pos);
+						fn(pos, paths);
+					}
+				}
+			});
+	}
+}
+
+}

+ 13 - 2
client/CMT.cpp

@@ -56,6 +56,7 @@ namespace po = boost::program_options;
 namespace po_style = boost::program_options::command_line_style;
 
 static std::atomic<bool> quitRequestedDuringOpeningPlayback = false;
+static std::atomic<bool> headlessQuit = false;
 
 #ifndef VCMI_IOS
 void processCommand(const std::string &message);
@@ -371,8 +372,10 @@ int main(int argc, char * argv[])
 	}
 	else
 	{
-		while(true)
+		while(!headlessQuit)
 			boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+
+		quitApplication();
 	}
 
 	return 0;
@@ -481,7 +484,15 @@ void handleQuit(bool ask)
 	// proper solution would be to abort init thread (or wait for it to finish)
 	if(!ask)
 	{
-		quitApplication();
+		if(settings["session"]["headless"].Bool())
+		{
+			headlessQuit = true;
+		}
+		else
+		{
+			quitApplication();
+		}
+
 		return;
 	}