From 003d588d139a789efa4d717f75aba8995114a0c5 Mon Sep 17 00:00:00 2001 From: elexis Date: Wed, 18 Sep 2019 00:17:56 +0000 Subject: [PATCH] Happy savegame hack removal following e0ea53a8ee, refs #2030. Simply pass the JS value to the Save functions instead of letting those obtain the data later from the topmost GUI page. The JS hack incidence appears to be unused since 4b1297b328. Differential Revision: https://code.wildfiregames.com/D2302 Tested on: clang 8.0.1, Jenkins This was SVN commit r22922. --- .../data/mods/public/gui/savegame/save.js | 7 ---- .../mods/public/gui/session/hotkeys/misc.xml | 2 +- .../data/mods/public/gui/session/session.xml | 4 ++ source/gui/GUIManager.cpp | 24 ----------- source/gui/GUIManager.h | 7 ---- source/ps/scripting/JSInterface_SavedGame.cpp | 14 +++++-- source/ps/scripting/JSInterface_SavedGame.h | 4 +- source/simulation2/system/TurnManager.cpp | 40 +++++++++++++------ source/simulation2/system/TurnManager.h | 6 +-- 9 files changed, 48 insertions(+), 60 deletions(-) diff --git a/binaries/data/mods/public/gui/savegame/save.js b/binaries/data/mods/public/gui/savegame/save.js index 1325e7750e..4814034e1d 100644 --- a/binaries/data/mods/public/gui/savegame/save.js +++ b/binaries/data/mods/public/gui/savegame/save.js @@ -82,10 +82,3 @@ function closeSave() { Engine.PopGuiPage(); } - -// HACK: Engine.SaveGame* expects this function to be defined on the current page. -// That's why we have to pass the data to this page even if we don't need it. -function getSavedGameData() -{ - return g_SavedGameData; -} diff --git a/binaries/data/mods/public/gui/session/hotkeys/misc.xml b/binaries/data/mods/public/gui/session/hotkeys/misc.xml index 28c3b17288..89f96d65be 100644 --- a/binaries/data/mods/public/gui/session/hotkeys/misc.xml +++ b/binaries/data/mods/public/gui/session/hotkeys/misc.xml @@ -56,7 +56,7 @@ - Engine.QuickSave(); + Engine.QuickSave(getSavedGameData()); diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml index dbecc7b75f..a41d83ab79 100644 --- a/binaries/data/mods/public/gui/session/session.xml +++ b/binaries/data/mods/public/gui/session/session.xml @@ -15,6 +15,10 @@ onWindowResized(); + + restoreSavedGameData(arguments[0]); + + onSimulationUpdate(); diff --git a/source/gui/GUIManager.cpp b/source/gui/GUIManager.cpp index f6fb9f479c..be59e24dc3 100644 --- a/source/gui/GUIManager.cpp +++ b/source/gui/GUIManager.cpp @@ -290,30 +290,6 @@ void CGUIManager::ResetCursor() g_CursorName = g_DefaultCursor; } -std::string CGUIManager::GetSavedGameData() -{ - shared_ptr scriptInterface = top()->GetScriptInterface(); - JSContext* cx = scriptInterface->GetContext(); - JSAutoRequest rq(cx); - - JS::RootedValue data(cx); - JS::RootedValue global(cx, top()->GetGlobalObject()); - scriptInterface->CallFunction(global, "getSavedGameData", &data); - return scriptInterface->StringifyJSON(&data, false); -} - -void CGUIManager::RestoreSavedGameData(const std::string& jsonData) -{ - shared_ptr scriptInterface = top()->GetScriptInterface(); - JSContext* cx = scriptInterface->GetContext(); - JSAutoRequest rq(cx); - - JS::RootedValue global(cx, top()->GetGlobalObject()); - JS::RootedValue dataVal(cx); - scriptInterface->ParseJSON(jsonData, &dataVal); - scriptInterface->CallFunctionVoid(global, "restoreSavedGameData", dataVal); -} - InReaction CGUIManager::HandleEvent(const SDL_Event_* ev) { // We want scripts to have access to the raw input events, so they can do complex diff --git a/source/gui/GUIManager.h b/source/gui/GUIManager.h index 7cd9d2e24f..9dacb601bf 100644 --- a/source/gui/GUIManager.h +++ b/source/gui/GUIManager.h @@ -122,13 +122,6 @@ public: */ void UpdateResolution(); - /** - * Calls the current page's script function getSavedGameData() and returns the result. - */ - std::string GetSavedGameData(); - - void RestoreSavedGameData(const std::string& jsonData); - /** * Check if a template with this name exists */ diff --git a/source/ps/scripting/JSInterface_SavedGame.cpp b/source/ps/scripting/JSInterface_SavedGame.cpp index 47c76650ec..1c3fff57b7 100644 --- a/source/ps/scripting/JSInterface_SavedGame.cpp +++ b/source/ps/scripting/JSInterface_SavedGame.cpp @@ -52,14 +52,20 @@ void JSI_SavedGame::SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, const LOGERROR("Failed to save game"); } -void JSI_SavedGame::QuickSave(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_SavedGame::QuickSave(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), JS::HandleValue GUIMetadata) { - g_Game->GetTurnManager()->QuickSave(); + if (g_Game) + g_Game->GetTurnManager()->QuickSave(GUIMetadata); + else + LOGERROR("Can't store quicksave if game is not running!"); } void JSI_SavedGame::QuickLoad(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) { - g_Game->GetTurnManager()->QuickLoad(); + if (g_Game) + g_Game->GetTurnManager()->QuickLoad(); + else + LOGERROR("Can't load quicksave if game is not running!"); } JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name) @@ -111,7 +117,7 @@ void JSI_SavedGame::RegisterScriptFunctions(const ScriptInterface& scriptInterfa scriptInterface.RegisterFunction("DeleteSavedGame"); scriptInterface.RegisterFunction("SaveGame"); scriptInterface.RegisterFunction("SaveGamePrefix"); - scriptInterface.RegisterFunction("QuickSave"); + scriptInterface.RegisterFunction("QuickSave"); scriptInterface.RegisterFunction("QuickLoad"); scriptInterface.RegisterFunction("StartSavedGame"); } diff --git a/source/ps/scripting/JSInterface_SavedGame.h b/source/ps/scripting/JSInterface_SavedGame.h index 7eed8f992b..532947ef28 100644 --- a/source/ps/scripting/JSInterface_SavedGame.h +++ b/source/ps/scripting/JSInterface_SavedGame.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -26,7 +26,7 @@ namespace JSI_SavedGame bool DeleteSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name); void SaveGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata); void SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata); - void QuickSave(ScriptInterface::CxPrivate* pCxPrivate); + void QuickSave(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue GUIMetadata); void QuickLoad(ScriptInterface::CxPrivate* pCxPrivate); JS::Value StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name); diff --git a/source/simulation2/system/TurnManager.cpp b/source/simulation2/system/TurnManager.cpp index d147eb04c3..c9965ad7f7 100644 --- a/source/simulation2/system/TurnManager.cpp +++ b/source/simulation2/system/TurnManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -43,7 +43,8 @@ const int COMMAND_DELAY = 2; CTurnManager::CTurnManager(CSimulation2& simulation, u32 defaultTurnLength, int clientId, IReplayLogger& replay) : m_Simulation2(simulation), m_CurrentTurn(0), m_ReadyTurn(1), m_TurnLength(defaultTurnLength), m_PlayerId(-1), m_ClientId(clientId), m_DeltaSimTime(0), m_HasSyncError(false), m_Replay(replay), - m_FinalTurn(std::numeric_limits::max()), m_TimeWarpNumTurns(0) + m_FinalTurn(std::numeric_limits::max()), m_TimeWarpNumTurns(0), + m_QuickSaveMetadata(m_Simulation2.GetScriptInterface().GetContext()) { // When we are on turn n, we schedule new commands for n+2. // We know that all other clients have finished scheduling commands for n (else we couldn't have got here). @@ -290,7 +291,7 @@ void CTurnManager::RewindTimeWarp() ResetState(0, 1); } -void CTurnManager::QuickSave() +void CTurnManager::QuickSave(JS::HandleValue GUIMetadata) { TIMER(L"QuickSave"); @@ -302,13 +303,21 @@ void CTurnManager::QuickSave() } m_QuickSaveState = stream.str(); - if (g_GUI) - m_QuickSaveMetadata = g_GUI->GetSavedGameData(); + + JSContext* cx = m_Simulation2.GetScriptInterface().GetContext(); + JSAutoRequest rq(cx); + + if (JS_StructuredClone(cx, GUIMetadata, &m_QuickSaveMetadata, nullptr, nullptr)) + { + m_Simulation2.GetScriptInterface().FreezeObject(m_QuickSaveMetadata, true); + } else - m_QuickSaveMetadata = std::string(); + { + LOGERROR("Could not copy savegame GUI metadata"); + m_QuickSaveMetadata = JS::UndefinedValue(); + } LOGMESSAGERENDER("Quicksaved game"); - } void CTurnManager::QuickLoad() @@ -328,11 +337,18 @@ void CTurnManager::QuickLoad() return; } - if (g_GUI && !m_QuickSaveMetadata.empty()) - g_GUI->RestoreSavedGameData(m_QuickSaveMetadata); - - LOGMESSAGERENDER("Quickloaded game"); - // See RewindTimeWarp ResetState(0, 1); + + if (!g_GUI) + return; + + JSContext* cx = m_Simulation2.GetScriptInterface().GetContext(); + JSAutoRequest rq(cx); + + JS::AutoValueArray<1> paramData(cx); + paramData[0].set(m_QuickSaveMetadata); + g_GUI->SendEventToAll("SavegameLoaded", paramData); + + LOGMESSAGERENDER("Quickloaded game"); } diff --git a/source/simulation2/system/TurnManager.h b/source/simulation2/system/TurnManager.h index 92d228785d..10bf4372cd 100644 --- a/source/simulation2/system/TurnManager.h +++ b/source/simulation2/system/TurnManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -130,7 +130,7 @@ public: */ void RewindTimeWarp(); - void QuickSave(); + void QuickSave(JS::HandleValue GUIMetadata); void QuickLoad(); u32 GetCurrentTurn() { return m_CurrentTurn; } @@ -189,7 +189,7 @@ private: size_t m_TimeWarpNumTurns; // 0 if disabled std::list m_TimeWarpStates; std::string m_QuickSaveState; // TODO: should implement a proper disk-based quicksave system - std::string m_QuickSaveMetadata; + JS::PersistentRootedValue m_QuickSaveMetadata; }; #endif // INCLUDED_TURNMANAGER