1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Shut down the thread for tactic phase properly

This commit is contained in:
Adriankhl 2023-04-04 21:54:30 +02:00 committed by Nordsoft91
parent 4d37686eb3
commit 1d6192ca62
5 changed files with 37 additions and 1 deletions

View File

@ -1032,6 +1032,12 @@ void CPlayerInterface::yourTacticPhase(int distance)
boost::this_thread::sleep(boost::posix_time::millisec(1));
}
void CPlayerInterface::forceEndTacticPhase()
{
if (battleInt)
battleInt->tacticsMode = false;
}
void CPlayerInterface::showInfoDialog(EInfoWindowMode type, const std::string &text, const std::vector<Component> & components, int soundID)
{
EVENT_HANDLER_CALLED_BY_CLIENT;

View File

@ -226,6 +226,7 @@ public:
void battleCatapultAttacked(const CatapultAttack & ca) override; //called when catapult makes an attack
void battleGateStateChanged(const EGateState state) override;
void yourTacticPhase(int distance) override;
void forceEndTacticPhase() override;
//-------------//
void showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList<bool()> onYes);

View File

@ -7,6 +7,7 @@
* Full text of license available in license.txt file, in main folder
*
*/
#include "Global.h"
#include "StdInc.h"
#include "Client.h"
@ -31,6 +32,7 @@
#include "../lib/registerTypes/RegisterTypes.h"
#include "../lib/serializer/Connection.h"
#include <memory>
#include <vcmi/events/EventBus.h>
#if SCRIPTING_ENABLED
@ -369,6 +371,9 @@ void CClient::endGame()
logNetwork->info("Deleted mapHandler and gameState.");
}
//threads cleanup has to be after gs cleanup and before battleints cleanup to stop tacticThread
cleanThreads();
playerint.clear();
battleints.clear();
battleCallbacks.clear();
@ -593,7 +598,8 @@ void CClient::battleStarted(const BattleInfo * info)
if(info->tacticDistance && vstd::contains(battleints, info->sides[info->tacticsSide].color))
{
boost::thread(&CClient::commenceTacticPhaseForInt, this, battleints[info->sides[info->tacticsSide].color]);
PlayerColor color = info->sides[info->tacticsSide].color;
playerTacticThreads[color] = std::make_unique<boost::thread>(&CClient::commenceTacticPhaseForInt, this, battleints[color]);
}
}
@ -754,6 +760,23 @@ void CClient::removeGUI()
LOCPLINT = nullptr;
}
void CClient::cleanThreads()
{
stopAllBattleActions();
while (!playerTacticThreads.empty())
{
PlayerColor color = playerTacticThreads.begin()->first;
//set tacticcMode of the players to false to stop tacticThread
if (vstd::contains(battleints, color))
battleints[color]->forceEndTacticPhase();
playerTacticThreads[color]->join();
playerTacticThreads.erase(color);
}
}
#ifdef VCMI_ANDROID
#ifndef SINGLE_PROCESS_APP
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerClosed(JNIEnv * env, jclass cls)

View File

@ -9,6 +9,7 @@
*/
#pragma once
#include <memory>
#include <vcmi/Environment.h>
#include "../lib/IGameCallback.h"
@ -241,6 +242,8 @@ public:
void showInfoDialog(const std::string & msg, PlayerColor player) override {};
void removeGUI();
void cleanThreads();
#if SCRIPTING_ENABLED
scripting::Pool * getGlobalContextPool() const override;
scripting::Pool * getContextPool() const override;
@ -262,6 +265,8 @@ private:
std::map<PlayerColor, std::shared_ptr<boost::thread>> playerActionThreads;
std::map<PlayerColor, std::unique_ptr<boost::thread>> playerTacticThreads;
void waitForMoveAndSend(PlayerColor color);
void reinitScripting();
};

View File

@ -82,6 +82,7 @@ public:
//battle call-ins
virtual BattleAction activeStack(const CStack * stack)=0; //called when it's turn of that stack
virtual void yourTacticPhase(int distance){}; //called when interface has opportunity to use Tactics skill -> use cb->battleMakeTacticAction from this function
virtual void forceEndTacticPhase(){}; //force the tatic phase to end to clean up the tactic phase thread
};
/// Central class for managing human player / AI interface logic