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.
This commit is contained in:
elexis 2018-05-08 09:45:54 +00:00
parent 4c73614955
commit 27da92e55f
7 changed files with 65 additions and 66 deletions

View File

@ -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<const char*>(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();

View File

@ -94,7 +94,7 @@
#define MUST_INIT_X11 0
#endif
extern void restart_engine();
extern void RestartEngine();
#include <iostream>
@ -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;
}
}

View File

@ -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<void, &ExitProgram>("Exit");
scriptInterface.RegisterFunction<void, &RestartInAtlas>("RestartInAtlas");
scriptInterface.RegisterFunction<void, &QuitEngine>("Exit");
scriptInterface.RegisterFunction<void, &StartAtlas>("RestartInAtlas");
scriptInterface.RegisterFunction<bool, &AtlasIsAvailable>("AtlasIsAvailable");
scriptInterface.RegisterFunction<bool, &IsAtlasRunning>("IsAtlasRunning");
scriptInterface.RegisterFunction<void, std::string, &OpenURL>("OpenURL");

View File

@ -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);

View File

@ -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<CStr>& mods)

View File

@ -22,15 +22,15 @@
bool g_GameRestarted;
void kill_mainloop()
void QuitEngine()
{
}
void restart_mainloop_in_atlas()
void StartAtlas()
{
}
void restart_engine()
void RestartEngine()
{
}

View File

@ -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();
}
/**