1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00

Use exception throwing to shutdown main thread

This commit is contained in:
Ivan Savenko
2025-03-04 15:25:04 +00:00
parent 9732d39c70
commit a474803aaf
4 changed files with 30 additions and 15 deletions

View File

@@ -16,4 +16,3 @@ extern SDL_Renderer * mainRenderer;
/// Defined in clientapp EntryPoint
/// TODO: decide on better location for this method
[[noreturn]] void handleFatalError(const std::string & message, bool terminate);
[[noreturn]] void quitApplication();

View File

@@ -100,13 +100,15 @@ bool GameInstance::capturedAllEvents()
void GameInstance::onShutdownRequested(bool ask)
{
auto doQuit = [](){ throw GameShutdownException(); };
if(!ask)
quitApplication();
doQuit();
else
{
if (interface())
interface()->showYesNoDialog(LIBRARY->generaltexth->allTexts[69], quitApplication, nullptr);
interface()->showYesNoDialog(LIBRARY->generaltexth->allTexts[69], doQuit, nullptr);
else
CInfoWindow::showYesNoDialog(LIBRARY->generaltexth->allTexts[69], {}, quitApplication, {}, PlayerColor(1));
CInfoWindow::showYesNoDialog(LIBRARY->generaltexth->allTexts[69], {}, doQuit, {}, PlayerColor(1));
}
}

View File

@@ -21,6 +21,15 @@ VCMI_LIB_NAMESPACE_BEGIN
class INetworkHandler;
VCMI_LIB_NAMESPACE_END
class GameShutdownException final : public std::exception
{
public:
const char* what() const noexcept final
{
return "Game shutdown has been requested";
}
};
class GameInstance final : boost::noncopyable, public IGameEngineUser
{
std::unique_ptr<CServerHandler> serverInstance;

View File

@@ -62,7 +62,7 @@ namespace po_style = boost::program_options::command_line_style;
static std::atomic<bool> headlessQuit = false;
static std::optional<std::string> criticalInitializationError;
[[noreturn]] extern void quitApplication();
[[noreturn]] static void quitApplication();
static void init()
{
@@ -380,23 +380,28 @@ int main(int argc, char * argv[])
setThreadName("MainGUI");
#endif
if(!settings["session"]["headless"].Bool())
try
{
checkForModLoadingFailure();
ENGINE->mainLoop();
if(!settings["session"]["headless"].Bool())
{
checkForModLoadingFailure();
ENGINE->mainLoop();
}
else
{
while(!headlessQuit)
std::this_thread::sleep_for(std::chrono::milliseconds(200));
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
else
catch (const GameShutdownException & )
{
while(!headlessQuit)
std::this_thread::sleep_for(std::chrono::milliseconds(200));
std::this_thread::sleep_for(std::chrono::milliseconds(500));
quitApplication();
}
}
[[noreturn]] void quitApplication()
[[noreturn]] static void quitApplication()
{
GAME->server().endNetwork();