1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-15 00:05:02 +02:00

Merge pull request #1767 from Adriankhl/fix_battle_thread_shutdown

Properly shutdown battle thread
This commit is contained in:
Ivan Savenko
2023-03-29 14:40:15 +03:00
committed by GitHub
2 changed files with 16 additions and 6 deletions

View File

@ -51,6 +51,8 @@
#include "../lib/serializer/Cast.h" #include "../lib/serializer/Cast.h"
#include "../lib/serializer/JsonSerializer.h" #include "../lib/serializer/JsonSerializer.h"
#include "../lib/ScriptHandler.h" #include "../lib/ScriptHandler.h"
#include "vstd/CLoggerBase.h"
#include <memory>
#include <vcmi/events/EventBus.h> #include <vcmi/events/EventBus.h>
#include <vcmi/events/GenericEvents.h> #include <vcmi/events/GenericEvents.h>
#include <vcmi/events/AdventureEvents.h> #include <vcmi/events/AdventureEvents.h>
@ -1671,6 +1673,12 @@ CGameHandler::CGameHandler(CVCMIServer * lobby)
CGameHandler::~CGameHandler() CGameHandler::~CGameHandler()
{ {
if (battleThread)
{
//Setting battleMadeAction is needed because battleThread waits for the action to continue the main loop
battleMadeAction.setn(true);
battleThread->join();
}
delete spellEnv; delete spellEnv;
delete gs; delete gs;
} }
@ -2712,7 +2720,7 @@ void CGameHandler::startBattlePrimary(const CArmedInstance *army1, const CArmedI
auto battleQuery = std::make_shared<CBattleQuery>(this, gs->curB); auto battleQuery = std::make_shared<CBattleQuery>(this, gs->curB);
queries.addQuery(battleQuery); queries.addQuery(battleQuery);
boost::thread(&CGameHandler::runBattle, this); this->battleThread = std::make_unique<boost::thread>(boost::thread(&CGameHandler::runBattle, this));
} }
void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank) void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank)
@ -6424,7 +6432,7 @@ void CGameHandler::runBattle()
//tactic round //tactic round
{ {
while (gs->curB->tacticDistance && !battleResult.get()) while ((lobby->state != EServerState::SHUTDOWN) && gs->curB->tacticDistance && !battleResult.get())
boost::this_thread::sleep(boost::posix_time::milliseconds(50)); boost::this_thread::sleep(boost::posix_time::milliseconds(50));
} }
@ -6502,7 +6510,7 @@ void CGameHandler::runBattle()
bool firstRound = true;//FIXME: why first round is -1? bool firstRound = true;//FIXME: why first round is -1?
//main loop //main loop
while (!battleResult.get()) //till the end of the battle ;] while ((lobby->state != EServerState::SHUTDOWN) && !battleResult.get()) //till the end of the battle ;]
{ {
BattleNextRound bnr; BattleNextRound bnr;
bnr.round = gs->curB->round + 1; bnr.round = gs->curB->round + 1;
@ -6567,7 +6575,7 @@ void CGameHandler::runBattle()
}; };
const CStack * next = nullptr; const CStack * next = nullptr;
while((next = getNextStack())) while((lobby->state != EServerState::SHUTDOWN) && (next = getNextStack()))
{ {
BattleUnitsChanged removeGhosts; BattleUnitsChanged removeGhosts;
for(auto stack : curB.stacks) for(auto stack : curB.stacks)
@ -6746,7 +6754,7 @@ void CGameHandler::runBattle()
boost::unique_lock<boost::mutex> lock(battleMadeAction.mx); boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
battleMadeAction.data = false; battleMadeAction.data = false;
while (!actionWasMade()) while ((lobby->state != EServerState::SHUTDOWN) && !actionWasMade())
{ {
battleMadeAction.cond.wait(lock); battleMadeAction.cond.wait(lock);
if (battleGetStackByID(nextId, false) != next) if (battleGetStackByID(nextId, false) != next)
@ -6802,6 +6810,7 @@ void CGameHandler::runBattle()
firstRound = false; firstRound = false;
} }
if (lobby->state != EServerState::SHUTDOWN)
endBattle(gs->curB->tile, gs->curB->battleGetFightingHero(0), gs->curB->battleGetFightingHero(1)); endBattle(gs->curB->tile, gs->curB->battleGetFightingHero(0), gs->curB->battleGetFightingHero(1));
} }

View File

@ -96,6 +96,7 @@ class CGameHandler : public IGameCallback, public CBattleInfoCallback, public En
{ {
CVCMIServer * lobby; CVCMIServer * lobby;
std::shared_ptr<CApplier<CBaseForGHApply>> applier; std::shared_ptr<CApplier<CBaseForGHApply>> applier;
std::unique_ptr<boost::thread> battleThread;
public: public:
using FireShieldInfo = std::vector<std::pair<const CStack *, int64_t>>; using FireShieldInfo = std::vector<std::pair<const CStack *, int64_t>>;
//use enums as parameters, because doMove(sth, true, false, true) is not readable //use enums as parameters, because doMove(sth, true, false, true) is not readable