diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index 10f4639702..e8bbcf6ac4 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -77,10 +77,10 @@ const CStr CGame::EventNameSimulationUpdate = "SimulationUpdate"; * Constructor * **/ -CGame::CGame(bool replayLog, const bool oosLog): +CGame::CGame(bool replayLog, const SimulationDebugOptions debugOptions): m_World(new CWorld(*this)), m_Simulation2{new CSimulation2{&m_World->GetUnitManager(), *g_ScriptContext, &m_World->GetTerrain(), - oosLog}}, + debugOptions}}, // TODO: we need to remove that global dependency. Maybe the game view // should be created outside only if needed. m_GameView(CRenderer::IsInitialised() ? new CGameView(g_VideoMode.GetBackendDevice(), this) : nullptr), diff --git a/source/ps/Game.h b/source/ps/Game.h index fb8d05fd42..6fcb45b44e 100644 --- a/source/ps/Game.h +++ b/source/ps/Game.h @@ -24,6 +24,7 @@ #include "ps/CStr.h" #include "ps/Errors.h" #include "simulation2/helpers/Player.h" +#include "simulation2/system/DebugOptions.h" #include #include @@ -88,7 +89,7 @@ class CGame CTurnManager* m_TurnManager; public: - CGame(bool replayLog, const bool oosLog = false); + CGame(bool replayLog, const SimulationDebugOptions debugOptions = {}); ~CGame(); /** diff --git a/source/ps/Replay.cpp b/source/ps/Replay.cpp index 771f85699b..e88c8a1c8e 100644 --- a/source/ps/Replay.cpp +++ b/source/ps/Replay.cpp @@ -249,11 +249,18 @@ void CReplayPlayer::Replay(const bool serializationtest, const int rejointesttur MountMods(Paths(g_CmdLineArgs), g_Mods.GetEnabledMods()); } - g_Game = new CGame(false, ooslog); + if (serializationtest && rejointestturn >= 0) + LOGERROR("serializationtest and rejointest can't be activ at the same time."); + + SimulationDebugOptions debugOption{}; if (serializationtest) - g_Game->GetSimulation2()->EnableSerializationTest(); + debugOption.test = SimulationDebugOptions::SerializationTest{}; if (rejointestturn >= 0) - g_Game->GetSimulation2()->EnableRejoinTest(rejointestturn); + debugOption.test = SimulationDebugOptions::RejoinTest{rejointestturn}; + if (ooslog) + debugOption.oosLog = true; + + g_Game = new CGame(false, debugOption); ScriptRequest rq(g_Game->GetSimulation2()->GetScriptInterface()); JS::RootedValue attribs(rq.cx); diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index ba6259e326..4edbd8fc4d 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -73,16 +73,24 @@ class CSimulation2Impl { public: CSimulation2Impl(CUnitManager* unitManager, ScriptContext& cx, CTerrain* terrain, - const bool enableOOSLog) : + const SimulationDebugOptions debugOptions) : m_SimContext{terrain, unitManager}, m_ComponentManager{m_SimContext, cx}, m_InitAttributes{cx.GetGeneralJSContext()}, m_MapSettings{cx.GetGeneralJSContext()}, // Tests won't have config initialised - m_EnableOOSLog{enableOOSLog || CConfigDB::GetIfInitialised("ooslog", false)}, - m_EnableSerializationTest{CConfigDB::GetIfInitialised("serializationtest", false)}, + m_EnableOOSLog{debugOptions.oosLog || CConfigDB::GetIfInitialised("ooslog", false)}, + m_EnableSerializationTest{ + std::holds_alternative(debugOptions.test) || + CConfigDB::GetIfInitialised("serializationtest", false)}, // Handle bogus values of the arg - m_RejoinTestTurn{std::max(CConfigDB::GetIfInitialised("rejointest", -1), -1)} + m_RejoinTestTurn{[&] + { + const auto* rejoinTestOption{ + std::get_if(&debugOptions.test)}; + return rejoinTestOption ? rejoinTestOption->turn : + std::max(CConfigDB::GetIfInitialised("rejointest", -1), -1); + }()} { m_ComponentManager.LoadComponentTypes(); @@ -646,8 +654,8 @@ void CSimulation2Impl::DumpState() //////////////////////////////////////////////////////////////// CSimulation2::CSimulation2(CUnitManager* unitManager, ScriptContext& cx, CTerrain* terrain, - const bool enableOOSLog) : - m(std::make_unique(unitManager, cx, terrain, enableOOSLog)) + const SimulationDebugOptions debugOptions) : + m(std::make_unique(unitManager, cx, terrain, debugOptions)) { } @@ -655,16 +663,6 @@ CSimulation2::~CSimulation2() = default; // Forward all method calls to the appropriate CSimulation2Impl/CComponentManager methods: -void CSimulation2::EnableSerializationTest() -{ - m->m_EnableSerializationTest = true; -} - -void CSimulation2::EnableRejoinTest(int rejoinTestTurn) -{ - m->m_RejoinTestTurn = rejoinTestTurn; -} - entity_id_t CSimulation2::AddEntity(const std::wstring& templateName) { return m->m_ComponentManager.AddEntity(templateName, m->m_ComponentManager.AllocateNewEntity()); diff --git a/source/simulation2/Simulation2.h b/source/simulation2/Simulation2.h index 39a9423869..078b4d3a7e 100644 --- a/source/simulation2/Simulation2.h +++ b/source/simulation2/Simulation2.h @@ -21,6 +21,7 @@ #include "lib/code_annotation.h" #include "lib/file/vfs/vfs_path.h" #include "lib/status.h" +#include "simulation2/system/DebugOptions.h" #include "simulation2/system/Entity.h" #include @@ -56,12 +57,9 @@ public: // TODO: CUnitManager should probably be handled automatically by this // module, but for now we'll have it passed in externally instead CSimulation2(CUnitManager* unitManager, ScriptContext& cx, CTerrain* terrain, - const bool enableOOSLog = false); + const SimulationDebugOptions debugOptions = {}); ~CSimulation2(); - void EnableSerializationTest(); - void EnableRejoinTest(int rejoinTestTurn); - /** * Load all scripts in the specified directory (non-recursively), * so they can register new component types and functions. This diff --git a/source/simulation2/system/DebugOptions.h b/source/simulation2/system/DebugOptions.h new file mode 100644 index 0000000000..5cbf810870 --- /dev/null +++ b/source/simulation2/system/DebugOptions.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2025 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#ifndef INCLUDED_SIMULATION_DEBUG_OPTIONS +#define INCLUDED_SIMULATION_DEBUG_OPTIONS + +#include + +struct SimulationDebugOptions +{ + struct SerializationTest {}; + struct RejoinTest + { + int turn; + }; + std::variant test; + bool oosLog{false}; +}; + +#endif // INCLUDED_SIMULATION_DEBUG_OPTIONS