From 0e3a6d811ca22c15330180cd0a7d644d3c016513 Mon Sep 17 00:00:00 2001 From: elexis Date: Mon, 11 Sep 2017 23:22:28 +0000 Subject: [PATCH] Move SavedGame ScriptFunctions to a new JS Interface, refs #4772. This was SVN commit r20166. --- source/gui/scripting/ScriptFunctions.cpp | 97 +------------- source/ps/scripting/JSInterface_SavedGame.cpp | 122 ++++++++++++++++++ source/ps/scripting/JSInterface_SavedGame.h | 37 ++++++ 3 files changed, 162 insertions(+), 94 deletions(-) create mode 100644 source/ps/scripting/JSInterface_SavedGame.cpp create mode 100644 source/ps/scripting/JSInterface_SavedGame.h diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index 6b159b9d83..7f881186b3 100644 --- a/source/gui/scripting/ScriptFunctions.cpp +++ b/source/gui/scripting/ScriptFunctions.cpp @@ -52,12 +52,12 @@ #include "ps/Profile.h" #include "ps/Pyrogenesis.h" #include "ps/Replay.h" -#include "ps/SavedGame.h" #include "ps/UserReport.h" #include "ps/World.h" #include "ps/scripting/JSInterface_ConfigDB.h" #include "ps/scripting/JSInterface_Console.h" #include "ps/scripting/JSInterface_Mod.h" +#include "ps/scripting/JSInterface_SavedGame.h" #include "ps/scripting/JSInterface_VFS.h" #include "ps/scripting/JSInterface_VisualReplay.h" #include "renderer/scripting/JSInterface_Renderer.h" @@ -226,11 +226,6 @@ void SetViewedPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int id) g_Game->SetViewedPlayerID(id); } -JS::Value GetEngineInfo(ScriptInterface::CxPrivate* pCxPrivate) -{ - return SavedGames::GetEngineInfo(*(pCxPrivate->pScriptInterface)); -} - JS::Value FindStunEndpoint(ScriptInterface::CxPrivate* pCxPrivate, int port) { return StunClient::FindStunEndpointHost(*(pCxPrivate->pScriptInterface), port); @@ -262,64 +257,6 @@ void StartGame(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs, g_Game->StartGame(&gameAttribs, ""); } -JS::Value StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name) -{ - // We need to be careful with different compartments and contexts. - // The GUI calls this function from the GUI context and expects the return value in the same context. - // The game we start from here creates another context and expects data in this context. - - JSContext* cxGui = pCxPrivate->pScriptInterface->GetContext(); - JSAutoRequest rq(cxGui); - - ENSURE(!g_NetServer); - ENSURE(!g_NetClient); - - ENSURE(!g_Game); - - // Load the saved game data from disk - JS::RootedValue guiContextMetadata(cxGui); - std::string savedState; - Status err = SavedGames::Load(name, *(pCxPrivate->pScriptInterface), &guiContextMetadata, savedState); - if (err < 0) - return JS::UndefinedValue(); - - g_Game = new CGame(); - - { - CSimulation2* sim = g_Game->GetSimulation2(); - JSContext* cxGame = sim->GetScriptInterface().GetContext(); - JSAutoRequest rq(cxGame); - - JS::RootedValue gameContextMetadata(cxGame, - sim->GetScriptInterface().CloneValueFromOtherContext(*(pCxPrivate->pScriptInterface), guiContextMetadata)); - JS::RootedValue gameInitAttributes(cxGame); - sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes); - - int playerID; - sim->GetScriptInterface().GetProperty(gameContextMetadata, "playerID", playerID); - - // Start the game - g_Game->SetPlayerID(playerID); - g_Game->StartGame(&gameInitAttributes, savedState); - } - - return guiContextMetadata; -} - -void SaveGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata) -{ - shared_ptr GUIMetadataClone = pCxPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); - if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) - LOGERROR("Failed to save game"); -} - -void SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata) -{ - shared_ptr GUIMetadataClone = pCxPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); - if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) - LOGERROR("Failed to save game"); -} - void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1) { ENSURE(g_NetClient); @@ -487,16 +424,6 @@ JS::Value GetAIs(ScriptInterface::CxPrivate* pCxPrivate) return ICmpAIManager::GetAIs(*(pCxPrivate->pScriptInterface)); } -JS::Value GetSavedGames(ScriptInterface::CxPrivate* pCxPrivate) -{ - return SavedGames::GetSavedGames(*(pCxPrivate->pScriptInterface)); -} - -bool DeleteSavedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& name) -{ - return SavedGames::DeleteSavedGame(name); -} - void OpenURL(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& url) { sys_open_url(url); @@ -655,16 +582,6 @@ void RewindTimeWarp(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) g_Game->GetTurnManager()->RewindTimeWarp(); } -void QuickSave(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) -{ - g_Game->GetTurnManager()->QuickSave(); -} - -void QuickLoad(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) -{ - g_Game->GetTurnManager()->QuickLoad(); -} - void SetBoundingBoxDebugOverlay(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool enabled) { ICmpSelectable::ms_EnableDebugOverlays = enabled; @@ -848,6 +765,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface) JSI_Console::RegisterScriptFunctions(scriptInterface); JSI_ConfigDB::RegisterScriptFunctions(scriptInterface); JSI_Mod::RegisterScriptFunctions(scriptInterface); + JSI_SavedGame::RegisterScriptFunctions(scriptInterface); JSI_Sound::RegisterScriptFunctions(scriptInterface); JSI_L10n::RegisterScriptFunctions(scriptInterface); JSI_Lobby::RegisterScriptFunctions(scriptInterface); @@ -890,18 +808,8 @@ void GuiScriptingInit(ScriptInterface& scriptInterface) scriptInterface.RegisterFunction("SendNetworkChat"); scriptInterface.RegisterFunction("SendNetworkReady"); scriptInterface.RegisterFunction("GetAIs"); - scriptInterface.RegisterFunction("GetEngineInfo"); scriptInterface.RegisterFunction("FindStunEndpoint"); - // Saved games - scriptInterface.RegisterFunction("StartSavedGame"); - scriptInterface.RegisterFunction("GetSavedGames"); - scriptInterface.RegisterFunction("DeleteSavedGame"); - scriptInterface.RegisterFunction("SaveGame"); - scriptInterface.RegisterFunction("SaveGamePrefix"); - scriptInterface.RegisterFunction("QuickSave"); - scriptInterface.RegisterFunction("QuickLoad"); - // Misc functions scriptInterface.RegisterFunction("SetCursor"); scriptInterface.RegisterFunction("IsVisualReplay"); @@ -909,6 +817,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface) scriptInterface.RegisterFunction("GetPlayerID"); scriptInterface.RegisterFunction("SetPlayerID"); scriptInterface.RegisterFunction("SetViewedPlayer"); + scriptInterface.RegisterFunction("OpenURL"); scriptInterface.RegisterFunction("GetMatchID"); scriptInterface.RegisterFunction("RestartInAtlas"); diff --git a/source/ps/scripting/JSInterface_SavedGame.cpp b/source/ps/scripting/JSInterface_SavedGame.cpp new file mode 100644 index 0000000000..5928eae3f8 --- /dev/null +++ b/source/ps/scripting/JSInterface_SavedGame.cpp @@ -0,0 +1,122 @@ +/* Copyright (C) 2017 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 . + */ + +#include "precompiled.h" + +#include "ps/scripting/JSInterface_SavedGame.h" + +#include "network/NetClient.h" +#include "network/NetServer.h" +#include "ps/CLogger.h" +#include "ps/Game.h" +#include "ps/SavedGame.h" +#include "simulation2/Simulation2.h" +#include "simulation2/system/TurnManager.h" + +JS::Value JSI_SavedGame::GetEngineInfo(ScriptInterface::CxPrivate* pCxPrivate) +{ + return SavedGames::GetEngineInfo(*(pCxPrivate->pScriptInterface)); +} + +JS::Value JSI_SavedGame::GetSavedGames(ScriptInterface::CxPrivate* pCxPrivate) +{ + return SavedGames::GetSavedGames(*(pCxPrivate->pScriptInterface)); +} + +bool JSI_SavedGame::DeleteSavedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& name) +{ + return SavedGames::DeleteSavedGame(name); +} + +void JSI_SavedGame::SaveGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata) +{ + shared_ptr GUIMetadataClone = pCxPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); + if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) + LOGERROR("Failed to save game"); +} + +void JSI_SavedGame::SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata) +{ + shared_ptr GUIMetadataClone = pCxPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); + if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) + LOGERROR("Failed to save game"); +} + +void JSI_SavedGame::QuickSave(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +{ + g_Game->GetTurnManager()->QuickSave(); +} + +void JSI_SavedGame::QuickLoad(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +{ + g_Game->GetTurnManager()->QuickLoad(); +} + +JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name) +{ + // We need to be careful with different compartments and contexts. + // The GUI calls this function from the GUI context and expects the return value in the same context. + // The game we start from here creates another context and expects data in this context. + + JSContext* cxGui = pCxPrivate->pScriptInterface->GetContext(); + JSAutoRequest rq(cxGui); + + ENSURE(!g_NetServer); + ENSURE(!g_NetClient); + + ENSURE(!g_Game); + + // Load the saved game data from disk + JS::RootedValue guiContextMetadata(cxGui); + std::string savedState; + Status err = SavedGames::Load(name, *(pCxPrivate->pScriptInterface), &guiContextMetadata, savedState); + if (err < 0) + return JS::UndefinedValue(); + + g_Game = new CGame(); + + { + CSimulation2* sim = g_Game->GetSimulation2(); + JSContext* cxGame = sim->GetScriptInterface().GetContext(); + JSAutoRequest rq(cxGame); + + JS::RootedValue gameContextMetadata(cxGame, + sim->GetScriptInterface().CloneValueFromOtherContext(*(pCxPrivate->pScriptInterface), guiContextMetadata)); + JS::RootedValue gameInitAttributes(cxGame); + sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes); + + int playerID; + sim->GetScriptInterface().GetProperty(gameContextMetadata, "playerID", playerID); + + g_Game->SetPlayerID(playerID); + g_Game->StartGame(&gameInitAttributes, savedState); + } + + return guiContextMetadata; +} + +void JSI_SavedGame::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +{ + scriptInterface.RegisterFunction("GetEngineInfo"); + scriptInterface.RegisterFunction("GetSavedGames"); + scriptInterface.RegisterFunction("DeleteSavedGame"); + scriptInterface.RegisterFunction("SaveGame"); + scriptInterface.RegisterFunction("SaveGamePrefix"); + 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 new file mode 100644 index 0000000000..1e00984da1 --- /dev/null +++ b/source/ps/scripting/JSInterface_SavedGame.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2017 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_JSI_SAVEDGAME +#define INCLUDED_JSI_SAVEDGAME + +#include "scriptinterface/ScriptInterface.h" + +namespace JSI_SavedGame +{ + JS::Value GetEngineInfo(ScriptInterface::CxPrivate* pCxPrivate); + JS::Value GetSavedGames(ScriptInterface::CxPrivate* pCxPrivate); + 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 QuickLoad(ScriptInterface::CxPrivate* pCxPrivate); + JS::Value StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name); + + void RegisterScriptFunctions(const ScriptInterface& scriptInterface); +} + +#endif