diff --git a/source/ps/scripting/JSInterface_SavedGame.cpp b/source/ps/scripting/JSInterface_SavedGame.cpp index ba60cefadf..d6d97463bf 100644 --- a/source/ps/scripting/JSInterface_SavedGame.cpp +++ b/source/ps/scripting/JSInterface_SavedGame.cpp @@ -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 @@ -19,6 +19,7 @@ #include "JSInterface_SavedGame.h" +#include "gui/GUIManager.h" #include "lib/debug.h" #include "network/NetClient.h" #include "network/NetServer.h" @@ -80,11 +81,32 @@ void QuickSave(JS::HandleValue GUIMetadata) void QuickLoad() { if (g_NetServer || g_NetClient) + { LOGERROR("Can't load quicksave during multiplayer!"); - else if (g_Game) - g_Game->GetTurnManager()->QuickLoad(); - else + return; + } + if (!g_Game) + { LOGERROR("Can't load quicksave if game is not running!"); + return; + } + + const std::optional maybeMetadata{g_Game->GetTurnManager()->TryQuickLoad()}; + + if (!g_GUI || !maybeMetadata.has_value()) + return; + + const ScriptRequest rq{g_Game->GetSimulation2()->GetScriptInterface()}; + JS::RootedValue metadata{rq.cx, maybeMetadata.value()}; + + // Provide a copy, so that GUI components don't have to clone to get mutable objects + JS::RootedValue quickSaveMetadataClone(rq.cx, Script::DeepCopy(rq, metadata)); + + JS::RootedValueArray<1> paramData(rq.cx); + paramData[0].set(quickSaveMetadataClone); + g_GUI->SendEventToAll(CTurnManager::EventNameSavegameLoaded, paramData); + + LOGMESSAGERENDER("Quickloaded game"); } JS::Value LoadSavedGameMetadata(const ScriptInterface& scriptInterface, const std::wstring& name) diff --git a/source/simulation2/system/TurnManager.cpp b/source/simulation2/system/TurnManager.cpp index d8dc7df5fe..c45ccdcc59 100644 --- a/source/simulation2/system/TurnManager.cpp +++ b/source/simulation2/system/TurnManager.cpp @@ -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 @@ -19,7 +19,6 @@ #include "TurnManager.h" -#include "gui/GUIManager.h" #include "lib/debug.h" #include "maths/MathUtil.h" #include "ps/CLogger.h" @@ -309,37 +308,25 @@ void CTurnManager::QuickSave(JS::HandleValue GUIMetadata) LOGMESSAGERENDER("Quicksaved game"); } -void CTurnManager::QuickLoad() +std::optional CTurnManager::TryQuickLoad() { PROFILE2("QuickLoad"); if (m_QuickSaveState.empty()) { LOGERROR("Cannot quickload game - no game was quicksaved"); - return; + return std::nullopt; } std::stringstream stream(m_QuickSaveState); if (!m_Simulation2.DeserializeState(stream)) { LOGERROR("Failed to quickload game"); - return; + return std::nullopt; } // See RewindTimeWarp ResetState(1, m_CommandDelay); - if (!g_GUI) - return; - - ScriptRequest rq(m_Simulation2.GetScriptInterface()); - - // Provide a copy, so that GUI components don't have to clone to get mutable objects - JS::RootedValue quickSaveMetadataClone(rq.cx, Script::DeepCopy(rq, m_QuickSaveMetadata)); - - JS::RootedValueArray<1> paramData(rq.cx); - paramData[0].set(quickSaveMetadataClone); - g_GUI->SendEventToAll(EventNameSavegameLoaded, paramData); - - LOGMESSAGERENDER("Quickloaded game"); + return m_QuickSaveMetadata; } diff --git a/source/simulation2/system/TurnManager.h b/source/simulation2/system/TurnManager.h index b4a724dc99..c6826b1947 100644 --- a/source/simulation2/system/TurnManager.h +++ b/source/simulation2/system/TurnManager.h @@ -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 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -87,6 +88,8 @@ class CTurnManager { NONCOPYABLE(CTurnManager); public: + static const CStr EventNameSavegameLoaded; + /** * Construct for a given network session ID. */ @@ -154,7 +157,7 @@ public: void RewindTimeWarp(); void QuickSave(JS::HandleValue GUIMetadata); - void QuickLoad(); + std::optional TryQuickLoad(); u32 GetCurrentTurn() const { return m_CurrentTurn; } @@ -216,8 +219,6 @@ protected: u32 m_FinalTurn; private: - static const CStr EventNameSavegameLoaded; - size_t m_TimeWarpNumTurns; // 0 if disabled std::list m_TimeWarpStates; std::string m_QuickSaveState; // TODO: should implement a proper disk-based quicksave system diff --git a/source/tools/lint/cppcheck/suppressions-list.txt b/source/tools/lint/cppcheck/suppressions-list.txt index 20c3cda2a2..34f05f8d81 100644 --- a/source/tools/lint/cppcheck/suppressions-list.txt +++ b/source/tools/lint/cppcheck/suppressions-list.txt @@ -66,5 +66,6 @@ unknownMacro:source/lib/sysdep/os/win/wposix/wutsname.cpp unknownMacro:source/ps/CStr.cpp uninitvar:source/ps/Game.cpp:246 +uninitvar:source/ps/scripting/JSInterface_SavedGame.cpp:149 danglingLifetime:source/renderer/backend/gl/Device.cpp