소스 검색

Removed usage of boost::thread from vcmi, except for AI

Ivan Savenko 7 달 전
부모
커밋
844dfb1604

+ 25 - 32
AI/BattleAI/BattleAI.cpp

@@ -143,49 +143,42 @@ void CBattleAI::activeStack(const BattleID & battleID, const CStack * stack )
 
 	auto start = std::chrono::high_resolution_clock::now();
 
-	try
+	if(stack->creatureId() == CreatureID::CATAPULT)
 	{
-		if(stack->creatureId() == CreatureID::CATAPULT)
-		{
-			cb->battleMakeUnitAction(battleID, useCatapult(battleID, stack));
-			return;
-		}
-		if(stack->hasBonusOfType(BonusType::SIEGE_WEAPON) && stack->hasBonusOfType(BonusType::HEALER))
-		{
-			cb->battleMakeUnitAction(battleID, useHealingTent(battleID, stack));
-			return;
-		}
+		cb->battleMakeUnitAction(battleID, useCatapult(battleID, stack));
+		return;
+	}
+	if(stack->hasBonusOfType(BonusType::SIEGE_WEAPON) && stack->hasBonusOfType(BonusType::HEALER))
+	{
+		cb->battleMakeUnitAction(battleID, useHealingTent(battleID, stack));
+		return;
+	}
 
 #if BATTLE_TRACE_LEVEL>=1
-		logAi->trace("Build evaluator and targets");
+	logAi->trace("Build evaluator and targets");
 #endif
 
-		BattleEvaluator evaluator(
-			env, cb, stack, playerID, battleID, side, 
-			getStrengthRatio(cb->getBattle(battleID), side),
-			getSimulationTurnsCount(env->game()->getStartInfo()));
+	BattleEvaluator evaluator(
+		env, cb, stack, playerID, battleID, side,
+		getStrengthRatio(cb->getBattle(battleID), side),
+		getSimulationTurnsCount(env->game()->getStartInfo()));
 
-		result = evaluator.selectStackAction(stack);
+	result = evaluator.selectStackAction(stack);
 
-		if(autobattlePreferences.enableSpellsUsage && evaluator.canCastSpell())
-		{
-			auto spelCasted = evaluator.attemptCastingSpell(stack);
-
-			if(spelCasted)
-				return;
-		}
-
-		logAi->trace("Spellcast attempt completed in %lld", timeElapsed(start));
+	if(autobattlePreferences.enableSpellsUsage && evaluator.canCastSpell())
+	{
+		auto spelCasted = evaluator.attemptCastingSpell(stack);
 
-		if(auto action = considerFleeingOrSurrendering(battleID))
-		{
-			cb->battleMakeUnitAction(battleID, *action);
+		if(spelCasted)
 			return;
-		}
 	}
-	catch(boost::thread_interrupted &)
+
+	logAi->trace("Spellcast attempt completed in %lld", timeElapsed(start));
+
+	if(auto action = considerFleeingOrSurrendering(battleID))
 	{
-		throw;
+		cb->battleMakeUnitAction(battleID, *action);
+		return;
 	}
 
 	if(result.actionType == EActionType::DEFEND)

+ 2 - 0
AI/Nullkiller/AIGateway.h

@@ -22,6 +22,8 @@
 #include "Pathfinding/AIPathfinder.h"
 #include "Engine/Nullkiller.h"
 
+#include <boost/thread/thread_only.hpp>
+
 namespace NKAI
 {
 

+ 1 - 1
AI/Nullkiller/Analyzers/BuildAnalyzer.cpp

@@ -62,7 +62,7 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo)
 		{BuildingID::MAGES_GUILD_3, BuildingID::MAGES_GUILD_5}
 	};
 
-	if(developmentInfo.existingDwellings.size() >= 2 && ai->cb->getDate(Date::DAY_OF_WEEK) > boost::date_time::Friday)
+	if(developmentInfo.existingDwellings.size() >= 2 && ai->cb->getDate(Date::DAY_OF_WEEK) > 4)
 	{
 		otherBuildings.push_back({BuildingID::HORDE_1});
 		otherBuildings.push_back({BuildingID::HORDE_2});

+ 2 - 0
AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.cpp

@@ -15,6 +15,8 @@
 #include "../../../lib/CRandomGenerator.h"
 #include "../../../lib/logging/VisualLogger.h"
 
+#include <boost/thread/thread_only.hpp>
+
 namespace NKAI
 {
 

+ 2 - 0
AI/Nullkiller/Pathfinding/AIPathfinder.cpp

@@ -14,6 +14,8 @@
 #include "../../../lib/mapping/CMap.h"
 #include "../Engine/Nullkiller.h"
 
+#include <boost/thread/thread_only.hpp>
+
 namespace NKAI
 {
 

+ 0 - 1
AI/StupidAI/StupidAI.cpp

@@ -124,7 +124,6 @@ void CStupidAI::yourTacticPhase(const BattleID & battleID, int distance)
 
 void CStupidAI::activeStack(const BattleID & battleID, const CStack * stack)
 {
-	//boost::this_thread::sleep_for(boost::chrono::seconds(2));
 	print("activeStack called for " + stack->nodeName());
 	ReachabilityInfo dists = cb->getBattle(battleID)->getReachability(stack);
 	std::vector<EnemyInfo> enemiesShootable;

+ 2 - 0
AI/VCAI/VCAI.h

@@ -23,6 +23,8 @@
 #include "../../lib/spells/CSpellHandler.h"
 #include "Pathfinding/AIPathfinder.h"
 
+#include <boost/thread/thread_only.hpp>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 struct QuestInfo;

+ 0 - 2
CCallback.cpp

@@ -262,8 +262,6 @@ int CBattleCallback::sendRequest(const CPackForServer & request)
 		auto gsUnlocker = vstd::makeUnlockSharedGuardIf(CGameState::mutex, unlockGsWhenWaiting);
 		CClient::waitingRequest.waitWhileContains(requestID);
 	}
-
-	boost::this_thread::interruption_point();
 	return requestID;
 }
 

+ 1 - 3
Global.h

@@ -138,6 +138,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #include <shared_mutex>
 #include <sstream>
 #include <string>
+#include <thread>
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
@@ -172,8 +173,6 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #include <boost/current_function.hpp>
 #include <boost/container/small_vector.hpp>
 #include <boost/container/static_vector.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <boost/date_time/posix_time/time_formatters.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/filesystem/path.hpp>
@@ -188,7 +187,6 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #include <boost/range/adaptor/filtered.hpp>
 #include <boost/range/adaptor/reversed.hpp>
 #include <boost/range/algorithm.hpp>
-#include <boost/thread/thread_only.hpp>
 
 #ifndef M_PI
 #  define M_PI 3.14159265358979323846

+ 1 - 1
client/ArtifactsUIController.cpp

@@ -58,7 +58,7 @@ bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const Art
 	auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), onlyEquipped);
 	if(!assemblyPossibilities.empty())
 	{
-		auto askThread = new boost::thread([this, hero, art, slot, assemblyPossibilities, checkIgnored]() -> void
+		auto askThread = new std::thread([this, hero, art, slot, assemblyPossibilities, checkIgnored]() -> void
 			{
 				std::scoped_lock askLock(askAssembleArtifactMutex);
 				for(const auto combinedArt : assemblyPossibilities)

+ 2 - 2
client/CPlayerInterface.cpp

@@ -1437,7 +1437,7 @@ void CPlayerInterface::centerView (int3 pos, int focusTime)
 		{
 			IgnoreEvents ignore(*this);
 			auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
-			boost::this_thread::sleep_for(boost::chrono::milliseconds(focusTime));
+			std::this_thread::sleep_for(std::chrono::milliseconds(focusTime));
 		}
 	}
 	ENGINE->cursor().show();
@@ -1789,7 +1789,7 @@ void CPlayerInterface::waitForAllDialogs()
 	while(!dialogs.empty())
 	{
 		auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
-		boost::this_thread::sleep_for(boost::chrono::milliseconds(5));
+		std::this_thread::sleep_for(std::chrono::milliseconds(5));
 	}
 	waitWhileDialog();
 }

+ 14 - 18
client/CServerHandler.cpp

@@ -64,20 +64,14 @@ CServerHandler::~CServerHandler()
 	if (serverRunner)
 		serverRunner->shutdown();
 	networkHandler->stop();
-	try
-	{
-		if (serverRunner)
-			serverRunner->wait();
-		serverRunner.reset();
-		{
-			auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
-			threadNetwork.join();
-		}
-	}
-	catch (const std::runtime_error & e)
+
+	if (serverRunner)
+		serverRunner->wait();
+	serverRunner.reset();
+	if (threadNetwork.joinable())
 	{
-		logGlobal->error("Failed to shut down network thread! Reason: %s", e.what());
-		assert(0);
+		auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
+		threadNetwork.join();
 	}
 }
 
@@ -86,6 +80,8 @@ void CServerHandler::endNetwork()
 	if (client)
 		client->endNetwork();
 	networkHandler->stop();
+
+	if (threadNetwork.joinable())
 	{
 		auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 		threadNetwork.join();
@@ -792,20 +788,20 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
 	else
 		startLocalServerAndConnect(false);
 
-	boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+	std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
 	while(!settings["session"]["headless"].Bool() && !ENGINE->windows().topWindow<CLobbyScreen>())
-		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 
 	while(!mi || mapInfo->fileURI != mi->fileURI)
 	{
 		setMapInfo(mapInfo);
-		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 	}
 	// "Click" on color to remove us from it
 	setPlayer(myFirstColor());
 	while(myFirstColor() != PlayerColor::CANNOT_DETERMINE)
-		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 
 	while(true)
 	{
@@ -818,7 +814,7 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
 		{
 
 		}
-		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 	}
 }
 

+ 1 - 1
client/CServerHandler.h

@@ -103,7 +103,7 @@ class CServerHandler final : public IServerAPI, public LobbyInfo, public INetwor
 	std::shared_ptr<CMapInfo> mapToStart;
 	std::vector<std::string> localPlayerNames;
 
-	boost::thread threadNetwork;
+	std::thread threadNetwork;
 
 	std::atomic<EClientState> state;
 

+ 1 - 0
client/Client.h

@@ -70,6 +70,7 @@ public:
 
 	void waitWhileContains(const T & item)
 	{
+		//FIXME: should throw exception on destruction
 		TLock lock(mx);
 		while(vstd::contains(items, item))
 			cond.wait(lock);

+ 1 - 1
client/ServerRunner.cpp

@@ -49,7 +49,7 @@ void ServerThreadRunner::start(bool listenForConnections, bool connectToLobby, s
 
 	std::promise<uint16_t> promise;
 
-	threadRunLocalServer = boost::thread([this, connectToLobby, listenForConnections, &promise]{
+	threadRunLocalServer = std::thread([this, connectToLobby, listenForConnections, &promise]{
 		setThreadName("runServer");
 		uint16_t port = server->prepare(connectToLobby, listenForConnections);
 		promise.set_value(port);

+ 1 - 1
client/ServerRunner.h

@@ -36,7 +36,7 @@ public:
 class ServerThreadRunner final : public IServerRunner, boost::noncopyable
 {
 	std::unique_ptr<CVCMIServer> server;
-	boost::thread threadRunLocalServer;
+	std::thread threadRunLocalServer;
 	uint16_t serverPort = 0;
 	bool lobbyMode = false;
 

+ 1 - 1
client/adventureMap/CInGameConsole.cpp

@@ -300,7 +300,7 @@ void CInGameConsole::endEnteringText(bool processEnteredText)
 				commandController.processCommand(txt.substr(1), true);
 			};
 
-			boost::thread clientCommandThread(threadFunction);
+			std::thread clientCommandThread(threadFunction);
 			clientCommandThread.detach();
 		}
 		else

+ 1 - 1
client/battle/BattleInterface.cpp

@@ -751,7 +751,7 @@ void BattleInterface::requestAutofightingAIToTakeAction()
 			// FIXME: unsafe
 			// Run task in separate thread to avoid UI lock while AI is making turn (which might take some time)
 			// HOWEVER this thread won't atttempt to lock game state, potentially leading to races
-			boost::thread aiThread([localBattleID = battleID, localCurInt = curInt, activeStack]()
+			std::thread aiThread([localBattleID = battleID, localCurInt = curInt, activeStack]()
 			{
 				setThreadName("autofightingAI");
 				localCurInt->autofightingAI->activeStack(localBattleID, activeStack);

+ 6 - 6
client/gui/FramerateManager.cpp

@@ -15,7 +15,7 @@
 #include <SDL_video.h>
 
 FramerateManager::FramerateManager(int targetFrameRate)
-	: targetFrameTime(Duration(boost::chrono::seconds(1)) / targetFrameRate)
+	: targetFrameTime(Duration(std::chrono::seconds(1)) / targetFrameRate)
 	, lastFrameIndex(0)
 	, lastFrameTimes({})
 	, lastTimePoint(Clock::now())
@@ -31,15 +31,15 @@ void FramerateManager::framerateDelay()
 	if(!vsyncEnabled && timeSpentBusy < targetFrameTime)
 	{
 		// if FPS is higher than it should be, then wait some time
-		boost::this_thread::sleep_for(targetFrameTime - timeSpentBusy);
+		std::this_thread::sleep_for(targetFrameTime - timeSpentBusy);
 	}
 
 	// compute actual timeElapsed taking into account actual sleep interval
 	// limit it to 100 ms to avoid breaking animation in case of huge lag (e.g. triggered breakpoint)
 	TimePoint currentTicks = Clock::now();
 	Duration timeElapsed = currentTicks - lastTimePoint;
-	if(timeElapsed > boost::chrono::milliseconds(100))
-		timeElapsed = boost::chrono::milliseconds(100);
+	if(timeElapsed > std::chrono::milliseconds(100))
+		timeElapsed = std::chrono::milliseconds(100);
 
 	lastTimePoint = currentTicks;
 	lastFrameIndex = (lastFrameIndex + 1) % lastFrameTimes.size();
@@ -48,7 +48,7 @@ void FramerateManager::framerateDelay()
 
 ui32 FramerateManager::getElapsedMilliseconds() const
 {
-	return lastFrameTimes[lastFrameIndex] / boost::chrono::milliseconds(1);
+	return lastFrameTimes[lastFrameIndex] / std::chrono::milliseconds(1);
 }
 
 ui32 FramerateManager::getFramerate() const
@@ -59,5 +59,5 @@ ui32 FramerateManager::getFramerate() const
 	if(actualFrameTime == actualFrameTime.zero())
 		return 0;
 
-	return std::round(boost::chrono::duration<double>(1) / actualFrameTime);
+	return std::round(std::chrono::duration<double>(1) / actualFrameTime);
 };

+ 1 - 1
client/gui/FramerateManager.h

@@ -12,7 +12,7 @@
 /// Framerate manager controls current game frame rate by constantly trying to reach targeted frame rate
 class FramerateManager
 {
-	using Clock = boost::chrono::high_resolution_clock;
+	using Clock = std::chrono::steady_clock;
 	using TimePoint = Clock::time_point;
 	using Duration = Clock::duration;
 

+ 5 - 5
clientapp/EntryPoint.cpp

@@ -318,7 +318,7 @@ int main(int argc, char * argv[])
 	
 #ifndef VCMI_NO_THREADED_LOAD
 	//we can properly play intro only in the main thread, so we have to move loading to the separate thread
-	boost::thread loading([]()
+	std::thread loading([]()
 	{
 		setThreadName("initialize");
 		init();
@@ -368,13 +368,13 @@ int main(int argc, char * argv[])
 	{
 		session["testmap"].String() = vm["testmap"].as<std::string>();
 		session["onlyai"].Bool() = true;
-		boost::thread(&CServerHandler::debugStartTest, &GAME->server(), session["testmap"].String(), false);
+		GAME->server().debugStartTest(session["testmap"].String(), false);
 	}
 	else if(vm.count("testsave"))
 	{
 		session["testsave"].String() = vm["testsave"].as<std::string>();
 		session["onlyai"].Bool() = true;
-		boost::thread(&CServerHandler::debugStartTest, &GAME->server(), session["testsave"].String(), true);
+		GAME->server().debugStartTest(session["testsave"].String(), true);
 	}
 	else if (!settings["session"]["headless"].Bool())
 	{
@@ -397,9 +397,9 @@ int main(int argc, char * argv[])
 	else
 	{
 		while(!headlessQuit)
-			boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+			std::this_thread::sleep_for(std::chrono::milliseconds(200));
 
-		boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+		std::this_thread::sleep_for(std::chrono::milliseconds(500));
 
 		quitApplication();
 	}

+ 5 - 4
lib/CConsoleHandler.cpp

@@ -252,9 +252,10 @@ int CConsoleHandler::run()
 					cb(buffer, false);
 		}
 		else
-			boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+			std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
-		boost::this_thread::interruption_point();
+		if (shutdownPending)
+			return -1;
 #else
 		std::getline(std::cin, buffer);
 		if ( cb )
@@ -306,7 +307,7 @@ void CConsoleHandler::end()
 	if (thread.joinable())
 	{
 #ifndef VCMI_WINDOWS
-		thread.interrupt();
+		shutdownPending = true;
 #else
 		TerminateThread(thread.native_handle(),0);
 #endif
@@ -316,7 +317,7 @@ void CConsoleHandler::end()
 
 void CConsoleHandler::start()
 {
-	thread = boost::thread(std::bind(&CConsoleHandler::run, this));
+	thread = std::thread(std::bind(&CConsoleHandler::run,console));
 }
 
 VCMI_LIB_NAMESPACE_END

+ 3 - 1
lib/CConsoleHandler.h

@@ -94,9 +94,11 @@ private:
 	//function to be called when message is received - string: message, bool: whether call was made from in-game console
 	std::function<void(const std::string &, bool)> cb;
 
+	std::atomic<bool> shutdownPending = false;
+
 	std::mutex smx;
 
-	boost::thread thread;
+	std::thread thread;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 1 - 1
lib/CRandomGenerator.cpp

@@ -35,7 +35,7 @@ void CRandomGenerator::resetSeed()
 {
 	logRng->trace("CRandomGenerator::resetSeed");
 	boost::hash<std::string> stringHash;
-	auto threadIdHash = stringHash(boost::lexical_cast<std::string>(boost::this_thread::get_id()));
+	auto threadIdHash = stringHash(boost::lexical_cast<std::string>(std::this_thread::get_id()));
 	setSeed(static_cast<int>(threadIdHash * std::time(nullptr)));
 }
 

+ 1 - 1
lib/CThreadHelper.cpp

@@ -28,7 +28,7 @@ std::string getThreadName()
 	if (!threadNameForLogging.empty())
 		return threadNameForLogging;
 
-	return boost::lexical_cast<std::string>(boost::this_thread::get_id());
+	return boost::lexical_cast<std::string>(std::this_thread::get_id());
 }
 
 void setThreadNameLoggingOnly(const std::string &name)

+ 4 - 0
lib/logging/CLogger.h

@@ -10,6 +10,10 @@
 #pragma once
 
 
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/date_time/posix_time/time_formatters.hpp>
+
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CLogger;

+ 1 - 1
mapeditor/graphics.cpp

@@ -102,7 +102,7 @@ Graphics::Graphics()
 	tasks += std::bind(&Graphics::loadErmuToPicture,this);
 	tasks += std::bind(&Graphics::initializeImageLists,this);
 	
-	CThreadHelper th(&tasks,std::max((ui32)1,boost::thread::hardware_concurrency()));
+	CThreadHelper th(&tasks,std::max((ui32)1,std::thread::hardware_concurrency()));
 	th.run();
 #else
 	loadPaletteAndColors();

+ 2 - 2
server/CVCMIServer.cpp

@@ -229,7 +229,7 @@ bool CVCMIServer::prepareToStartGame()
 	if (lobbyProcessor)
 		lobbyProcessor->sendGameStarted();
 
-	auto progressTrackingThread = boost::thread([this, &progressTracking]()
+	auto progressTrackingThread = std::thread([this, &progressTracking]()
 	{
 		auto currentProgress = std::numeric_limits<Load::Type>::max();
 
@@ -243,7 +243,7 @@ bool CVCMIServer::prepareToStartGame()
 				loadProgress.progress = currentProgress;
 				announcePack(loadProgress);
 			}
-			boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+			std::this_thread::sleep_for(std::chrono::milliseconds(50));
 		}
 	});