From 27da92e55f1ca2eb94e2d112147927f2db1f5de4 Mon Sep 17 00:00:00 2001 From: elexis Date: Tue, 8 May 2018 09:45:54 +0000 Subject: [PATCH] Main.cpp cleanup. Use an enum to indicate the type of engine shutdown instead of three bools. State in the comments that the program is restarted within the same process. In preparation of introducing an IsQuitRequested function (which shall not be named is_quit_requested as stressed by Vladislav): Rename kill_mainloop to QuitEngine, restart_mainloop to RestartEngine, restart_mainloop_in_atlas to StartAtlas to not break consistency. Don't rename RestartInAtlas in JS just now. Group declarations at the top of main.cpp. This was SVN commit r21817. --- source/main.cpp | 91 +++++++++---------- source/ps/GameSetup/GameSetup.cpp | 4 +- source/ps/scripting/JSInterface_Main.cpp | 16 ++-- source/ps/scripting/JSInterface_Main.h | 6 +- source/ps/scripting/JSInterface_Mod.cpp | 4 +- source/ps/tests/stub_impl_hack.h | 6 +- .../simulation2/components/CCmpAIManager.cpp | 4 +- 7 files changed, 65 insertions(+), 66 deletions(-) diff --git a/source/main.cpp b/source/main.cpp index b7f2e6db53..7e9db44fec 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -89,13 +89,30 @@ that of Atlas depending on commandline parameters. #define getpid _getpid // Use the non-deprecated function name #endif +extern CmdLineArgs g_args; extern CStrW g_UniqueLogPostfix; -void kill_mainloop(); - // Marks terrain as modified so the minimap can repaint (is there a cleaner way of handling this?) bool g_GameRestarted = false; +// Determines the lifetime of the mainloop +enum ShutdownType +{ + // The application shall continue the main loop. + None, + + // The process shall terminate as soon as possible. + Quit, + + // The engine should be restarted in the same process, for instance to activate different mods. + Restart, + + // Atlas should be started in the same process. + RestartAsAtlas +}; + +static ShutdownType g_Shutdown = ShutdownType::None; + // to avoid redundant and/or recursive resizing, we save the new // size after VIDEORESIZE messages and only update the video mode // once per frame. @@ -106,6 +123,21 @@ static int g_ResizedH; static std::chrono::high_resolution_clock::time_point lastFrameTime; +void QuitEngine() +{ + g_Shutdown = ShutdownType::Quit; +} + +void RestartEngine() +{ + g_Shutdown = ShutdownType::Restart; +} + +void StartAtlas() +{ + g_Shutdown = ShutdownType::RestartAsAtlas; +} + // main app message handler static InReaction MainInputHandler(const SDL_Event_* ev) { @@ -130,14 +162,14 @@ static InReaction MainInputHandler(const SDL_Event_* ev) break; case SDL_QUIT: - kill_mainloop(); + QuitEngine(); break; case SDL_HOTKEYDOWN: std::string hotkey = static_cast(ev->ev.user.data1); if (hotkey == "exit") { - kill_mainloop(); + QuitEngine(); return IN_HANDLED; } else if (hotkey == "screenshot") @@ -278,9 +310,6 @@ static void RendererIncrementalLoad() while (more && timer_Time() - startTime < maxTime); } - -static bool quit = false; // break out of main loop - static void Frame() { g_Profiler2.RecordFrameStart(); @@ -334,7 +363,7 @@ static void Frame() // if the user quit by closing the window, the GL context will be broken and // may crash when we call Render() on some drivers, so leave this loop // before rendering - if (quit) + if (g_Shutdown != ShutdownType::None) return; // respond to pumped resize events @@ -406,10 +435,9 @@ static void NonVisualFrame() g_Profiler.Frame(); if (g_Game->IsGameFinished()) - kill_mainloop(); + QuitEngine(); } - static void MainControllerInit() { // add additional input handlers only needed by this controller: @@ -418,41 +446,11 @@ static void MainControllerInit() in_add_handler(MainInputHandler); } - - static void MainControllerShutdown() { in_reset_handlers(); } - -// stop the main loop and trigger orderly shutdown. called from several -// places: the event handler (SDL_QUIT and hotkey) and JS exitProgram. -void kill_mainloop() -{ - quit = true; -} - - -static bool restart_in_atlas = false; -// called by game code to indicate main() should restart in Atlas mode -// instead of terminating -void restart_mainloop_in_atlas() -{ - quit = true; - restart_in_atlas = true; -} - -static bool restart = false; -// trigger an orderly shutdown and restart the game. -void restart_engine() -{ - quit = true; - restart = true; -} - -extern CmdLineArgs g_args; - // moved into a helper function to ensure args is destroyed before // exit(), which may result in a memory leak. static void RunGameOrAtlas(int argc, const char* argv[]) @@ -593,8 +591,8 @@ static void RunGameOrAtlas(int argc, const char* argv[]) int flags = INIT_MODS; do { - restart = false; - quit = false; + g_Shutdown = ShutdownType::None; + if (!Init(args, flags)) { flags &= ~INIT_MODS; @@ -618,14 +616,14 @@ static void RunGameOrAtlas(int argc, const char* argv[]) if (isNonVisual) { InitNonVisual(args); - while (!quit) + while (g_Shutdown == ShutdownType::None) NonVisualFrame(); } else { InitGraphics(args, 0, installedMods); MainControllerInit(); - while (!quit) + while (g_Shutdown == ShutdownType::None) Frame(); } @@ -635,9 +633,10 @@ static void RunGameOrAtlas(int argc, const char* argv[]) Shutdown(0); MainControllerShutdown(); flags &= ~INIT_MODS; - } while (restart); - if (restart_in_atlas) + } while (g_Shutdown == ShutdownType::Restart); + + if (g_Shutdown == ShutdownType::RestartAsAtlas) ATLAS_RunIfOnCmdLine(args, true); CXeromyces::Terminate(); diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index ba9a108bbb..3712e98a59 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -94,7 +94,7 @@ #define MUST_INIT_X11 0 #endif -extern void restart_engine(); +extern void RestartEngine(); #include @@ -958,7 +958,7 @@ bool Init(const CmdLineArgs& args, int flags) std::swap(g_modsLoaded, mods); // Abort init and restart - restart_engine(); + RestartEngine(); return false; } } diff --git a/source/ps/scripting/JSInterface_Main.cpp b/source/ps/scripting/JSInterface_Main.cpp index 13076d5a3b..6a6767c6ba 100644 --- a/source/ps/scripting/JSInterface_Main.cpp +++ b/source/ps/scripting/JSInterface_Main.cpp @@ -31,17 +31,17 @@ #include "scriptinterface/ScriptInterface.h" #include "tools/atlas/GameInterface/GameLoop.h" -extern void restart_mainloop_in_atlas(); -extern void kill_mainloop(); +extern void QuitEngine(); +extern void StartAtlas(); -void JSI_Main::ExitProgram(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Main::QuitEngine(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) { - kill_mainloop(); + ::QuitEngine(); } -void JSI_Main::RestartInAtlas(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Main::StartAtlas(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) { - restart_mainloop_in_atlas(); + ::StartAtlas(); } bool JSI_Main::AtlasIsAvailable(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) @@ -111,8 +111,8 @@ int JSI_Main::GetTextWidth(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const void JSI_Main::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("Exit"); - scriptInterface.RegisterFunction("RestartInAtlas"); + scriptInterface.RegisterFunction("Exit"); + scriptInterface.RegisterFunction("RestartInAtlas"); scriptInterface.RegisterFunction("AtlasIsAvailable"); scriptInterface.RegisterFunction("IsAtlasRunning"); scriptInterface.RegisterFunction("OpenURL"); diff --git a/source/ps/scripting/JSInterface_Main.h b/source/ps/scripting/JSInterface_Main.h index 12153f3a4e..01260bb080 100644 --- a/source/ps/scripting/JSInterface_Main.h +++ b/source/ps/scripting/JSInterface_Main.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -22,8 +22,8 @@ namespace JSI_Main { - void ExitProgram(ScriptInterface::CxPrivate* pCxPrivate); - void RestartInAtlas(ScriptInterface::CxPrivate* pCxPrivate); + void QuitEngine(ScriptInterface::CxPrivate* pCxPrivate); + void StartAtlas(ScriptInterface::CxPrivate* pCxPrivate); bool AtlasIsAvailable(ScriptInterface::CxPrivate* pCxPrivate); bool IsAtlasRunning(ScriptInterface::CxPrivate* pCxPrivate); void OpenURL(ScriptInterface::CxPrivate* pCxPrivate, const std::string& url); diff --git a/source/ps/scripting/JSInterface_Mod.cpp b/source/ps/scripting/JSInterface_Mod.cpp index 420ab9211b..a195f2bcf0 100644 --- a/source/ps/scripting/JSInterface_Mod.cpp +++ b/source/ps/scripting/JSInterface_Mod.cpp @@ -22,7 +22,7 @@ #include "ps/Mod.h" #include "scriptinterface/ScriptInterface.h" -extern void restart_engine(); +extern void RestartEngine(); JS::Value JSI_Mod::GetEngineInfo(ScriptInterface::CxPrivate* pCxPrivate) { @@ -46,7 +46,7 @@ JS::Value JSI_Mod::GetAvailableMods(ScriptInterface::CxPrivate* pCxPrivate) void JSI_Mod::RestartEngine(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) { - restart_engine(); + ::RestartEngine(); } void JSI_Mod::SetMods(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::vector& mods) diff --git a/source/ps/tests/stub_impl_hack.h b/source/ps/tests/stub_impl_hack.h index fc34795a74..40e02bc8de 100644 --- a/source/ps/tests/stub_impl_hack.h +++ b/source/ps/tests/stub_impl_hack.h @@ -22,15 +22,15 @@ bool g_GameRestarted; -void kill_mainloop() +void QuitEngine() { } -void restart_mainloop_in_atlas() +void StartAtlas() { } -void restart_engine() +void RestartEngine() { } diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp index a52472df0d..23be80b7a8 100644 --- a/source/simulation2/components/CCmpAIManager.cpp +++ b/source/simulation2/components/CCmpAIManager.cpp @@ -44,7 +44,7 @@ #include "simulation2/serialization/StdSerializer.h" #include "simulation2/serialization/SerializeTemplates.h" -extern void kill_mainloop(); +extern void QuitEngine(); /** * @file @@ -354,7 +354,7 @@ public: static void ExitProgram(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) { - kill_mainloop(); + QuitEngine(); } /**