Readd JS API function Engine.Exit()

Requested in #8244 for scripting purposes and automated testing. Extend
the original design by adding a means to pass an exit status. This also
comes in handy in case one wants to cleanly error out from JS on parsing
errors of command line arguments as reported in #7967.

Fixes: #8244
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
This commit is contained in:
Ralph Sennhauser 2025-11-12 19:21:27 +01:00
parent b5c4a4635c
commit 0d60bdfd2e
No known key found for this signature in database
5 changed files with 18 additions and 14 deletions

View file

@ -9,9 +9,9 @@ export function aiWarn(output)
/**
* Useful for simulating consecutive AI matches.
*/
export function exit()
export function exit(exitStatus)
{
Engine.Exit();
Engine.Exit(exitStatus);
}
export function VectorDistance(a, b)

View file

@ -165,6 +165,7 @@ enum ShutdownType
};
static ShutdownType g_Shutdown = ShutdownType::None;
static int g_ExitStatus{EXIT_SUCCESS};
// to avoid redundant and/or recursive resizing, we save the new
// size after VIDEORESIZE messages and only update the video mode
@ -181,9 +182,10 @@ bool IsQuitRequested()
return g_Shutdown == ShutdownType::Quit;
}
void QuitEngine()
void QuitEngine(int exitStatus)
{
g_Shutdown = ShutdownType::Quit;
g_ExitStatus = exitStatus;
}
void RestartEngine()
@ -209,7 +211,7 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
break;
case SDL_QUIT:
QuitEngine();
QuitEngine(EXIT_SUCCESS);
break;
case SDL_DROPFILE:
@ -235,7 +237,7 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
std::string hotkey = static_cast<const char*>(ev->ev.user.data1);
if (hotkey == "exit")
{
QuitEngine();
QuitEngine(EXIT_SUCCESS);
return IN_HANDLED;
}
else if (hotkey == "screenshot")
@ -512,7 +514,7 @@ static void NonVisualFrame()
g_Profiler.Frame();
if (g_Game->IsGameFinished())
QuitEngine();
QuitEngine(EXIT_SUCCESS);
}
static void MainControllerInit()
@ -832,7 +834,6 @@ int main(int argc, char* argv[])
EarlyInit(); // must come at beginning of main
int returnValue{EXIT_SUCCESS};
try
{
// static_cast is ok, argc is never negative.
@ -840,7 +841,7 @@ int main(int argc, char* argv[])
}
catch (const RL::SetupError&)
{
returnValue = EXIT_FAILURE;
g_ExitStatus = EXIT_FAILURE;
}
// Shut down profiler initialised by EarlyInit
@ -854,5 +855,5 @@ int main(int argc, char* argv[])
wutil_Shutdown();
#endif
return returnValue;
return g_ExitStatus;
}

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -47,6 +47,8 @@
class ScriptInterface;
extern void QuitEngine(int exitStatus);
namespace JSI_Main
{
bool AtlasIsAvailable()
@ -134,6 +136,7 @@ std::string CalculateMD5(const std::string& input)
void RegisterScriptFunctions(const ScriptRequest& rq)
{
ScriptFunction::Register<&QuitEngine>(rq, "Exit");
ScriptFunction::Register<&AtlasIsAvailable>(rq, "AtlasIsAvailable");
ScriptFunction::Register<&IsAtlasRunning>(rq, "IsAtlasRunning");
ScriptFunction::Register<&OpenURL>(rq, "OpenURL");

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -25,7 +25,7 @@ bool IsQuitRequested()
return false;
}
void QuitEngine()
void QuitEngine(int)
{
}

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -87,7 +87,7 @@
#include <utility>
#include <vector>
extern void QuitEngine();
extern void QuitEngine(int exitStatus);
/**
* @file