Split off StructuredClone from ScriptInterface
Follows 34b1920e7b
.
This separates StructuredClone & DeepCopy logic into its own header,
reducing the size of the monolithic ScriptInterface header.
Differential Revision: https://code.wildfiregames.com/D3922
This was SVN commit r25419.
This commit is contained in:
parent
ad62707eef
commit
6fbf036ae4
@ -225,7 +225,7 @@ double CMapGeneratorWorker::GetMicroseconds()
|
||||
return JS_Now();
|
||||
}
|
||||
|
||||
ScriptInterface::StructuredClone CMapGeneratorWorker::GetResults()
|
||||
Script::StructuredClone CMapGeneratorWorker::GetResults()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_WorkerMutex);
|
||||
return m_MapData;
|
||||
@ -235,7 +235,7 @@ void CMapGeneratorWorker::ExportMap(JS::HandleValue data)
|
||||
{
|
||||
// Copy results
|
||||
std::lock_guard<std::mutex> lock(m_WorkerMutex);
|
||||
m_MapData = m_ScriptInterface->WriteStructuredClone(data);
|
||||
m_MapData = Script::WriteStructuredClone(ScriptRequest(m_ScriptInterface), data);
|
||||
m_Progress = 0;
|
||||
}
|
||||
|
||||
@ -422,7 +422,7 @@ int CMapGenerator::GetProgress()
|
||||
return m_Worker->GetProgress();
|
||||
}
|
||||
|
||||
ScriptInterface::StructuredClone CMapGenerator::GetResults()
|
||||
Script::StructuredClone CMapGenerator::GetResults()
|
||||
{
|
||||
return m_Worker->GetResults();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "lib/posix/posix_pthread.h"
|
||||
#include "ps/FileIo.h"
|
||||
#include "ps/TemplateLoader.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
|
||||
@ -67,7 +67,7 @@ public:
|
||||
*
|
||||
* @return StructuredClone containing map data
|
||||
*/
|
||||
ScriptInterface::StructuredClone GetResults();
|
||||
Script::StructuredClone GetResults();
|
||||
|
||||
private:
|
||||
CMapGeneratorWorker* m_Worker;
|
||||
@ -110,7 +110,7 @@ public:
|
||||
*
|
||||
* @return StructuredClone containing map data
|
||||
*/
|
||||
ScriptInterface::StructuredClone GetResults();
|
||||
Script::StructuredClone GetResults();
|
||||
|
||||
/**
|
||||
* Set initial seed, callback data.
|
||||
@ -196,7 +196,7 @@ private:
|
||||
/**
|
||||
* Result of the mapscript generation including terrain, entities and environment settings.
|
||||
*/
|
||||
ScriptInterface::StructuredClone m_MapData;
|
||||
Script::StructuredClone m_MapData;
|
||||
|
||||
/**
|
||||
* Deterministic random number generator.
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "renderer/SkyManager.h"
|
||||
#include "renderer/WaterManager.h"
|
||||
#include "scriptinterface/ScriptContext.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpCinemaManager.h"
|
||||
#include "simulation2/components/ICmpGarrisonHolder.h"
|
||||
@ -1294,11 +1295,11 @@ int CMapReader::GenerateMap()
|
||||
else if (progress == 0)
|
||||
{
|
||||
// Finished, get results as StructuredClone object, which must be read to obtain the JS::Value
|
||||
ScriptInterface::StructuredClone results = m_MapGen->GetResults();
|
||||
Script::StructuredClone results = m_MapGen->GetResults();
|
||||
|
||||
// Parse data into simulation context
|
||||
JS::RootedValue data(rq.cx);
|
||||
pSimulation2->GetScriptInterface().ReadStructuredClone(results, &data);
|
||||
Script::ReadStructuredClone(rq, results, &data);
|
||||
|
||||
if (data.isUndefined())
|
||||
{
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptContext.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
CGUIManager* g_GUI = nullptr;
|
||||
|
||||
@ -88,17 +89,18 @@ void CGUIManager::SwitchPage(const CStrW& pageName, ScriptInterface* srcScriptIn
|
||||
{
|
||||
// The page stack is cleared (including the script context where initData came from),
|
||||
// therefore we have to clone initData.
|
||||
ScriptRequest rq(srcScriptInterface);
|
||||
|
||||
ScriptInterface::StructuredClone initDataClone;
|
||||
Script::StructuredClone initDataClone;
|
||||
if (!initData.isUndefined())
|
||||
initDataClone = srcScriptInterface->WriteStructuredClone(initData);
|
||||
initDataClone = Script::WriteStructuredClone(rq, initData);
|
||||
|
||||
m_PageStack.clear();
|
||||
|
||||
PushPage(pageName, initDataClone, JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
void CGUIManager::PushPage(const CStrW& pageName, ScriptInterface::StructuredClone initData, JS::HandleValue callbackFunction)
|
||||
void CGUIManager::PushPage(const CStrW& pageName, Script::StructuredClone initData, JS::HandleValue callbackFunction)
|
||||
{
|
||||
// Store the callback handler in the current GUI page before opening the new one
|
||||
if (!m_PageStack.empty() && !callbackFunction.isUndefined())
|
||||
@ -110,7 +112,7 @@ void CGUIManager::PushPage(const CStrW& pageName, ScriptInterface::StructuredClo
|
||||
m_PageStack.back().LoadPage(m_ScriptContext);
|
||||
}
|
||||
|
||||
void CGUIManager::PopPage(ScriptInterface::StructuredClone args)
|
||||
void CGUIManager::PopPage(Script::StructuredClone args)
|
||||
{
|
||||
if (m_PageStack.size() < 2)
|
||||
{
|
||||
@ -122,7 +124,7 @@ void CGUIManager::PopPage(ScriptInterface::StructuredClone args)
|
||||
m_PageStack.back().PerformCallbackFunction(args);
|
||||
}
|
||||
|
||||
CGUIManager::SGUIPage::SGUIPage(const CStrW& pageName, const ScriptInterface::StructuredClone initData)
|
||||
CGUIManager::SGUIPage::SGUIPage(const CStrW& pageName, const Script::StructuredClone initData)
|
||||
: m_Name(pageName), initData(initData), inputs(), gui(), callbackFunction()
|
||||
{
|
||||
}
|
||||
@ -130,7 +132,7 @@ CGUIManager::SGUIPage::SGUIPage(const CStrW& pageName, const ScriptInterface::St
|
||||
void CGUIManager::SGUIPage::LoadPage(shared_ptr<ScriptContext> scriptContext)
|
||||
{
|
||||
// If we're hotloading then try to grab some data from the previous page
|
||||
ScriptInterface::StructuredClone hotloadData;
|
||||
Script::StructuredClone hotloadData;
|
||||
if (gui)
|
||||
{
|
||||
shared_ptr<ScriptInterface> scriptInterface = gui->GetScriptInterface();
|
||||
@ -139,7 +141,7 @@ void CGUIManager::SGUIPage::LoadPage(shared_ptr<ScriptContext> scriptContext)
|
||||
JS::RootedValue global(rq.cx, rq.globalValue());
|
||||
JS::RootedValue hotloadDataVal(rq.cx);
|
||||
ScriptFunction::Call(rq, global, "getHotloadData", &hotloadDataVal);
|
||||
hotloadData = scriptInterface->WriteStructuredClone(hotloadDataVal);
|
||||
hotloadData = Script::WriteStructuredClone(rq, hotloadDataVal);
|
||||
}
|
||||
|
||||
g_CursorName = g_DefaultCursor;
|
||||
@ -207,10 +209,10 @@ void CGUIManager::SGUIPage::LoadPage(shared_ptr<ScriptContext> scriptContext)
|
||||
JS::RootedValue global(rq.cx, rq.globalValue());
|
||||
|
||||
if (initData)
|
||||
scriptInterface->ReadStructuredClone(initData, &initDataVal);
|
||||
Script::ReadStructuredClone(rq, initData, &initDataVal);
|
||||
|
||||
if (hotloadData)
|
||||
scriptInterface->ReadStructuredClone(hotloadData, &hotloadDataVal);
|
||||
Script::ReadStructuredClone(rq, hotloadData, &hotloadDataVal);
|
||||
|
||||
if (scriptInterface->HasProperty(global, "init") &&
|
||||
!ScriptFunction::CallVoid(rq, global, "init", initDataVal, hotloadDataVal))
|
||||
@ -236,7 +238,7 @@ void CGUIManager::SGUIPage::SetCallbackFunction(ScriptInterface& scriptInterface
|
||||
callbackFunction = std::make_shared<JS::PersistentRootedValue>(scriptInterface.GetGeneralJSContext(), callbackFunc);
|
||||
}
|
||||
|
||||
void CGUIManager::SGUIPage::PerformCallbackFunction(ScriptInterface::StructuredClone args)
|
||||
void CGUIManager::SGUIPage::PerformCallbackFunction(Script::StructuredClone args)
|
||||
{
|
||||
if (!callbackFunction)
|
||||
return;
|
||||
@ -253,7 +255,7 @@ void CGUIManager::SGUIPage::PerformCallbackFunction(ScriptInterface::StructuredC
|
||||
|
||||
JS::RootedValue argVal(rq.cx);
|
||||
if (args)
|
||||
scriptInterface->ReadStructuredClone(args, &argVal);
|
||||
Script::ReadStructuredClone(rq, args, &argVal);
|
||||
|
||||
JS::RootedValueVector paramData(rq.cx);
|
||||
ignore_result(paramData.append(argVal));
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "lib/input.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/TemplateLoader.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
@ -68,13 +68,13 @@ public:
|
||||
* user inputs.
|
||||
* If given, the callbackHandler function will be executed once this page is closed.
|
||||
*/
|
||||
void PushPage(const CStrW& pageName, ScriptInterface::StructuredClone initData, JS::HandleValue callbackFunc);
|
||||
void PushPage(const CStrW& pageName, Script::StructuredClone initData, JS::HandleValue callbackFunc);
|
||||
|
||||
/**
|
||||
* Unload the currently active GUI page, and make the previous page active.
|
||||
* (There must be at least two pages when you call this.)
|
||||
*/
|
||||
void PopPage(ScriptInterface::StructuredClone args);
|
||||
void PopPage(Script::StructuredClone args);
|
||||
|
||||
/**
|
||||
* Called when a file has been modified, to hotload changes.
|
||||
@ -131,7 +131,7 @@ private:
|
||||
/**
|
||||
* Initializes the data that will be used to create the CGUI page one or multiple times (hotloading).
|
||||
*/
|
||||
SGUIPage(const CStrW& pageName, const ScriptInterface::StructuredClone initData);
|
||||
SGUIPage(const CStrW& pageName, const Script::StructuredClone initData);
|
||||
|
||||
/**
|
||||
* Create the CGUI with it's own ScriptInterface. Deletes the previous CGUI if it existed.
|
||||
@ -146,11 +146,11 @@ private:
|
||||
/**
|
||||
* Execute the stored callback function with the given arguments.
|
||||
*/
|
||||
void PerformCallbackFunction(ScriptInterface::StructuredClone args);
|
||||
void PerformCallbackFunction(Script::StructuredClone args);
|
||||
|
||||
CStrW m_Name;
|
||||
std::unordered_set<VfsPath> inputs; // for hotloading
|
||||
ScriptInterface::StructuredClone initData; // data to be passed to the init() function
|
||||
Script::StructuredClone initData; // data to be passed to the init() function
|
||||
shared_ptr<CGUI> gui; // the actual GUI page
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -24,15 +24,15 @@
|
||||
#include "gui/ObjectBases/IGUIObject.h"
|
||||
#include "ps/GameSetup/Config.h"
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
namespace JSI_GUIManager
|
||||
{
|
||||
// Note that the initData argument may only contain clonable data.
|
||||
// Functions aren't supported for example!
|
||||
void PushGuiPage(const ScriptInterface& scriptInterface, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction)
|
||||
void PushGuiPage(const ScriptRequest& rq, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction)
|
||||
{
|
||||
g_GUI->PushPage(name, scriptInterface.WriteStructuredClone(initData), callbackFunction);
|
||||
g_GUI->PushPage(name, Script::WriteStructuredClone(rq, initData), callbackFunction);
|
||||
}
|
||||
|
||||
void SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData)
|
||||
@ -40,16 +40,15 @@ void SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstrin
|
||||
g_GUI->SwitchPage(name, pCmptPrivate->pScriptInterface, initData);
|
||||
}
|
||||
|
||||
void PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue args)
|
||||
void PopGuiPage(const ScriptRequest& rq, JS::HandleValue args)
|
||||
{
|
||||
if (g_GUI->GetPageCount() < 2)
|
||||
{
|
||||
ScriptRequest rq(pCmptPrivate->pScriptInterface);
|
||||
ScriptException::Raise(rq, "Can't pop GUI pages when less than two pages are opened!");
|
||||
return;
|
||||
}
|
||||
|
||||
g_GUI->PopPage(pCmptPrivate->pScriptInterface->WriteStructuredClone(args));
|
||||
g_GUI->PopPage(Script::WriteStructuredClone(rq, args));
|
||||
}
|
||||
|
||||
std::wstring SetCursor(const std::wstring& name)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ps/GameSetup/GameSetup.h"
|
||||
#include "ps/Hotkey.h"
|
||||
#include "ps/XML/Xeromyces.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -63,7 +64,7 @@ public:
|
||||
JS::RootedValue val(rq.cx);
|
||||
scriptInterface.CreateObject(rq, &val);
|
||||
|
||||
ScriptInterface::StructuredClone data = scriptInterface.WriteStructuredClone(JS::NullHandleValue);
|
||||
Script::StructuredClone data = Script::WriteStructuredClone(rq, JS::NullHandleValue);
|
||||
g_GUI->PushPage(L"event/page_event.xml", data, JS::UndefinedHandleValue);
|
||||
|
||||
const ScriptInterface& pageScriptInterface = *(g_GUI->GetActiveGUI()->GetScriptInterface());
|
||||
@ -127,7 +128,7 @@ public:
|
||||
JS::RootedValue val(rq.cx);
|
||||
scriptInterface.CreateObject(rq, &val);
|
||||
|
||||
ScriptInterface::StructuredClone data = scriptInterface.WriteStructuredClone(JS::NullHandleValue);
|
||||
Script::StructuredClone data = Script::WriteStructuredClone(rq, JS::NullHandleValue);
|
||||
g_GUI->PushPage(L"hotkey/page_hotkey.xml", data, JS::UndefinedHandleValue);
|
||||
|
||||
// Press 'a'.
|
||||
|
@ -20,7 +20,8 @@
|
||||
|
||||
#include "scriptinterface/ScriptTypes.h"
|
||||
|
||||
class ScriptInterface;
|
||||
class ScriptRequest;
|
||||
|
||||
namespace StunClient {
|
||||
struct StunEndpoint;
|
||||
}
|
||||
@ -58,8 +59,8 @@ public:
|
||||
virtual JS::Value GUIGetBoardList(const ScriptInterface& scriptInterface) = 0;
|
||||
virtual JS::Value GUIGetProfile(const ScriptInterface& scriptInterface) = 0;
|
||||
|
||||
virtual JS::Value GuiPollNewMessages(const ScriptInterface& scriptInterface) = 0;
|
||||
virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface) = 0;
|
||||
virtual JS::Value GuiPollNewMessages(const ScriptInterface& guiInterface) = 0;
|
||||
virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& guiInterface) = 0;
|
||||
virtual bool GuiPollHasPlayerListUpdate() = 0;
|
||||
|
||||
virtual void SendMUCMessage(const std::string& message) = 0;
|
||||
|
@ -34,8 +34,8 @@
|
||||
#include "ps/ConfigDB.h"
|
||||
#include "ps/GUID.h"
|
||||
#include "ps/Pyrogenesis.h"
|
||||
#include "scriptinterface/ScriptExtraHeaders.h" // StructuredClone
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -734,7 +734,7 @@ bool XmppClient::GuiPollHasPlayerListUpdate()
|
||||
return hasUpdate;
|
||||
}
|
||||
|
||||
JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& scriptInterface)
|
||||
JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& guiInterface)
|
||||
{
|
||||
if ((m_isConnected && !m_initialLoadComplete) || m_GuiMessageQueue.empty())
|
||||
return JS::UndefinedValue();
|
||||
@ -765,8 +765,8 @@ JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& scriptInterface)
|
||||
if (level != "room-message" && level != "private-message")
|
||||
continue;
|
||||
|
||||
JS::RootedValue historicMessage(rq.cx);
|
||||
if (JS_StructuredClone(rq.cx, rootedMessage, &historicMessage, nullptr, nullptr))
|
||||
JS::RootedValue historicMessage(rq.cx, Script::DeepCopy(rq, rootedMessage));
|
||||
if (true)
|
||||
{
|
||||
m_ScriptInterface->SetProperty(historicMessage, "historic", true);
|
||||
m_ScriptInterface->FreezeObject(historicMessage, true);
|
||||
@ -778,10 +778,10 @@ JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& scriptInterface)
|
||||
m_GuiMessageQueue.clear();
|
||||
|
||||
// Copy the messages over to the caller script interface.
|
||||
return scriptInterface.CloneValueFromOtherCompartment(*m_ScriptInterface, messages);
|
||||
return Script::CloneValueFromOtherCompartment(guiInterface, *m_ScriptInterface, messages);
|
||||
}
|
||||
|
||||
JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInterface)
|
||||
JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& guiInterface)
|
||||
{
|
||||
if (m_HistoricGuiMessages.empty())
|
||||
return JS::UndefinedValue();
|
||||
@ -796,7 +796,7 @@ JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInter
|
||||
m_ScriptInterface->SetPropertyInt(messages, j++, message);
|
||||
|
||||
// Copy the messages over to the caller script interface.
|
||||
return scriptInterface.CloneValueFromOtherCompartment(*m_ScriptInterface, messages);
|
||||
return Script::CloneValueFromOtherCompartment(guiInterface, *m_ScriptInterface, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ScriptInterface;
|
||||
class ScriptRequest;
|
||||
|
||||
namespace glooxwrapper
|
||||
{
|
||||
@ -159,8 +159,8 @@ protected:
|
||||
virtual void handleSessionInitiation(glooxwrapper::Jingle::Session& session, const glooxwrapper::Jingle::Session::Jingle& jingle);
|
||||
|
||||
public:
|
||||
JS::Value GuiPollNewMessages(const ScriptInterface& scriptInterface);
|
||||
JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface);
|
||||
JS::Value GuiPollNewMessages(const ScriptInterface& guiInterface);
|
||||
JS::Value GuiPollHistoricMessages(const ScriptInterface& guiInterface);
|
||||
bool GuiPollHasPlayerListUpdate();
|
||||
void SendMUCMessage(const std::string& message);
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "ps/GUID.h"
|
||||
#include "ps/Util.h"
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include "third_party/encryption/pkcs5_pbkdf2.h"
|
||||
|
||||
@ -210,7 +210,7 @@ CStr GetPlayerGUID()
|
||||
return g_NetClient->GetGUID();
|
||||
}
|
||||
|
||||
JS::Value PollNetworkClient(const ScriptInterface& scriptInterface)
|
||||
JS::Value PollNetworkClient(const ScriptInterface& guiInterface)
|
||||
{
|
||||
if (!g_NetClient)
|
||||
return JS::UndefinedValue();
|
||||
@ -219,7 +219,7 @@ JS::Value PollNetworkClient(const ScriptInterface& scriptInterface)
|
||||
ScriptRequest rqNet(g_NetClient->GetScriptInterface());
|
||||
JS::RootedValue pollNet(rqNet.cx);
|
||||
g_NetClient->GuiPoll(&pollNet);
|
||||
return scriptInterface.CloneValueFromOtherCompartment(g_NetClient->GetScriptInterface(), pollNet);
|
||||
return Script::CloneValueFromOtherCompartment(guiInterface, g_NetClient->GetScriptInterface(), pollNet);
|
||||
}
|
||||
|
||||
void SendGameSetupMessage(const ScriptInterface& scriptInterface, JS::HandleValue attribs1)
|
||||
|
@ -31,12 +31,12 @@
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Mod.h"
|
||||
#include "ps/Pyrogenesis.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
|
||||
// TODO: we ought to check version numbers when loading files
|
||||
|
||||
Status SavedGames::SavePrefix(const CStrW& prefix, const CStrW& description, CSimulation2& simulation, const ScriptInterface::StructuredClone& guiMetadataClone)
|
||||
Status SavedGames::SavePrefix(const CStrW& prefix, const CStrW& description, CSimulation2& simulation, const Script::StructuredClone& guiMetadataClone)
|
||||
{
|
||||
// Determine the filename to save under
|
||||
const VfsPath basenameFormat(L"saves/" + prefix + L"-%04d");
|
||||
@ -51,7 +51,7 @@ Status SavedGames::SavePrefix(const CStrW& prefix, const CStrW& description, CSi
|
||||
return Save(filename.Filename().string(), description, simulation, guiMetadataClone);
|
||||
}
|
||||
|
||||
Status SavedGames::Save(const CStrW& name, const CStrW& description, CSimulation2& simulation, const ScriptInterface::StructuredClone& guiMetadataClone)
|
||||
Status SavedGames::Save(const CStrW& name, const CStrW& description, CSimulation2& simulation, const Script::StructuredClone& guiMetadataClone)
|
||||
{
|
||||
ScriptRequest rq(simulation.GetScriptInterface());
|
||||
|
||||
@ -93,7 +93,7 @@ Status SavedGames::Save(const CStrW& name, const CStrW& description, CSimulation
|
||||
"initAttributes", initAttributes);
|
||||
|
||||
JS::RootedValue guiMetadata(rq.cx);
|
||||
simulation.GetScriptInterface().ReadStructuredClone(guiMetadataClone, &guiMetadata);
|
||||
Script::ReadStructuredClone(rq, guiMetadataClone, &guiMetadata);
|
||||
|
||||
// get some camera data
|
||||
const CVector3D cameraPosition = g_Game->GetView()->GetCameraPosition();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -18,7 +18,8 @@
|
||||
#ifndef INCLUDED_SAVEDGAME
|
||||
#define INCLUDED_SAVEDGAME
|
||||
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
class CSimulation2;
|
||||
class CGUIManager;
|
||||
|
||||
@ -45,7 +46,7 @@ namespace SavedGames
|
||||
* @param guiMetadataClone if not NULL, store some UI-related data with the saved game
|
||||
* @return INFO::OK if successfully saved, else an error Status
|
||||
*/
|
||||
Status Save(const CStrW& name, const CStrW& description, CSimulation2& simulation, const ScriptInterface::StructuredClone& guiMetadataClone);
|
||||
Status Save(const CStrW& name, const CStrW& description, CSimulation2& simulation, const Script::StructuredClone& guiMetadataClone);
|
||||
|
||||
/**
|
||||
* Create new saved game archive with given prefix and simulation data
|
||||
@ -56,7 +57,7 @@ namespace SavedGames
|
||||
* @param guiMetadataClone if not NULL, store some UI-related data with the saved game
|
||||
* @return INFO::OK if successfully saved, else an error Status
|
||||
*/
|
||||
Status SavePrefix(const CStrW& prefix, const CStrW& description, CSimulation2& simulation, const ScriptInterface::StructuredClone& guiMetadataClone);
|
||||
Status SavePrefix(const CStrW& prefix, const CStrW& description, CSimulation2& simulation, const Script::StructuredClone& guiMetadataClone);
|
||||
|
||||
/**
|
||||
* Load saved game archive with the given name
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "ps/Replay.h"
|
||||
#include "ps/World.h"
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
#include "simulation2/system/TurnManager.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "soundmanager/SoundManager.h"
|
||||
@ -40,7 +40,7 @@ bool IsGameStarted()
|
||||
return g_Game;
|
||||
}
|
||||
|
||||
void StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs, int playerID)
|
||||
void StartGame(const ScriptInterface& guiInterface, JS::HandleValue attribs, int playerID)
|
||||
{
|
||||
ENSURE(!g_NetServer);
|
||||
ENSURE(!g_NetClient);
|
||||
@ -48,12 +48,11 @@ void StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attri
|
||||
|
||||
g_Game = new CGame(true);
|
||||
|
||||
// Convert from GUI script context to sim script context
|
||||
// Convert from GUI script context to sim script context/
|
||||
CSimulation2* sim = g_Game->GetSimulation2();
|
||||
ScriptRequest rqSim(sim->GetScriptInterface());
|
||||
|
||||
JS::RootedValue gameAttribs(rqSim.cx,
|
||||
sim->GetScriptInterface().CloneValueFromOtherCompartment(*(pCmptPrivate->pScriptInterface), attribs));
|
||||
JS::RootedValue gameAttribs(rqSim.cx, Script::CloneValueFromOtherCompartment(sim->GetScriptInterface(), guiInterface, attribs));
|
||||
|
||||
g_Game->SetPlayerID(playerID);
|
||||
g_Game->StartGame(&gameAttribs, "");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 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 @@
|
||||
#include "ps/Game.h"
|
||||
#include "ps/SavedGame.h"
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/system/TurnManager.h"
|
||||
|
||||
@ -41,16 +41,16 @@ bool DeleteSavedGame(const std::wstring& name)
|
||||
return SavedGames::DeleteSavedGame(name);
|
||||
}
|
||||
|
||||
void SaveGame(const ScriptInterface& scriptInterface, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata)
|
||||
void SaveGame(const ScriptRequest& rq, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata)
|
||||
{
|
||||
ScriptInterface::StructuredClone GUIMetadataClone = scriptInterface.WriteStructuredClone(GUIMetadata);
|
||||
Script::StructuredClone GUIMetadataClone = Script::WriteStructuredClone(rq, GUIMetadata);
|
||||
if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0)
|
||||
LOGERROR("Failed to save game");
|
||||
}
|
||||
|
||||
void SaveGamePrefix(const ScriptInterface& scriptInterface, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata)
|
||||
void SaveGamePrefix(const ScriptRequest& rq, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata)
|
||||
{
|
||||
ScriptInterface::StructuredClone GUIMetadataClone = scriptInterface.WriteStructuredClone(GUIMetadata);
|
||||
Script::StructuredClone GUIMetadataClone = Script::WriteStructuredClone(rq, GUIMetadata);
|
||||
if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0)
|
||||
LOGERROR("Failed to save game");
|
||||
}
|
||||
@ -101,8 +101,7 @@ JS::Value StartSavedGame(const ScriptInterface& scriptInterface, const std::wstr
|
||||
CSimulation2* sim = g_Game->GetSimulation2();
|
||||
ScriptRequest rqGame(sim->GetScriptInterface());
|
||||
|
||||
JS::RootedValue gameContextMetadata(rqGame.cx,
|
||||
sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, guiContextMetadata));
|
||||
JS::RootedValue gameContextMetadata(rqGame.cx, Script::CloneValueFromOtherCompartment(sim->GetScriptInterface(), scriptInterface, guiContextMetadata));
|
||||
JS::RootedValue gameInitAttributes(rqGame.cx);
|
||||
sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ps/Game.h"
|
||||
#include "ps/GameSetup/GameSetup.h"
|
||||
#include "ps/Loader.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpAIInterface.h"
|
||||
#include "simulation2/components/ICmpTemplateManager.h"
|
||||
|
@ -34,7 +34,7 @@ constexpr int DEFAULT_HEAP_GROWTH_BYTES_GCTRIGGER = 2 * 1024 * 1024;
|
||||
* should only be used on a single thread.
|
||||
*
|
||||
* (One means to share data between threads and contexts is to create
|
||||
* a ScriptInterface::StructuredClone.)
|
||||
* a Script::StructuredClone.)
|
||||
*/
|
||||
|
||||
class ScriptContext
|
||||
|
@ -58,7 +58,6 @@
|
||||
#include "js/GCHashTable.h"
|
||||
#include "js/JSON.h"
|
||||
#include "js/SourceText.h"
|
||||
#include "js/StructuredClone.h"
|
||||
#include "js/Proxy.h"
|
||||
#include "js/Warnings.h"
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ScriptExtraHeaders.h"
|
||||
#include "ScriptInterface.h"
|
||||
#include "ScriptStats.h"
|
||||
#include "StructuredClone.h"
|
||||
|
||||
#include "lib/debug.h"
|
||||
#include "lib/utf8.h"
|
||||
@ -187,8 +188,8 @@ JS::Value deepcopy(const ScriptRequest& rq, JS::HandleValue val)
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
JS::RootedValue ret(rq.cx);
|
||||
if (!JS_StructuredClone(rq.cx, val, &ret, NULL, NULL))
|
||||
JS::RootedValue ret(rq.cx, Script::DeepCopy(rq, val));
|
||||
if (ret.isNullOrUndefined())
|
||||
{
|
||||
ScriptException::Raise(rq, "deepcopy StructureClone copy failed.");
|
||||
return JS::UndefinedValue();
|
||||
@ -343,7 +344,7 @@ ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugN
|
||||
|
||||
ScriptRequest rq(this);
|
||||
m_CmptPrivate.pScriptInterface = this;
|
||||
JS_SetCompartmentPrivate(js::GetObjectCompartment(rq.glob), (void*)&m_CmptPrivate);
|
||||
JS::SetRealmPrivate(JS::GetObjectRealmOrNull(rq.glob), (void*)&m_CmptPrivate);
|
||||
}
|
||||
|
||||
ScriptInterface::~ScriptInterface()
|
||||
@ -362,7 +363,7 @@ void ScriptInterface::SetCallbackData(void* pCBData)
|
||||
|
||||
ScriptInterface::CmptPrivate* ScriptInterface::GetScriptInterfaceAndCBData(JSContext* cx)
|
||||
{
|
||||
CmptPrivate* pCmptPrivate = (CmptPrivate*)JS_GetCompartmentPrivate(js::GetContextCompartment(cx));
|
||||
CmptPrivate* pCmptPrivate = (CmptPrivate*)JS::GetRealmPrivate(JS::GetCurrentRealmOrNull(cx));
|
||||
return pCmptPrivate;
|
||||
}
|
||||
|
||||
@ -963,36 +964,3 @@ std::string ScriptInterface::ToString(JS::MutableHandleValue obj, bool pretty) c
|
||||
ScriptFunction::Call(rq, obj, "toSource", source);
|
||||
return utf8_from_wstring(source);
|
||||
}
|
||||
|
||||
JS::Value ScriptInterface::CloneValueFromOtherCompartment(const ScriptInterface& otherCompartment, JS::HandleValue val) const
|
||||
{
|
||||
PROFILE("CloneValueFromOtherCompartment");
|
||||
ScriptRequest rq(this);
|
||||
JS::RootedValue out(rq.cx);
|
||||
ScriptInterface::StructuredClone structuredClone = otherCompartment.WriteStructuredClone(val);
|
||||
ReadStructuredClone(structuredClone, &out);
|
||||
return out.get();
|
||||
}
|
||||
|
||||
ScriptInterface::StructuredClone ScriptInterface::WriteStructuredClone(JS::HandleValue v) const
|
||||
{
|
||||
ScriptRequest rq(this);
|
||||
ScriptInterface::StructuredClone ret(new JSStructuredCloneData(JS::StructuredCloneScope::SameProcess));
|
||||
JS::CloneDataPolicy policy;
|
||||
if (!JS_WriteStructuredClone(rq.cx, v, ret.get(), JS::StructuredCloneScope::SameProcess, policy, nullptr, nullptr, JS::UndefinedHandleValue))
|
||||
{
|
||||
debug_warn(L"Writing a structured clone with JS_WriteStructuredClone failed!");
|
||||
ScriptException::CatchPending(rq);
|
||||
return ScriptInterface::StructuredClone();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ScriptInterface::ReadStructuredClone(const ScriptInterface::StructuredClone& ptr, JS::MutableHandleValue ret) const
|
||||
{
|
||||
ScriptRequest rq(this);
|
||||
JS::CloneDataPolicy policy;
|
||||
if (!JS_ReadStructuredClone(rq.cx, *ptr, JS_STRUCTURED_CLONE_VERSION, ptr->scope(), ret, policy, nullptr, nullptr))
|
||||
ScriptException::CatchPending(rq);
|
||||
}
|
||||
|
@ -48,8 +48,6 @@ ERROR_TYPE(Scripting_DefineType, CreationFailed);
|
||||
// but as large as necessary for all wrapped functions)
|
||||
#define SCRIPT_INTERFACE_MAX_ARGS 8
|
||||
|
||||
class JSStructuredCloneData;
|
||||
|
||||
class ScriptInterface;
|
||||
struct ScriptInterface_impl;
|
||||
|
||||
@ -314,26 +312,6 @@ public:
|
||||
*/
|
||||
bool MathRandom(double& nbr);
|
||||
|
||||
/**
|
||||
* Structured clones are a way to serialize 'simple' JS::Values into a buffer
|
||||
* that can safely be passed between compartments and between threads.
|
||||
* A StructuredClone can be stored and read multiple times if desired.
|
||||
* We wrap them in shared_ptr so memory management is automatic and
|
||||
* thread-safe.
|
||||
*/
|
||||
using StructuredClone = shared_ptr<JSStructuredCloneData>;
|
||||
|
||||
StructuredClone WriteStructuredClone(JS::HandleValue v) const;
|
||||
void ReadStructuredClone(const StructuredClone& ptr, JS::MutableHandleValue ret) const;
|
||||
|
||||
/**
|
||||
* Construct a new value (usable in this ScriptInterface's compartment) by cloning
|
||||
* a value from a different compartment.
|
||||
* Complex values (functions, XML, etc) won't be cloned correctly, but basic
|
||||
* types and cyclic references should be fine.
|
||||
*/
|
||||
JS::Value CloneValueFromOtherCompartment(const ScriptInterface& otherCompartment, JS::HandleValue val) const;
|
||||
|
||||
/**
|
||||
* Retrieve the private data field of a JSObject that is an instance of the given JSClass.
|
||||
*/
|
||||
|
82
source/scriptinterface/StructuredClone.cpp
Normal file
82
source/scriptinterface/StructuredClone.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ScriptExceptions.h"
|
||||
#include "ScriptInterface.h"
|
||||
#include "ScriptRequest.h"
|
||||
#include "StructuredClone.h"
|
||||
|
||||
// Ignore warnings in SM headers.
|
||||
#if GCC_VERSION || CLANG_VERSION
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
# pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#elif MSC_VERSION
|
||||
# pragma warning(push, 1)
|
||||
#endif
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
|
||||
#if GCC_VERSION || CLANG_VERSION
|
||||
# pragma GCC diagnostic pop
|
||||
#elif MSC_VERSION
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
Script::StructuredClone Script::WriteStructuredClone(const ScriptRequest& rq, JS::HandleValue v)
|
||||
{
|
||||
Script::StructuredClone ret(new JSStructuredCloneData(JS::StructuredCloneScope::SameProcess));
|
||||
JS::CloneDataPolicy policy;
|
||||
if (!JS_WriteStructuredClone(rq.cx, v, ret.get(), JS::StructuredCloneScope::SameProcess, policy, nullptr, nullptr, JS::UndefinedHandleValue))
|
||||
{
|
||||
debug_warn(L"Writing a structured clone with JS_WriteStructuredClone failed!");
|
||||
ScriptException::CatchPending(rq);
|
||||
return StructuredClone();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Script::ReadStructuredClone(const ScriptRequest& rq, const Script::StructuredClone& ptr, JS::MutableHandleValue ret)
|
||||
{
|
||||
JS::CloneDataPolicy policy;
|
||||
if (!JS_ReadStructuredClone(rq.cx, *ptr, JS_STRUCTURED_CLONE_VERSION, ptr->scope(), ret, policy, nullptr, nullptr))
|
||||
ScriptException::CatchPending(rq);
|
||||
}
|
||||
|
||||
JS::Value Script::CloneValueFromOtherCompartment(const ScriptInterface& to, const ScriptInterface& from, JS::HandleValue val)
|
||||
{
|
||||
PROFILE("CloneValueFromOtherCompartment");
|
||||
Script::StructuredClone structuredClone;
|
||||
{
|
||||
ScriptRequest fromRq(from);
|
||||
structuredClone = WriteStructuredClone(fromRq, val);
|
||||
}
|
||||
ScriptRequest toRq(to);
|
||||
JS::RootedValue out(toRq.cx);
|
||||
ReadStructuredClone(toRq, structuredClone, &out);
|
||||
return out.get();
|
||||
}
|
||||
|
||||
JS::Value Script::DeepCopy(const ScriptRequest& rq, JS::HandleValue val)
|
||||
{
|
||||
JS::RootedValue out(rq.cx);
|
||||
ReadStructuredClone(rq, WriteStructuredClone(rq, val), &out);
|
||||
return out.get();
|
||||
}
|
61
source/scriptinterface/StructuredClone.h
Normal file
61
source/scriptinterface/StructuredClone.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_SCRIPTINTERFACE_STRUCTUREDCLONE
|
||||
#define INCLUDED_SCRIPTINTERFACE_STRUCTUREDCLONE
|
||||
|
||||
#include "ScriptForward.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class JSStructuredCloneData;
|
||||
|
||||
namespace Script
|
||||
{
|
||||
/**
|
||||
* Structured clones are a way to serialize 'simple' JS::Values into a buffer
|
||||
* that can safely be passed between compartments and between threads.
|
||||
* A StructuredClone can be stored and read multiple times if desired.
|
||||
* We wrap them in shared_ptr so memory management is automatic and
|
||||
* thread-safe.
|
||||
*/
|
||||
using StructuredClone = std::shared_ptr<JSStructuredCloneData>;
|
||||
|
||||
StructuredClone WriteStructuredClone(const ScriptRequest& rq, JS::HandleValue v);
|
||||
void ReadStructuredClone(const ScriptRequest& rq, const StructuredClone& ptr, JS::MutableHandleValue ret);
|
||||
|
||||
/**
|
||||
* Construct a new value by cloning a value (possibly from a different Compartment).
|
||||
* Complex values (functions, XML, etc) won't be cloned correctly, but basic
|
||||
* types and cyclic references should be fine.
|
||||
* Takes ScriptInterfaces to enter the correct realm.
|
||||
* Caller beware - manipulating several compartments in the same function is tricky.
|
||||
* @param to - ScriptInterface of the target. Should match the rooting context of the result.
|
||||
* @param from - ScriptInterface of @a val.
|
||||
*/
|
||||
JS::Value CloneValueFromOtherCompartment(const ScriptInterface& to, const ScriptInterface& from, JS::HandleValue val);
|
||||
|
||||
/**
|
||||
* Clone a JS value, ensuring that changes to the result
|
||||
* won't affect the original value.
|
||||
* Works by cloning, so the same restrictions as CloneValueFromOtherCompartment apply.
|
||||
*/
|
||||
JS::Value DeepCopy(const ScriptRequest& rq, JS::HandleValue val);
|
||||
|
||||
} // namespace Script
|
||||
|
||||
#endif // INCLUDED_SCRIPTINTERFACE_STRUCTUREDCLONE
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
@ -73,7 +74,7 @@ public:
|
||||
{
|
||||
ScriptRequest rq2(script2);
|
||||
|
||||
JS::RootedValue obj2(rq2.cx, script2.CloneValueFromOtherCompartment(script1, obj1));
|
||||
JS::RootedValue obj2(rq2.cx, Script::CloneValueFromOtherCompartment(script2, script1, obj1));
|
||||
|
||||
std::string source;
|
||||
TS_ASSERT(ScriptFunction::Call(rq2, obj2, "toSource", source));
|
||||
@ -95,7 +96,7 @@ public:
|
||||
{
|
||||
ScriptRequest rq2(script2);
|
||||
|
||||
JS::RootedValue obj2(rq2.cx, script2.CloneValueFromOtherCompartment(script1, obj1));
|
||||
JS::RootedValue obj2(rq2.cx, Script::CloneValueFromOtherCompartment(script2, script1, obj1));
|
||||
|
||||
std::string source;
|
||||
TS_ASSERT(ScriptFunction::Call(rq2, obj2, "toSource", source));
|
||||
@ -115,7 +116,7 @@ public:
|
||||
|
||||
{
|
||||
ScriptRequest rq2(script2);
|
||||
JS::RootedValue obj2(rq2.cx, script2.CloneValueFromOtherCompartment(script1, obj1));
|
||||
JS::RootedValue obj2(rq2.cx, Script::CloneValueFromOtherCompartment(script2, script1, obj1));
|
||||
|
||||
// Use JSAPI function to check if the values of the properties "a", "b" are equals a.x[0]
|
||||
JS::RootedValue prop_a(rq2.cx);
|
||||
@ -244,7 +245,7 @@ public:
|
||||
TS_ASSERT_STR_EQUALS(script.ToString(&val), "({x:1, z:[2, \"3\\u263A\\uD800\"], y:true})");
|
||||
}
|
||||
|
||||
// This function tests a common way to mod functions, by crating a wrapper that
|
||||
// This function tests a common way to mod functions, by creating a wrapper that
|
||||
// extends the functionality and is then assigned to the name of the function.
|
||||
void test_function_override()
|
||||
{
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptContext.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include "simulation2/MessageTypes.h"
|
||||
#include "simulation2/system/ComponentManager.h"
|
||||
@ -161,7 +162,7 @@ public:
|
||||
void InitRNGSeedSimulation();
|
||||
void InitRNGSeedAI();
|
||||
|
||||
static std::vector<SimulationCommand> CloneCommandsFromOtherCompartment(const ScriptInterface& oldScript, const ScriptInterface& newScript,
|
||||
static std::vector<SimulationCommand> CloneCommandsFromOtherCompartment(const ScriptInterface& newScript, const ScriptInterface& oldScript,
|
||||
const std::vector<SimulationCommand>& commands)
|
||||
{
|
||||
std::vector<SimulationCommand> newCommands;
|
||||
@ -170,7 +171,7 @@ public:
|
||||
ScriptRequest rqNew(newScript);
|
||||
for (const SimulationCommand& command : commands)
|
||||
{
|
||||
JS::RootedValue tmpCommand(rqNew.cx, newScript.CloneValueFromOtherCompartment(oldScript, command.data));
|
||||
JS::RootedValue tmpCommand(rqNew.cx, Script::CloneValueFromOtherCompartment(newScript, oldScript, command.data));
|
||||
newScript.FreezeObject(tmpCommand, true);
|
||||
SimulationCommand cmd(command.player, rqNew.cx, tmpCommand);
|
||||
newCommands.emplace_back(std::move(cmd));
|
||||
@ -414,9 +415,9 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
|
||||
|
||||
// Load the trigger scripts after we have loaded the simulation.
|
||||
{
|
||||
ScriptRequest rq(scriptInterface);
|
||||
ScriptRequest rq2(m_SecondaryComponentManager->GetScriptInterface());
|
||||
JS::RootedValue mapSettingsCloned(rq2.cx,
|
||||
m_SecondaryComponentManager->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, m_MapSettings));
|
||||
JS::RootedValue mapSettingsCloned(rq2.cx, Script::CloneValueFromOtherCompartment(m_SecondaryComponentManager->GetScriptInterface(), scriptInterface, m_MapSettings));
|
||||
ENSURE(LoadTriggerScripts(*m_SecondaryComponentManager, mapSettingsCloned, m_SecondaryLoadedScripts.get()));
|
||||
}
|
||||
|
||||
@ -469,7 +470,7 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
|
||||
ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false));
|
||||
|
||||
UpdateComponents(*m_SecondaryContext, turnLengthFixed,
|
||||
CloneCommandsFromOtherCompartment(scriptInterface, m_SecondaryComponentManager->GetScriptInterface(), commands));
|
||||
CloneCommandsFromOtherCompartment(m_SecondaryComponentManager->GetScriptInterface(), scriptInterface, commands));
|
||||
SerializationTestState secondaryStateAfter;
|
||||
ENSURE(m_SecondaryComponentManager->SerializeState(secondaryStateAfter.state));
|
||||
if (serializationTestHash)
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "ps/Util.h"
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptContext.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
#include "simulation2/components/ICmpAIInterface.h"
|
||||
#include "simulation2/components/ICmpCommandQueue.h"
|
||||
#include "simulation2/components/ICmpObstructionManager.h"
|
||||
@ -67,7 +68,7 @@ extern void QuitEngine();
|
||||
* will block until it's actually completed, so the rest of the engine should avoid
|
||||
* reading it for as long as possible.
|
||||
*
|
||||
* JS::Values are passed between the game and AI threads using ScriptInterface::StructuredClone.
|
||||
* JS::Values are passed between the game and AI threads using Script::StructuredClone.
|
||||
*
|
||||
* TODO: actually the thread isn't implemented yet, because performance hasn't been
|
||||
* sufficiently problematic to justify the complexity yet, but the CAIWorker interface
|
||||
@ -204,14 +205,14 @@ private:
|
||||
shared_ptr<ScriptInterface> m_ScriptInterface;
|
||||
|
||||
JS::PersistentRootedValue m_Obj;
|
||||
std::vector<ScriptInterface::StructuredClone > m_Commands;
|
||||
std::vector<Script::StructuredClone > m_Commands;
|
||||
};
|
||||
|
||||
public:
|
||||
struct SCommandSets
|
||||
{
|
||||
player_id_t player;
|
||||
std::vector<ScriptInterface::StructuredClone > commands;
|
||||
std::vector<Script::StructuredClone > commands;
|
||||
};
|
||||
|
||||
CAIWorker() :
|
||||
@ -291,11 +292,12 @@ public:
|
||||
|
||||
void PostCommand(int playerid, JS::HandleValue cmd)
|
||||
{
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
for (size_t i=0; i<m_Players.size(); i++)
|
||||
{
|
||||
if (m_Players[i]->m_Player == playerid)
|
||||
{
|
||||
m_Players[i]->m_Commands.push_back(m_ScriptInterface->WriteStructuredClone(cmd));
|
||||
m_Players[i]->m_Commands.push_back(Script::WriteStructuredClone(rq, cmd));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -465,7 +467,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RunGamestateInit(const ScriptInterface::StructuredClone& gameState, const Grid<NavcellData>& passabilityMap, const Grid<u8>& territoryMap,
|
||||
bool RunGamestateInit(const Script::StructuredClone& gameState, const Grid<NavcellData>& passabilityMap, const Grid<u8>& territoryMap,
|
||||
const std::map<std::string, pass_class_t>& nonPathfindingPassClassMasks, const std::map<std::string, pass_class_t>& pathfindingPassClassMasks)
|
||||
{
|
||||
// this will be run last by InitGame.js, passing the full game representation.
|
||||
@ -474,7 +476,7 @@ public:
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
|
||||
JS::RootedValue state(rq.cx);
|
||||
m_ScriptInterface->ReadStructuredClone(gameState, &state);
|
||||
Script::ReadStructuredClone(rq, gameState, &state);
|
||||
ScriptInterface::ToJSVal(rq, &m_PassabilityMapVal, passabilityMap);
|
||||
ScriptInterface::ToJSVal(rq, &m_TerritoryMapVal, territoryMap);
|
||||
|
||||
@ -501,7 +503,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateGameState(const ScriptInterface::StructuredClone& gameState)
|
||||
void UpdateGameState(const Script::StructuredClone& gameState)
|
||||
{
|
||||
ENSURE(m_CommandsComputed);
|
||||
m_GameState = gameState;
|
||||
@ -661,7 +663,7 @@ public:
|
||||
for (size_t j = 0; j < m_Players[i]->m_Commands.size(); ++j)
|
||||
{
|
||||
JS::RootedValue val(rq.cx);
|
||||
m_ScriptInterface->ReadStructuredClone(m_Players[i]->m_Commands[j], &val);
|
||||
Script::ReadStructuredClone(rq, m_Players[i]->m_Commands[j], &val);
|
||||
serializer.ScriptVal("command", &val);
|
||||
}
|
||||
|
||||
@ -726,7 +728,7 @@ public:
|
||||
{
|
||||
JS::RootedValue val(rq.cx);
|
||||
deserializer.ScriptVal("command", &val);
|
||||
m_Players.back()->m_Commands.push_back(m_ScriptInterface->WriteStructuredClone(val));
|
||||
m_Players.back()->m_Commands.push_back(Script::WriteStructuredClone(rq, val));
|
||||
}
|
||||
|
||||
deserializer.ScriptObjectAssign("data", m_Players.back()->m_Obj);
|
||||
@ -780,7 +782,7 @@ private:
|
||||
JS::RootedValue state(rq.cx);
|
||||
{
|
||||
PROFILE3("AI compute read state");
|
||||
m_ScriptInterface->ReadStructuredClone(m_GameState, &state);
|
||||
Script::ReadStructuredClone(rq, m_GameState, &state);
|
||||
m_ScriptInterface->SetProperty(state, "passabilityMap", m_PassabilityMapVal, true);
|
||||
m_ScriptInterface->SetProperty(state, "territoryMap", m_TerritoryMapVal, true);
|
||||
}
|
||||
@ -831,7 +833,7 @@ private:
|
||||
|
||||
std::set<std::wstring> m_LoadedModules;
|
||||
|
||||
ScriptInterface::StructuredClone m_GameState;
|
||||
Script::StructuredClone m_GameState;
|
||||
Grid<NavcellData> m_PassabilityMap;
|
||||
JS::PersistentRootedValue m_PassabilityMapVal;
|
||||
Grid<u8> m_TerritoryMap;
|
||||
@ -959,7 +961,7 @@ public:
|
||||
if (cmpPathfinder)
|
||||
cmpPathfinder->GetPassabilityClasses(nonPathfindingPassClassMasks, pathfindingPassClassMasks);
|
||||
|
||||
m_Worker.RunGamestateInit(scriptInterface.WriteStructuredClone(state),
|
||||
m_Worker.RunGamestateInit(Script::WriteStructuredClone(rq, state),
|
||||
*passabilityMap, *territoryMap, nonPathfindingPassClassMasks, pathfindingPassClassMasks);
|
||||
}
|
||||
|
||||
@ -985,7 +987,7 @@ public:
|
||||
LoadPathfinderClasses(state); // add the pathfinding classes to it
|
||||
|
||||
// Update the game state
|
||||
m_Worker.UpdateGameState(scriptInterface.WriteStructuredClone(state));
|
||||
m_Worker.UpdateGameState(Script::WriteStructuredClone(rq, state));
|
||||
|
||||
// Update the pathfinding data
|
||||
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
|
||||
@ -1039,7 +1041,7 @@ public:
|
||||
{
|
||||
for (size_t j = 0; j < commands[i].commands.size(); ++j)
|
||||
{
|
||||
scriptInterface.ReadStructuredClone(commands[i].commands[j], &clonedCommandVal);
|
||||
Script::ReadStructuredClone(rq, commands[i].commands[j], &clonedCommandVal);
|
||||
cmpCommandQueue->PushLocalCommand(commands[i].player, clonedCommandVal);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ps/Pyrogenesis.h"
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
#include "simulation2/components/ICmpAIManager.h"
|
||||
#include "simulation2/components/ICmpCommandQueue.h"
|
||||
#include "simulation2/components/ICmpGuiInterface.h"
|
||||
@ -55,11 +56,11 @@ JS::Value GuiInterfaceCall(const ScriptInterface& scriptInterface, const std::ws
|
||||
return JS::UndefinedValue();
|
||||
|
||||
ScriptRequest rqSim(sim->GetScriptInterface());
|
||||
JS::RootedValue arg(rqSim.cx, sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, data));
|
||||
JS::RootedValue arg(rqSim.cx, Script::CloneValueFromOtherCompartment(sim->GetScriptInterface(), scriptInterface, data));
|
||||
JS::RootedValue ret(rqSim.cx);
|
||||
cmpGuiInterface->ScriptCall(g_Game->GetViewedPlayerID(), name, arg, &ret);
|
||||
|
||||
return scriptInterface.CloneValueFromOtherCompartment(sim->GetScriptInterface(), ret);
|
||||
return Script::CloneValueFromOtherCompartment(scriptInterface, sim->GetScriptInterface(), ret);
|
||||
}
|
||||
|
||||
void PostNetworkCommand(const ScriptInterface& scriptInterface, JS::HandleValue cmd)
|
||||
@ -75,8 +76,7 @@ void PostNetworkCommand(const ScriptInterface& scriptInterface, JS::HandleValue
|
||||
return;
|
||||
|
||||
ScriptRequest rqSim(sim->GetScriptInterface());
|
||||
JS::RootedValue cmd2(rqSim.cx,
|
||||
sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, cmd));
|
||||
JS::RootedValue cmd2(rqSim.cx, Script::CloneValueFromOtherCompartment(sim->GetScriptInterface(), scriptInterface, cmd));
|
||||
|
||||
cmpCommandQueue->PostNetworkCommand(cmd2);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -22,6 +22,7 @@
|
||||
#include "gui/GUIManager.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Util.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
|
||||
const CStr CReplayTurnManager::EventNameReplayFinished = "ReplayFinished";
|
||||
@ -94,11 +95,11 @@ void CReplayTurnManager::NotifyFinishedUpdate(u32 turn)
|
||||
ignore_result(paramData.append(JS::NumberValue(turn)));
|
||||
|
||||
JS::RootedValue hashVal(rq.cx);
|
||||
scriptInterface.ToJSVal(rq, &hashVal, hash);
|
||||
ScriptInterface::ToJSVal(rq, &hashVal, hash);
|
||||
ignore_result(paramData.append(hashVal));
|
||||
|
||||
JS::RootedValue expectedHashVal(rq.cx);
|
||||
scriptInterface.ToJSVal(rq, &expectedHashVal, expectedHash);
|
||||
ScriptInterface::ToJSVal(rq, &expectedHashVal, expectedHash);
|
||||
ignore_result(paramData.append(expectedHashVal));
|
||||
|
||||
g_GUI->SendEventToAll(EventNameReplayOutOfSync, paramData);
|
||||
|
@ -292,16 +292,9 @@ void CTurnManager::QuickSave(JS::HandleValue GUIMetadata)
|
||||
|
||||
ScriptRequest rq(m_Simulation2.GetScriptInterface());
|
||||
|
||||
if (JS_StructuredClone(rq.cx, GUIMetadata, &m_QuickSaveMetadata, nullptr, nullptr))
|
||||
{
|
||||
// Freeze state to ensure that consectuvie loads don't modify the state
|
||||
m_Simulation2.GetScriptInterface().FreezeObject(m_QuickSaveMetadata, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR("Could not copy savegame GUI metadata");
|
||||
m_QuickSaveMetadata = JS::UndefinedValue();
|
||||
}
|
||||
m_QuickSaveMetadata.set(Script::DeepCopy(rq, GUIMetadata));
|
||||
// Freeze state to ensure that consectuvie loads don't modify the state
|
||||
m_Simulation2.GetScriptInterface().FreezeObject(m_QuickSaveMetadata, true);
|
||||
|
||||
LOGMESSAGERENDER("Quicksaved game");
|
||||
}
|
||||
@ -332,12 +325,7 @@ void CTurnManager::QuickLoad()
|
||||
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);
|
||||
if (!JS_StructuredClone(rq.cx, m_QuickSaveMetadata, &quickSaveMetadataClone, nullptr, nullptr))
|
||||
{
|
||||
LOGERROR("Failed to clone quicksave state!");
|
||||
return;
|
||||
}
|
||||
JS::RootedValue quickSaveMetadataClone(rq.cx, Script::DeepCopy(rq, m_QuickSaveMetadata));
|
||||
|
||||
JS::RootedValueArray<1> paramData(rq.cx);
|
||||
paramData[0].set(quickSaveMetadataClone);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -35,6 +35,7 @@
|
||||
#include "ps/GameSetup/Config.h"
|
||||
#include "ps/GameSetup/GameSetup.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpSoundManager.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user