Explorar o código

Client threading tweak

AlexVinS %!s(int64=8) %!d(string=hai) anos
pai
achega
805b5215de
Modificáronse 4 ficheiros con 49 adicións e 3 borrados
  1. 4 0
      AI/BattleAI/BattleAI.cpp
  2. 33 0
      client/Client.cpp
  3. 10 1
      client/Client.h
  4. 2 2
      client/NetPacksClient.cpp

+ 4 - 0
AI/BattleAI/BattleAI.cpp

@@ -103,6 +103,10 @@ BattleAction CBattleAI::activeStack( const CStack * stack )
 			}
 		}
 	}
+	catch(boost::thread_interrupted &)
+	{
+		throw;
+	}
 	catch(std::exception &e)
 	{
 		logAi->error("Exception occurred in %s %s",__FUNCTION__, e.what());

+ 33 - 0
client/Client.cpp

@@ -816,6 +816,7 @@ void CClient::battleStarted(const BattleInfo * info)
 
 void CClient::battleFinished()
 {
+	stopAllBattleActions();
 	for(auto & side : gs->curB->sides)
 		if(battleCallbacks.count(side.color))
 			battleCallbacks[side.color]->setBattle(nullptr);
@@ -982,6 +983,38 @@ std::string CClient::aiNameForPlayer(bool battleAI)
 	return goodAI;
 }
 
+void CClient::startPlayerBattleAction(PlayerColor color)
+{
+	stopPlayerBattleAction(color);
+
+	if(vstd::contains(battleints, color))
+	{
+		auto thread = std::make_shared<boost::thread>(std::bind(&CClient::waitForMoveAndSend, this, color));
+		playerActionThreads[color] = thread;
+	}
+}
+
+void CClient::stopPlayerBattleAction(PlayerColor color)
+{
+	if(vstd::contains(playerActionThreads, color))
+	{
+		auto thread = playerActionThreads.at(color);
+		if(thread->joinable())
+		{
+			thread->interrupt();
+			thread->join();
+		}
+		playerActionThreads.erase(color);
+	}
+
+}
+
+void CClient::stopAllBattleActions()
+{
+	while(!playerActionThreads.empty())
+		stopPlayerBattleAction(playerActionThreads.begin()->first);
+}
+
 void CServerHandler::startServer()
 {
 	if(settings["session"]["donotstartserver"].Bool())

+ 10 - 1
client/Client.h

@@ -123,6 +123,8 @@ public:
 class CClient : public IGameCallback
 {
 	std::unique_ptr<CPathsInfo> pathInfo;
+
+	std::map<PlayerColor, std::shared_ptr<boost::thread>> playerActionThreads;
 public:
 	std::map<PlayerColor,std::shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
 	std::map<PlayerColor,std::shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
@@ -143,7 +145,7 @@ public:
 
 	static ThreadSafeVector<int> waitingRequest;//FIXME: make this normal field (need to join all threads before client destruction)
 
-	void waitForMoveAndSend(PlayerColor color);
+
 	//void sendRequest(const CPackForServer *request, bool waitForRealization);
 	CClient(void);
 	CClient(CConnection *con, StartInfo *si);
@@ -252,4 +254,11 @@ public:
 	void serialize(BinarySerializer & h, const int version, const std::set<PlayerColor>& playerIDs);
 	void serialize(BinaryDeserializer & h, const int version, const std::set<PlayerColor>& playerIDs);
 	void battleFinished();
+
+    void startPlayerBattleAction(PlayerColor color);
+
+    void stopPlayerBattleAction(PlayerColor color);
+    void stopAllBattleActions();
+private:
+	void waitForMoveAndSend(PlayerColor color);
 };

+ 2 - 2
client/NetPacksClient.cpp

@@ -647,8 +647,8 @@ void BattleSetActiveStack::applyCl(CClient *cl)
 	{
 		playerToCall = activated->owner;
 	}
-	if (vstd::contains(cl->battleints, playerToCall))
-		boost::thread(std::bind(&CClient::waitForMoveAndSend, cl, playerToCall));
+
+	cl->startPlayerBattleAction(playerToCall);
 }
 
 void BattleTriggerEffect::applyCl(CClient * cl)