From 0f60bf3a976be43d9163a29e3f3ec6029ab85a92 Mon Sep 17 00:00:00 2001 From: wraitii Date: Thu, 13 May 2021 17:23:52 +0000 Subject: [PATCH] Split off Object-related functions from ScriptInterface Follows 34b1920e7b. This splits off the object-related functions, such as [Set/Get/Has]Property, CreateObject, CreateArray, FreezeObject. It also puts the definitions in the header itself, which might end up with faster code here & there, though perhaps slower compilation time (somewhat doubtful since we already included most things anyways). Differential Revision: https://code.wildfiregames.com/D3956 This was SVN commit r25430. --- source/graphics/MapGenerator.cpp | 10 +- source/graphics/MapReader.cpp | 13 +- .../scripting/JSInterface_GameView.cpp | 4 +- source/gui/GUIManager.cpp | 2 +- source/gui/ObjectBases/IGUIObject.cpp | 3 +- source/gui/ObjectTypes/CMiniMap.cpp | 3 +- source/gui/Scripting/GuiScriptConversions.cpp | 8 +- .../gui/Scripting/JSInterface_GUIProxy_impl.h | 4 +- source/gui/Scripting/JSInterface_GUISize.cpp | 5 +- source/gui/SettingTypes/CGUISize.cpp | 7 +- source/gui/tests/test_GuiManager.h | 33 +-- source/lobby/IXmppClient.h | 12 +- source/lobby/XmppClient.cpp | 78 +++--- source/lobby/XmppClient.h | 12 +- source/network/NetClient.cpp | 6 +- source/network/NetClient.h | 4 +- source/network/NetServer.cpp | 6 +- source/network/tests/test_Net.h | 16 +- source/network/tests/test_NetMessage.h | 7 +- source/ps/Game.cpp | 16 +- source/ps/GameSetup/GameSetup.cpp | 108 ++++---- source/ps/GameSetup/HWDetect.cpp | 181 +++++++------- source/ps/Mod.cpp | 19 +- source/ps/ProfileViewer.cpp | 15 +- source/ps/Replay.cpp | 11 +- source/ps/SavedGame.cpp | 17 +- source/ps/VisualReplay.cpp | 20 +- source/ps/XMB/XMBStorage.cpp | 11 +- source/ps/scripting/JSInterface_ModIo.cpp | 28 +-- source/ps/scripting/JSInterface_SavedGame.cpp | 4 +- source/ps/scripting/JSInterface_VFS.cpp | 8 +- source/rlinterface/RLInterface.cpp | 9 +- source/scriptinterface/FunctionWrapper.h | 2 + source/scriptinterface/Object.h | 233 ++++++++++++++++++ source/scriptinterface/ScriptInterface.cpp | 187 +------------- source/scriptinterface/ScriptInterface.h | 161 ------------ .../tests/test_ScriptInterface.h | 15 +- source/simulation2/Simulation2.cpp | 30 ++- .../simulation2/components/CCmpAIManager.cpp | 46 ++-- .../simulation2/components/ICmpAIManager.cpp | 6 +- .../scripting/EngineScriptConversions.cpp | 12 +- .../scripting/JSInterface_Simulation.cpp | 6 +- .../simulation2/scripting/ScriptComponent.cpp | 9 +- .../serialization/DebugSerializer.cpp | 3 +- .../serialization/SerializedScriptTypes.h | 2 +- .../serialization/StdDeserializer.cpp | 2 +- .../simulation2/system/ComponentManager.cpp | 8 +- source/simulation2/system/TurnManager.cpp | 8 +- .../GameInterface/Handlers/MapHandlers.cpp | 17 +- 49 files changed, 661 insertions(+), 766 deletions(-) create mode 100644 source/scriptinterface/Object.h diff --git a/source/graphics/MapGenerator.cpp b/source/graphics/MapGenerator.cpp index 046a26c532..34d8cc0736 100644 --- a/source/graphics/MapGenerator.cpp +++ b/source/graphics/MapGenerator.cpp @@ -126,7 +126,7 @@ bool CMapGeneratorWorker::Run() } // Prevent unintentional modifications to the settings object by random map scripts - if (!m_ScriptInterface->FreezeObject(settingsVal, true)) + if (!Script::FreezeObject(rq, settingsVal, true)) { LOGERROR("CMapGeneratorWorker::Run: Failed to deepfreeze settings"); return false; @@ -134,8 +134,8 @@ bool CMapGeneratorWorker::Run() // Init RNG seed u32 seed = 0; - if (!m_ScriptInterface->HasProperty(settingsVal, "Seed") || - !m_ScriptInterface->GetProperty(settingsVal, "Seed", seed)) + if (!Script::HasProperty(rq, settingsVal, "Seed") || + !Script::GetProperty(rq, settingsVal, "Seed", seed)) LOGWARNING("CMapGeneratorWorker::Run: No seed value specified - using 0"); InitScriptInterface(seed); @@ -144,7 +144,7 @@ bool CMapGeneratorWorker::Run() // Copy settings to global variable JS::RootedValue global(rq.cx, rq.globalValue()); - if (!m_ScriptInterface->SetProperty(global, "g_MapSettings", settingsVal, true, true)) + if (!Script::SetProperty(rq, global, "g_MapSettings", settingsVal, true, true)) { LOGERROR("CMapGeneratorWorker::Run: Failed to define g_MapSettings"); return false; @@ -390,7 +390,7 @@ JS::Value CMapGeneratorWorker::LoadMapTerrain(const VfsPath& filename) JS::RootedValue returnValue(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &returnValue, "height", heightmap, diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index c72526ecb4..f7d9f0bf81 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -39,6 +39,7 @@ #include "renderer/PostprocManager.h" #include "renderer/SkyManager.h" #include "renderer/WaterManager.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptContext.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" @@ -379,14 +380,14 @@ void CMapSummaryReader::GetMapSettings(const ScriptInterface& scriptInterface, J { ScriptRequest rq(scriptInterface); - ScriptInterface::CreateObject(rq, ret); + Script::CreateObject(rq, ret); if (m_ScriptSettings.empty()) return; JS::RootedValue scriptSettingsVal(rq.cx); scriptInterface.ParseJSON(m_ScriptSettings, &scriptSettingsVal); - scriptInterface.SetProperty(ret, "settings", scriptSettingsVal, false); + Script::SetProperty(rq, ret, "settings", scriptSettingsVal, false); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1333,7 +1334,7 @@ int CMapReader::ParseTerrain() // parse terrain from map data // an error here should stop the loading process #define GET_TERRAIN_PROPERTY(val, prop, out)\ - if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ +if (!Script::GetProperty(rq, val, #prop, out))\ { LOGERROR("CMapReader::ParseTerrain() failed to get '%s' property", #prop);\ throw PSERROR_Game_World_MapLoadFailed("Error parsing terrain data.\nCheck application log for details"); } @@ -1408,7 +1409,7 @@ int CMapReader::ParseEntities() // parse entities from map data std::vector entities; - if (!pSimulation2->GetScriptInterface().GetProperty(m_MapData, "entities", entities)) + if (!Script::GetProperty(rq, m_MapData, "entities", entities)) LOGWARNING("CMapReader::ParseEntities() failed to get 'entities' property"); CSimulation2& sim = *pSimulation2; @@ -1470,7 +1471,7 @@ int CMapReader::ParseEnvironment() ScriptRequest rq(pSimulation2->GetScriptInterface()); #define GET_ENVIRONMENT_PROPERTY(val, prop, out)\ - if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ + if (!Script::GetProperty(rq, val, #prop, out))\ LOGWARNING("CMapReader::ParseEnvironment() failed to get '%s' property", #prop); JS::RootedValue envObj(rq.cx); @@ -1570,7 +1571,7 @@ int CMapReader::ParseCamera() CVector3D translation = CVector3D(100, 150, -100); #define GET_CAMERA_PROPERTY(val, prop, out)\ - if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ + if (!Script::GetProperty(rq, val, #prop, out))\ LOGWARNING("CMapReader::ParseCamera() failed to get '%s' property", #prop); JS::RootedValue cameraObj(rq.cx); diff --git a/source/graphics/scripting/JSInterface_GameView.cpp b/source/graphics/scripting/JSInterface_GameView.cpp index 1d08b6921f..7410c6c783 100644 --- a/source/graphics/scripting/JSInterface_GameView.cpp +++ b/source/graphics/scripting/JSInterface_GameView.cpp @@ -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 @@ -80,7 +80,7 @@ JS::Value GetCameraPivot(const ScriptRequest& rq) pivot = g_Game->GetView()->GetCameraPivot(); JS::RootedValue pivotValue(rq.cx); - ScriptInterface::CreateObject(rq, &pivotValue, "x", pivot.X, "z", pivot.Z); + Script::CreateObject(rq, &pivotValue, "x", pivot.X, "z", pivot.Z); return pivotValue; } diff --git a/source/gui/GUIManager.cpp b/source/gui/GUIManager.cpp index f12a9be359..0715641dd2 100644 --- a/source/gui/GUIManager.cpp +++ b/source/gui/GUIManager.cpp @@ -216,7 +216,7 @@ void CGUIManager::SGUIPage::LoadPage(shared_ptr scriptContext) if (hotloadData) Script::ReadStructuredClone(rq, hotloadData, &hotloadDataVal); - if (scriptInterface->HasProperty(global, "init") && + if (Script::HasProperty(rq, global, "init") && !ScriptFunction::CallVoid(rq, global, "init", initDataVal, hotloadDataVal)) LOGERROR("GUI page '%s': Failed to call init() function", utf8_from_wstring(m_Name)); } diff --git a/source/gui/ObjectBases/IGUIObject.cpp b/source/gui/ObjectBases/IGUIObject.cpp index 193044a33a..45d8ae5e1f 100644 --- a/source/gui/ObjectBases/IGUIObject.cpp +++ b/source/gui/ObjectBases/IGUIObject.cpp @@ -27,6 +27,7 @@ #include "ps/CLogger.h" #include "ps/GameSetup/Config.h" #include "ps/Profile.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptContext.h" #include "scriptinterface/ScriptExtraHeaders.h" #include "scriptinterface/ScriptInterface.h" @@ -370,7 +371,7 @@ InReaction IGUIObject::SendMouseEvent(EGUIMessageType type, const CStr& eventNam const CVector2D& mousePos = m_pGUI.GetMousePos(); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &mouse, "x", mousePos.X, diff --git a/source/gui/ObjectTypes/CMiniMap.cpp b/source/gui/ObjectTypes/CMiniMap.cpp index d06580d149..e7825257f1 100644 --- a/source/gui/ObjectTypes/CMiniMap.cpp +++ b/source/gui/ObjectTypes/CMiniMap.cpp @@ -43,6 +43,7 @@ #include "renderer/Renderer.h" #include "renderer/RenderingOptions.h" #include "renderer/WaterManager.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpMinimap.h" @@ -281,7 +282,7 @@ bool CMiniMap::FireWorldClickEvent(int button, int UNUSED(clicks)) GetMouseWorldCoordinates(x, z); JS::RootedValue coords(rq.cx); - ScriptInterface::CreateObject(rq, &coords, "x", x, "z", z); + Script::CreateObject(rq, &coords, "x", x, "z", z); JS::RootedValue buttonJs(rq.cx); Script::ToJSVal(rq, &buttonJs, button); diff --git a/source/gui/Scripting/GuiScriptConversions.cpp b/source/gui/Scripting/GuiScriptConversions.cpp index 9534a55397..b47666d585 100644 --- a/source/gui/Scripting/GuiScriptConversions.cpp +++ b/source/gui/Scripting/GuiScriptConversions.cpp @@ -28,8 +28,8 @@ #include "maths/Vector2D.h" #include "ps/Hotkey.h" #include "ps/CLogger.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptConversions.h" -#include "scriptinterface/ScriptInterface.h" // CreateObject #include @@ -184,7 +184,7 @@ template<> bool Script::FromJSVal(const ScriptRequest& rq, JS::Handle template<> void Script::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret, const CRect& val) { - ScriptInterface::CreateObject( + Script::CreateObject( rq, ret, "left", val.left, @@ -327,7 +327,7 @@ template<> bool Script::FromJSVal(const ScriptRequest& rq, J template<> void Script::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret, const CSize2D& val) { - ScriptInterface::CreateObject(rq, ret, "width", val.Width, "height", val.Height); + Script::CreateObject(rq, ret, "width", val.Width, "height", val.Height); } template<> bool Script::FromJSVal(const ScriptRequest& rq, JS::HandleValue v, CSize2D& out) @@ -355,7 +355,7 @@ template<> bool Script::FromJSVal(const ScriptRequest& rq, JS::HandleVa template<> void Script::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret, const CVector2D& val) { - ScriptInterface::CreateObject(rq, ret, "x", val.X, "y", val.Y); + Script::CreateObject(rq, ret, "x", val.X, "y", val.Y); } template<> bool Script::FromJSVal(const ScriptRequest& rq, JS::HandleValue v, CVector2D& out) diff --git a/source/gui/Scripting/JSInterface_GUIProxy_impl.h b/source/gui/Scripting/JSInterface_GUIProxy_impl.h index 224851435f..7f7adeed3c 100644 --- a/source/gui/Scripting/JSInterface_GUIProxy_impl.h +++ b/source/gui/Scripting/JSInterface_GUIProxy_impl.h @@ -208,10 +208,10 @@ bool JSI_GUIProxy::get(JSContext* cx, JS::HandleObject proxy, JS::HandleValue } else if (propName == "children") { - ScriptInterface::CreateArray(rq, vp); + Script::CreateArray(rq, vp); for (size_t i = 0; i < e->m_Children.size(); ++i) - pScriptInterface->SetPropertyInt(vp, i, e->m_Children[i]); + Script::SetPropertyInt(rq, vp, i, e->m_Children[i]); return true; } diff --git a/source/gui/Scripting/JSInterface_GUISize.cpp b/source/gui/Scripting/JSInterface_GUISize.cpp index ed2edc6473..ce99061945 100644 --- a/source/gui/Scripting/JSInterface_GUISize.cpp +++ b/source/gui/Scripting/JSInterface_GUISize.cpp @@ -21,6 +21,7 @@ #include "ps/CStr.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/Object.h" JSClass JSI_GUISize::JSI_class = { "GUISize", 0, &JSI_GUISize::JSI_classops @@ -111,8 +112,8 @@ bool JSI_GUISize::toString(JSContext* cx, uint argc, JS::Value* vp) double val, valr; #define SIDE(side) \ - pScriptInterface->GetProperty(args.thisv(), #side, val); \ - pScriptInterface->GetProperty(args.thisv(), "r"#side, valr); \ + Script::GetProperty(rq, args.thisv(), #side, val); \ + Script::GetProperty(rq, args.thisv(), "r"#side, valr); \ buffer += ToPercentString(val, valr); SIDE(left); diff --git a/source/gui/SettingTypes/CGUISize.cpp b/source/gui/SettingTypes/CGUISize.cpp index 8b08963e90..e844cc8216 100644 --- a/source/gui/SettingTypes/CGUISize.cpp +++ b/source/gui/SettingTypes/CGUISize.cpp @@ -21,6 +21,7 @@ #include "gui/Scripting/JSInterface_GUISize.h" #include "ps/CLogger.h" +#include "scriptinterface/Object.h" CGUISize::CGUISize() : pixel(), percent() @@ -159,7 +160,7 @@ void CGUISize::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret) cons } #define P(x, y, z)\ - if (!pScriptInterface->SetProperty(ret, #z, x.y)) \ + if (!Script::SetProperty(rq, ret, #z, x.y)) \ { \ ScriptException::Raise(rq, "Could not SetProperty '%s'", #z); \ return; \ @@ -177,8 +178,6 @@ void CGUISize::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret) cons bool CGUISize::FromJSVal(const ScriptRequest& rq, JS::HandleValue v) { - ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(rq.cx)->pScriptInterface; - if (v.isString()) { CStrW str; @@ -210,7 +209,7 @@ bool CGUISize::FromJSVal(const ScriptRequest& rq, JS::HandleValue v) } #define P(x, y, z) \ - if (!pScriptInterface->GetProperty(v, #z, x.y))\ + if (!Script::GetProperty(rq, v, #z, x.y))\ {\ LOGERROR("CGUISize could not get object property '%s'", #z);\ return false;\ diff --git a/source/gui/tests/test_GuiManager.h b/source/gui/tests/test_GuiManager.h index ad57db8ff7..c5d25a0d74 100755 --- a/source/gui/tests/test_GuiManager.h +++ b/source/gui/tests/test_GuiManager.h @@ -28,6 +28,7 @@ #include "scriptinterface/ScriptRequest.h" #include "scriptinterface/ScriptInterface.h" #include "scriptinterface/StructuredClone.h" +#include "scriptinterface/Object.h" #include @@ -64,7 +65,7 @@ public: const ScriptInterface& scriptInterface = *(g_GUI->GetScriptInterface()); ScriptRequest rq(scriptInterface); JS::RootedValue val(rq.cx); - scriptInterface.CreateObject(rq, &val); + Script::CreateObject(rq, &val); Script::StructuredClone data = Script::WriteStructuredClone(rq, JS::NullHandleValue); g_GUI->PushPage(L"event/page_event.xml", data, JS::UndefinedHandleValue); @@ -82,37 +83,37 @@ public: // first and second object. We don't want the fourth object to be // called, to avoid infinite additions of objects. g_GUI->TickObjects(); - pageScriptInterface.GetProperty(global, "called1", &js_called_value); + Script::GetProperty(prq, global, "called1", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 1); - pageScriptInterface.GetProperty(global, "called2", &js_called_value); + Script::GetProperty(prq, global, "called2", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 1); - pageScriptInterface.GetProperty(global, "called3", &js_called_value); + Script::GetProperty(prq, global, "called3", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 0); - pageScriptInterface.GetProperty(global, "called4", &js_called_value); + Script::GetProperty(prq, global, "called4", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 0); // Ticking again will still call the second object, but also the fourth. g_GUI->TickObjects(); - pageScriptInterface.GetProperty(global, "called1", &js_called_value); + Script::GetProperty(prq, global, "called1", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 1); - pageScriptInterface.GetProperty(global, "called2", &js_called_value); + Script::GetProperty(prq, global, "called2", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 2); - pageScriptInterface.GetProperty(global, "called3", &js_called_value); + Script::GetProperty(prq, global, "called3", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 0); - pageScriptInterface.GetProperty(global, "called4", &js_called_value); + Script::GetProperty(prq, global, "called4", &js_called_value); Script::FromJSVal(prq, js_called_value, called_value); TS_ASSERT_EQUALS(called_value, 1); } @@ -128,7 +129,7 @@ public: const ScriptInterface& scriptInterface = *(g_GUI->GetScriptInterface()); ScriptRequest rq(scriptInterface); JS::RootedValue val(rq.cx); - scriptInterface.CreateObject(rq, &val); + Script::CreateObject(rq, &val); Script::StructuredClone data = Script::WriteStructuredClone(rq, JS::NullHandleValue); g_GUI->PushPage(L"hotkey/page_hotkey.xml", data, JS::UndefinedHandleValue); @@ -154,12 +155,12 @@ public: bool hotkey_pressed_value = false; JS::RootedValue js_hotkey_pressed_value(prq.cx); - pageScriptInterface.GetProperty(global, "state_before", &js_hotkey_pressed_value); + Script::GetProperty(prq, global, "state_before", &js_hotkey_pressed_value); Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value); TS_ASSERT_EQUALS(hotkey_pressed_value, true); hotkey_pressed_value = false; - pageScriptInterface.GetProperty(global, "state_after", &js_hotkey_pressed_value); + Script::GetProperty(prq, global, "state_after", &js_hotkey_pressed_value); Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value); TS_ASSERT_EQUALS(hotkey_pressed_value, true); @@ -170,12 +171,12 @@ public: in_dispatch_event(&ev); hotkey_pressed_value = false; - pageScriptInterface.GetProperty(global, "state_before", &js_hotkey_pressed_value); + Script::GetProperty(prq, global, "state_before", &js_hotkey_pressed_value); Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value); TS_ASSERT_EQUALS(hotkey_pressed_value, true); hotkey_pressed_value = false; - pageScriptInterface.GetProperty(global, "state_after", &js_hotkey_pressed_value); + Script::GetProperty(prq, global, "state_after", &js_hotkey_pressed_value); Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value); TS_ASSERT_EQUALS(hotkey_pressed_value, true); @@ -185,12 +186,12 @@ public: in_dispatch_event(&ev); hotkey_pressed_value = true; - pageScriptInterface.GetProperty(global, "state_before", &js_hotkey_pressed_value); + Script::GetProperty(prq, global, "state_before", &js_hotkey_pressed_value); Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value); TS_ASSERT_EQUALS(hotkey_pressed_value, false); hotkey_pressed_value = true; - pageScriptInterface.GetProperty(global, "state_after", &js_hotkey_pressed_value); + Script::GetProperty(prq, global, "state_after", &js_hotkey_pressed_value); Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value); TS_ASSERT_EQUALS(hotkey_pressed_value, false); diff --git a/source/lobby/IXmppClient.h b/source/lobby/IXmppClient.h index 757a98377a..9bd2a4d497 100644 --- a/source/lobby/IXmppClient.h +++ b/source/lobby/IXmppClient.h @@ -38,8 +38,8 @@ public: virtual void recv() = 0; virtual void SendIqGetBoardList() = 0; virtual void SendIqGetProfile(const std::string& player) = 0; - virtual void SendIqGameReport(const ScriptInterface& scriptInterface, JS::HandleValue data) = 0; - virtual void SendIqRegisterGame(const ScriptInterface& scriptInterface, JS::HandleValue data) = 0; + virtual void SendIqGameReport(const ScriptRequest& rq, JS::HandleValue data) = 0; + virtual void SendIqRegisterGame(const ScriptRequest& rq, JS::HandleValue data) = 0; virtual void SendIqGetConnectionData(const std::string& jid, const std::string& password) = 0; virtual void SendIqUnregisterGame() = 0; virtual void SendIqChangeStateGame(const std::string& nbp, const std::string& players) = 0; @@ -54,10 +54,10 @@ public: virtual const char* GetRole(const std::string& nickname) = 0; virtual std::wstring GetRating(const std::string& nickname) = 0; virtual const std::wstring& GetSubject() = 0; - virtual JS::Value GUIGetPlayerList(const ScriptInterface& scriptInterface) = 0; - virtual JS::Value GUIGetGameList(const ScriptInterface& scriptInterface) = 0; - virtual JS::Value GUIGetBoardList(const ScriptInterface& scriptInterface) = 0; - virtual JS::Value GUIGetProfile(const ScriptInterface& scriptInterface) = 0; + virtual JS::Value GUIGetPlayerList(const ScriptRequest& rq) = 0; + virtual JS::Value GUIGetGameList(const ScriptRequest& rq) = 0; + virtual JS::Value GUIGetBoardList(const ScriptRequest& rq) = 0; + virtual JS::Value GUIGetProfile(const ScriptRequest& rq) = 0; virtual JS::Value GuiPollNewMessages(const ScriptInterface& guiInterface) = 0; virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& guiInterface) = 0; diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index f78fc11480..19fdae406e 100644 --- a/source/lobby/XmppClient.cpp +++ b/source/lobby/XmppClient.cpp @@ -389,7 +389,7 @@ void XmppClient::SendIqGetConnectionData(const std::string& jid, const std::stri * * @param data A JS array of game statistics */ -void XmppClient::SendIqGameReport(const ScriptInterface& scriptInterface, JS::HandleValue data) +void XmppClient::SendIqGameReport(const ScriptRequest& rq, JS::HandleValue data) { glooxwrapper::JID echelonJid(m_echelonId); @@ -399,11 +399,11 @@ void XmppClient::SendIqGameReport(const ScriptInterface& scriptInterface, JS::Ha // Iterate through all the properties reported and add them to the stanza. std::vector properties; - scriptInterface.EnumeratePropertyNames(data, true, properties); + Script::EnumeratePropertyNames(rq, data, true, properties); for (const std::string& p : properties) { std::wstring value; - scriptInterface.GetProperty(data, p.c_str(), value); + Script::GetProperty(rq, data, p.c_str(), value); report->addAttribute(p, utf8_from_wstring(value)); } @@ -422,7 +422,7 @@ void XmppClient::SendIqGameReport(const ScriptInterface& scriptInterface, JS::Ha * * @param data A JS array of game attributes */ -void XmppClient::SendIqRegisterGame(const ScriptInterface& scriptInterface, JS::HandleValue data) +void XmppClient::SendIqRegisterGame(const ScriptRequest& rq, JS::HandleValue data) { glooxwrapper::JID xpartamuppJid(m_xpartamuppId); @@ -433,11 +433,11 @@ void XmppClient::SendIqRegisterGame(const ScriptInterface& scriptInterface, JS:: // Iterate through all the properties reported and add them to the stanza. std::vector properties; - scriptInterface.EnumeratePropertyNames(data, true, properties); + Script::EnumeratePropertyNames(rq, data, true, properties); for (const std::string& p : properties) { std::string value; - if (!scriptInterface.GetProperty(data, p.c_str(), value)) + if (!Script::GetProperty(rq, data, p.c_str(), value)) { LOGERROR("Could not parse attribute '%s' as string.", p); return; @@ -569,19 +569,17 @@ void XmppClient::handleOOB(const glooxwrapper::JID&, const glooxwrapper::OOB&) * * @return A JS array containing all known players and their presences */ -JS::Value XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface) +JS::Value XmppClient::GUIGetPlayerList(const ScriptRequest& rq) { - ScriptRequest rq(scriptInterface); - JS::RootedValue ret(rq.cx); - ScriptInterface::CreateArray(rq, &ret); + Script::CreateArray(rq, &ret); int j = 0; for (const std::pair& p : m_PlayerMap) { JS::RootedValue player(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &player, "name", p.first, @@ -589,7 +587,7 @@ JS::Value XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface) "rating", p.second.m_Rating, "role", p.second.m_Role); - scriptInterface.SetPropertyInt(ret, j++, player); + Script::SetPropertyInt(rq, ret, j++, player); } return ret; } @@ -599,12 +597,10 @@ JS::Value XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface) * * @return A JS array containing all known games */ -JS::Value XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface) +JS::Value XmppClient::GUIGetGameList(const ScriptRequest& rq) { - ScriptRequest rq(scriptInterface); - JS::RootedValue ret(rq.cx); - ScriptInterface::CreateArray(rq, &ret); + Script::CreateArray(rq, &ret); int j = 0; const char* stats[] = { "name", "hostUsername", "hostJID", "state", "hasPassword", @@ -614,12 +610,12 @@ JS::Value XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface) for(const glooxwrapper::Tag* const& t : m_GameList) { JS::RootedValue game(rq.cx); - ScriptInterface::CreateObject(rq, &game); + Script::CreateObject(rq, &game); for (size_t i = 0; i < ARRAY_SIZE(stats); ++i) - scriptInterface.SetProperty(game, stats[i], t->findAttribute(stats[i])); + Script::SetProperty(rq, game, stats[i], t->findAttribute(stats[i])); - scriptInterface.SetPropertyInt(ret, j++, game); + Script::SetPropertyInt(rq, ret, j++, game); } return ret; } @@ -629,12 +625,10 @@ JS::Value XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface) * * @return A JS array containing all known leaderboard data */ -JS::Value XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface) +JS::Value XmppClient::GUIGetBoardList(const ScriptRequest& rq) { - ScriptRequest rq(scriptInterface); - JS::RootedValue ret(rq.cx); - ScriptInterface::CreateArray(rq, &ret); + Script::CreateArray(rq, &ret); int j = 0; const char* attributes[] = { "name", "rank", "rating" }; @@ -642,12 +636,12 @@ JS::Value XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface) for(const glooxwrapper::Tag* const& t : m_BoardList) { JS::RootedValue board(rq.cx); - ScriptInterface::CreateObject(rq, &board); + Script::CreateObject(rq, &board); for (size_t i = 0; i < ARRAY_SIZE(attributes); ++i) - scriptInterface.SetProperty(board, attributes[i], t->findAttribute(attributes[i])); + Script::SetProperty(rq, board, attributes[i], t->findAttribute(attributes[i])); - scriptInterface.SetPropertyInt(ret, j++, board); + Script::SetPropertyInt(rq, ret, j++, board); } return ret; } @@ -657,12 +651,10 @@ JS::Value XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface) * * @return A JS array containing the specific user's profile data */ -JS::Value XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface) +JS::Value XmppClient::GUIGetProfile(const ScriptRequest& rq) { - ScriptRequest rq(scriptInterface); - JS::RootedValue ret(rq.cx); - ScriptInterface::CreateArray(rq, &ret); + Script::CreateArray(rq, &ret); int j = 0; const char* stats[] = { "player", "rating", "totalGamesPlayed", "highestRating", "wins", "losses", "rank" }; @@ -670,12 +662,12 @@ JS::Value XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface) for (const glooxwrapper::Tag* const& t : m_Profile) { JS::RootedValue profile(rq.cx); - ScriptInterface::CreateObject(rq, &profile); + Script::CreateObject(rq, &profile); for (size_t i = 0; i < ARRAY_SIZE(stats); ++i) - scriptInterface.SetProperty(profile, stats[i], t->findAttribute(stats[i])); + Script::SetProperty(rq, profile, stats[i], t->findAttribute(stats[i])); - scriptInterface.SetPropertyInt(ret, j++, profile); + Script::SetPropertyInt(rq, ret, j++, profile); } return ret; } @@ -708,7 +700,7 @@ void XmppClient::CreateGUIMessage( return; ScriptRequest rq(m_ScriptInterface); JS::RootedValue message(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &message, "type", type, @@ -718,7 +710,7 @@ void XmppClient::CreateGUIMessage( JS::RootedObject messageObj(rq.cx, message.toObjectOrNull()); SetGUIMessageProperty(rq, messageObj, args...); - m_ScriptInterface->FreezeObject(message, true); + Script::FreezeObject(rq, message, true); m_GuiMessageQueue.push_back(JS::Heap(message)); } @@ -744,32 +736,32 @@ JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& guiInterface) // Optimize for batch message processing that is more // performance demanding than processing a lone message. JS::RootedValue messages(rq.cx); - ScriptInterface::CreateArray(rq, &messages); + Script::CreateArray(rq, &messages); int j = 0; for (const JS::Heap& message : m_GuiMessageQueue) { - m_ScriptInterface->SetPropertyInt(messages, j++, message); + Script::SetPropertyInt(rq, messages, j++, message); // Store historic chat messages. // Only store relevant messages to minimize memory footprint. JS::RootedValue rootedMessage(rq.cx, message); std::string type; - m_ScriptInterface->GetProperty(rootedMessage, "type", type); + Script::GetProperty(rq, rootedMessage, "type", type); if (type != "chat") continue; std::string level; - m_ScriptInterface->GetProperty(rootedMessage, "level", level); + Script::GetProperty(rq, rootedMessage, "level", level); if (level != "room-message" && level != "private-message") continue; JS::RootedValue historicMessage(rq.cx, Script::DeepCopy(rq, rootedMessage)); if (true) { - m_ScriptInterface->SetProperty(historicMessage, "historic", true); - m_ScriptInterface->FreezeObject(historicMessage, true); + Script::SetProperty(rq, historicMessage, "historic", true); + Script::FreezeObject(rq, historicMessage, true); m_HistoricGuiMessages.push_back(JS::Heap(historicMessage)); } else @@ -789,11 +781,11 @@ JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& guiInterfac ScriptRequest rq(m_ScriptInterface); JS::RootedValue messages(rq.cx); - ScriptInterface::CreateArray(rq, &messages); + Script::CreateArray(rq, &messages); int j = 0; for (const JS::Heap& message : m_HistoricGuiMessages) - m_ScriptInterface->SetPropertyInt(messages, j++, message); + Script::SetPropertyInt(rq, messages, j++, message); // Copy the messages over to the caller script interface. return Script::CloneValueFromOtherCompartment(guiInterface, *m_ScriptInterface, messages); diff --git a/source/lobby/XmppClient.h b/source/lobby/XmppClient.h index 8d2497ef51..a782c767f5 100644 --- a/source/lobby/XmppClient.h +++ b/source/lobby/XmppClient.h @@ -84,8 +84,8 @@ public: void recv(); void SendIqGetBoardList(); void SendIqGetProfile(const std::string& player); - void SendIqGameReport(const ScriptInterface& scriptInterface, JS::HandleValue data); - void SendIqRegisterGame(const ScriptInterface& scriptInterface, JS::HandleValue data); + void SendIqGameReport(const ScriptRequest& rq, JS::HandleValue data); + void SendIqRegisterGame(const ScriptRequest& rq, JS::HandleValue data); void SendIqGetConnectionData(const std::string& jid, const std::string& password); void SendIqUnregisterGame(); void SendIqChangeStateGame(const std::string& nbp, const std::string& players); @@ -101,10 +101,10 @@ public: std::wstring GetRating(const std::string& nickname); const std::wstring& GetSubject(); - JS::Value GUIGetPlayerList(const ScriptInterface& scriptInterface); - JS::Value GUIGetGameList(const ScriptInterface& scriptInterface); - JS::Value GUIGetBoardList(const ScriptInterface& scriptInterface); - JS::Value GUIGetProfile(const ScriptInterface& scriptInterface); + JS::Value GUIGetPlayerList(const ScriptRequest& rq); + JS::Value GUIGetGameList(const ScriptRequest& rq); + JS::Value GUIGetBoardList(const ScriptRequest& rq); + JS::Value GUIGetProfile(const ScriptRequest& rq); void SendStunEndpointToHost(const StunClient::StunEndpoint& stunEndpoint, const std::string& hostJID); diff --git a/source/network/NetClient.cpp b/source/network/NetClient.cpp index dc42bf2f26..d4c621033f 100644 --- a/source/network/NetClient.cpp +++ b/source/network/NetClient.cpp @@ -390,20 +390,20 @@ void CNetClient::PostPlayerAssignmentsToScript() ScriptRequest rq(GetScriptInterface()); JS::RootedValue newAssignments(rq.cx); - ScriptInterface::CreateObject(rq, &newAssignments); + Script::CreateObject(rq, &newAssignments); for (const std::pair& p : m_PlayerAssignments) { JS::RootedValue assignment(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &assignment, "name", p.second.m_Name, "player", p.second.m_PlayerID, "status", p.second.m_Status); - GetScriptInterface().SetProperty(newAssignments, p.first.c_str(), assignment); + Script::SetProperty(rq, newAssignments, p.first.c_str(), assignment); } PushGuiMessage( diff --git a/source/network/NetClient.h b/source/network/NetClient.h index 0bd29ede52..f388804eca 100644 --- a/source/network/NetClient.h +++ b/source/network/NetClient.h @@ -21,7 +21,7 @@ #include "network/fsm.h" #include "network/NetFileTransfer.h" #include "network/NetHost.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/Object.h" #include "ps/CStr.h" @@ -176,7 +176,7 @@ public: ScriptRequest rq(GetScriptInterface()); JS::RootedValue message(rq.cx); - ScriptInterface::CreateObject(rq, &message, args...); + Script::CreateObject(rq, &message, args...); m_GuiMessageQueue.push_back(JS::Heap(message)); } diff --git a/source/network/NetServer.cpp b/source/network/NetServer.cpp index 2674c88219..c0f100d357 100644 --- a/source/network/NetServer.cpp +++ b/source/network/NetServer.cpp @@ -1178,9 +1178,9 @@ bool CNetServerWorker::OnSimulationCommand(void* context, CFsmEvent* event) const ScriptInterface& scriptInterface = server.GetScriptInterface(); ScriptRequest rq(scriptInterface); JS::RootedValue settings(rq.cx); - scriptInterface.GetProperty(server.m_InitAttributes, "settings", &settings); - if (scriptInterface.HasProperty(settings, "CheatsEnabled")) - scriptInterface.GetProperty(settings, "CheatsEnabled", cheatsEnabled); + Script::GetProperty(rq, server.m_InitAttributes, "settings", &settings); + if (Script::HasProperty(rq, settings, "CheatsEnabled")) + Script::GetProperty(rq, settings, "CheatsEnabled", cheatsEnabled); PlayerAssignmentMap::iterator it = server.m_PlayerAssignments.find(session->GetGUID()); // When cheating is disabled, fail if the player the message claims to diff --git a/source/network/tests/test_Net.h b/source/network/tests/test_Net.h index 245f5943c5..f1f13b655e 100644 --- a/source/network/tests/test_Net.h +++ b/source/network/tests/test_Net.h @@ -153,7 +153,7 @@ public: CNetServer server("no_secret"); JS::RootedValue attrs(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &attrs, "mapType", "scenario", @@ -187,7 +187,7 @@ public: { JS::RootedValue cmd(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &cmd, "type", "debug-print", @@ -197,7 +197,7 @@ public: { JS::RootedValue cmd(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &cmd, "type", "debug-print", @@ -232,7 +232,7 @@ public: CNetServer server("no_secret"); JS::RootedValue attrs(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &attrs, "mapType", "scenario", @@ -270,7 +270,7 @@ public: { JS::RootedValue cmd(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &cmd, "type", "debug-print", @@ -287,7 +287,7 @@ public: { JS::RootedValue cmd(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &cmd, "type", "debug-print", @@ -347,7 +347,7 @@ public: { JS::RootedValue cmd(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &cmd, "type", "debug-print", @@ -364,7 +364,7 @@ public: { JS::RootedValue cmd(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &cmd, "type", "debug-print", diff --git a/source/network/tests/test_NetMessage.h b/source/network/tests/test_NetMessage.h index a77d738c30..36776bbdec 100644 --- a/source/network/tests/test_NetMessage.h +++ b/source/network/tests/test_NetMessage.h @@ -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 @@ -20,6 +20,7 @@ #include "network/NetMessage.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/Object.h" class TestNetMessage : public CxxTest::TestSuite { @@ -30,8 +31,8 @@ public: ScriptRequest rq(script); JS::RootedValue val(rq.cx); - ScriptInterface::CreateArray(rq, &val); - script.SetPropertyInt(val, 0, 4); + Script::CreateArray(rq, &val); + Script::SetPropertyInt(rq, val, 0, 4); CSimulationMessage msg(script, 1, 2, 3, val); TS_ASSERT_STR_EQUALS(msg.ToString(), "CSimulationMessage { m_Client: 1, m_Player: 2, m_Turn: 3, m_Data: [4] }"); diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index 2adf14198a..cbf55709d6 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -218,12 +218,12 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved m_Simulation2->SetInitAttributes(attribs); std::string mapType; - scriptInterface.GetProperty(attribs, "mapType", mapType); + Script::GetProperty(rq, attribs, "mapType", mapType); float speed; - if (scriptInterface.HasProperty(attribs, "gameSpeed")) + if (Script::HasProperty(rq, attribs, "gameSpeed")) { - if (scriptInterface.GetProperty(attribs, "gameSpeed", speed)) + if (Script::GetProperty(rq, attribs, "gameSpeed", speed)) SetSimRate(speed); else LOGERROR("GameSpeed could not be parsed."); @@ -247,8 +247,8 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved std::wstring scriptFile; JS::RootedValue settings(rq.cx); - scriptInterface.GetProperty(attribs, "script", scriptFile); - scriptInterface.GetProperty(attribs, "settings", &settings); + Script::GetProperty(rq, attribs, "script", scriptFile); + Script::GetProperty(rq, attribs, "settings", &settings); m_World->RegisterInitRMS(scriptFile, *scriptInterface.GetContext(), settings, m_PlayerID); } @@ -256,8 +256,8 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved { std::wstring mapFile; JS::RootedValue settings(rq.cx); - scriptInterface.GetProperty(attribs, "map", mapFile); - scriptInterface.GetProperty(attribs, "settings", &settings); + Script::GetProperty(rq, attribs, "map", mapFile); + Script::GetProperty(rq, attribs, "settings", &settings); m_World->RegisterInit(mapFile, *scriptInterface.GetContext(), settings, m_PlayerID); } @@ -333,7 +333,7 @@ PSRETURN CGame::ReallyStartGame() ScriptRequest rq(scriptInterface); JS::RootedValue global(rq.cx, rq.globalValue()); - if (scriptInterface->HasProperty(global, "reallyStartGame")) + if (Script::HasProperty(rq, global, "reallyStartGame")) ScriptFunction::CallVoid(rq, global, "reallyStartGame"); } diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 2fde8fff38..e413ff094d 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -493,18 +493,18 @@ void InitPsAutostart(bool networked, JS::HandleValue attrs) ScriptRequest rq(scriptInterface); JS::RootedValue playerAssignments(rq.cx); - ScriptInterface::CreateObject(rq, &playerAssignments); + Script::CreateObject(rq, &playerAssignments); if (!networked) { JS::RootedValue localPlayer(rq.cx); - ScriptInterface::CreateObject(rq, &localPlayer, "player", g_Game->GetPlayerID()); - scriptInterface.SetProperty(playerAssignments, "local", localPlayer); + Script::CreateObject(rq, &localPlayer, "player", g_Game->GetPlayerID()); + Script::SetProperty(rq, playerAssignments, "local", localPlayer); } JS::RootedValue sessionInitData(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &sessionInitData, "attribs", attrs, @@ -1076,9 +1076,9 @@ void InitGraphics(const CmdLineArgs& args, int flags, const std::vector& i JS::RootedValue data(rq.cx); if (g_GUI) { - ScriptInterface::CreateObject(rq, &data, "isStartup", true); + Script::CreateObject(rq, &data, "isStartup", true); if (!installedMods.empty()) - scriptInterface->SetProperty(data, "installedMods", installedMods); + Script::SetProperty(rq, data, "installedMods", installedMods); } InitPs(setup_gui, installedMods.empty() ? L"page_pregame.xml" : L"page_modmod.xml", g_GUI->GetScriptInterface().get(), data); } @@ -1237,9 +1237,9 @@ bool Autostart(const CmdLineArgs& args) JS::RootedValue settings(rq.cx); JS::RootedValue playerData(rq.cx); - ScriptInterface::CreateObject(rq, &attrs); - ScriptInterface::CreateObject(rq, &settings); - ScriptInterface::CreateArray(rq, &playerData); + Script::CreateObject(rq, &attrs); + Script::CreateObject(rq, &settings); + Script::CreateArray(rq, &playerData); // The directory in front of the actual map name indicates which type // of map is being loaded. Drawback of this approach is the association @@ -1256,12 +1256,12 @@ bool Autostart(const CmdLineArgs& args) std::wstring scriptPath = L"maps/" + autoStartName.FromUTF8() + L".json"; JS::RootedValue scriptData(rq.cx); scriptInterface.ReadJSONFile(scriptPath, &scriptData); - if (!scriptData.isUndefined() && scriptInterface.GetProperty(scriptData, "settings", &settings)) + if (!scriptData.isUndefined() && Script::GetProperty(rq, scriptData, "settings", &settings)) { // JSON loaded ok - copy script name over to game attributes std::wstring scriptFile; - scriptInterface.GetProperty(settings, "Script", scriptFile); - scriptInterface.SetProperty(attrs, "script", scriptFile); // RMS filename + Script::GetProperty(rq, settings, "Script", scriptFile); + Script::SetProperty(rq, attrs, "script", scriptFile); // RMS filename } else { @@ -1278,7 +1278,7 @@ bool Autostart(const CmdLineArgs& args) mapSize = size.ToUInt(); } - scriptInterface.SetProperty(settings, "Size", mapSize); // Random map size (in patches) + Script::SetProperty(rq, settings, "Size", mapSize); // Random map size (in patches) // Get optional number of players (default 2) size_t numPlayers = 2; @@ -1295,9 +1295,9 @@ bool Autostart(const CmdLineArgs& args) // We could load player_defaults.json here, but that would complicate the logic // even more and autostart is only intended for developers anyway - ScriptInterface::CreateObject(rq, &player, "Civ", "athen"); + Script::CreateObject(rq, &player, "Civ", "athen"); - scriptInterface.SetPropertyInt(playerData, i, player); + Script::SetPropertyInt(rq, playerData, i, player); } mapType = "random"; } @@ -1311,7 +1311,7 @@ bool Autostart(const CmdLineArgs& args) // Initialize the playerData array being modified by autostart // with the real map data, so sensible values are present: - scriptInterface.GetProperty(settings, "PlayerData", &playerData); + Script::GetProperty(rq, settings, "PlayerData", &playerData); if (mapDirectory == L"scenarios") mapType = "scenario"; @@ -1324,10 +1324,10 @@ bool Autostart(const CmdLineArgs& args) throw PSERROR_Game_World_MapLoadFailed("Unrecognized map type.\nConsult readme.txt for the currently supported types."); } - scriptInterface.SetProperty(attrs, "mapType", mapType); - scriptInterface.SetProperty(attrs, "map", "maps/" + autoStartName); - scriptInterface.SetProperty(settings, "mapType", mapType); - scriptInterface.SetProperty(settings, "CheatsEnabled", true); + Script::SetProperty(rq, attrs, "mapType", mapType); + Script::SetProperty(rq, attrs, "map", "maps/" + autoStartName); + Script::SetProperty(rq, settings, "mapType", mapType); + Script::SetProperty(rq, settings, "CheatsEnabled", true); // The seed is used for both random map generation and simulation u32 seed = 0; @@ -1339,7 +1339,7 @@ bool Autostart(const CmdLineArgs& args) else seed = seedArg.ToULong(); } - scriptInterface.SetProperty(settings, "Seed", seed); + Script::SetProperty(rq, settings, "Seed", seed); // Set seed for AIs u32 aiseed = 0; @@ -1351,14 +1351,14 @@ bool Autostart(const CmdLineArgs& args) else aiseed = seedArg.ToULong(); } - scriptInterface.SetProperty(settings, "AISeed", aiseed); + Script::SetProperty(rq, settings, "AISeed", aiseed); // Set player data for AIs // attrs.settings = { PlayerData: [ { AI: ... }, ... ] } // or = { PlayerData: [ null, { AI: ... }, ... ] } when gaia set int offset = 1; JS::RootedValue player(rq.cx); - if (scriptInterface.GetPropertyInt(playerData, 0, &player) && player.isNull()) + if (Script::GetPropertyInt(rq, playerData, 0, &player) && player.isNull()) offset = 0; // Set teams @@ -1371,7 +1371,7 @@ bool Autostart(const CmdLineArgs& args) // Instead of overwriting existing player data, modify the array JS::RootedValue currentPlayer(rq.cx); - if (!scriptInterface.GetPropertyInt(playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) + if (!Script::GetPropertyInt(rq, playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) { if (mapDirectory == L"skirmishes") { @@ -1379,19 +1379,19 @@ bool Autostart(const CmdLineArgs& args) LOGWARNING("Autostart: Invalid player %d in autostart-team option", playerID); continue; } - ScriptInterface::CreateObject(rq, ¤tPlayer); + Script::CreateObject(rq, ¤tPlayer); } int teamID = civArgs[i].AfterFirst(":").ToInt() - 1; - scriptInterface.SetProperty(currentPlayer, "Team", teamID); - scriptInterface.SetPropertyInt(playerData, playerID-offset, currentPlayer); + Script::SetProperty(rq, currentPlayer, "Team", teamID); + Script::SetPropertyInt(rq, playerData, playerID-offset, currentPlayer); } } int ceasefire = 0; if (args.Has("autostart-ceasefire")) ceasefire = args.Get("autostart-ceasefire").ToInt(); - scriptInterface.SetProperty(settings, "Ceasefire", ceasefire); + Script::SetProperty(rq, settings, "Ceasefire", ceasefire); if (args.Has("autostart-ai")) { @@ -1402,7 +1402,7 @@ bool Autostart(const CmdLineArgs& args) // Instead of overwriting existing player data, modify the array JS::RootedValue currentPlayer(rq.cx); - if (!scriptInterface.GetPropertyInt(playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) + if (!Script::GetPropertyInt(rq, playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) { if (mapDirectory == L"scenarios" || mapDirectory == L"skirmishes") { @@ -1410,13 +1410,13 @@ bool Autostart(const CmdLineArgs& args) LOGWARNING("Autostart: Invalid player %d in autostart-ai option", playerID); continue; } - ScriptInterface::CreateObject(rq, ¤tPlayer); + Script::CreateObject(rq, ¤tPlayer); } - scriptInterface.SetProperty(currentPlayer, "AI", aiArgs[i].AfterFirst(":")); - scriptInterface.SetProperty(currentPlayer, "AIDiff", 3); - scriptInterface.SetProperty(currentPlayer, "AIBehavior", "balanced"); - scriptInterface.SetPropertyInt(playerData, playerID-offset, currentPlayer); + Script::SetProperty(rq, currentPlayer, "AI", aiArgs[i].AfterFirst(":")); + Script::SetProperty(rq, currentPlayer, "AIDiff", 3); + Script::SetProperty(rq, currentPlayer, "AIBehavior", "balanced"); + Script::SetPropertyInt(rq, playerData, playerID-offset, currentPlayer); } } // Set AI difficulty @@ -1429,7 +1429,7 @@ bool Autostart(const CmdLineArgs& args) // Instead of overwriting existing player data, modify the array JS::RootedValue currentPlayer(rq.cx); - if (!scriptInterface.GetPropertyInt(playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) + if (!Script::GetPropertyInt(rq, playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) { if (mapDirectory == L"scenarios" || mapDirectory == L"skirmishes") { @@ -1437,11 +1437,11 @@ bool Autostart(const CmdLineArgs& args) LOGWARNING("Autostart: Invalid player %d in autostart-aidiff option", playerID); continue; } - ScriptInterface::CreateObject(rq, ¤tPlayer); + Script::CreateObject(rq, ¤tPlayer); } - scriptInterface.SetProperty(currentPlayer, "AIDiff", civArgs[i].AfterFirst(":").ToInt()); - scriptInterface.SetPropertyInt(playerData, playerID-offset, currentPlayer); + Script::SetProperty(rq, currentPlayer, "AIDiff", civArgs[i].AfterFirst(":").ToInt()); + Script::SetPropertyInt(rq, playerData, playerID-offset, currentPlayer); } } // Set player data for Civs @@ -1456,7 +1456,7 @@ bool Autostart(const CmdLineArgs& args) // Instead of overwriting existing player data, modify the array JS::RootedValue currentPlayer(rq.cx); - if (!scriptInterface.GetPropertyInt(playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) + if (!Script::GetPropertyInt(rq, playerData, playerID-offset, ¤tPlayer) || currentPlayer.isUndefined()) { if (mapDirectory == L"skirmishes") { @@ -1464,11 +1464,11 @@ bool Autostart(const CmdLineArgs& args) LOGWARNING("Autostart: Invalid player %d in autostart-civ option", playerID); continue; } - ScriptInterface::CreateObject(rq, ¤tPlayer); + Script::CreateObject(rq, ¤tPlayer); } - scriptInterface.SetProperty(currentPlayer, "Civ", civArgs[i].AfterFirst(":")); - scriptInterface.SetPropertyInt(playerData, playerID-offset, currentPlayer); + Script::SetProperty(rq, currentPlayer, "Civ", civArgs[i].AfterFirst(":")); + Script::SetPropertyInt(rq, playerData, playerID-offset, currentPlayer); } } else @@ -1476,10 +1476,10 @@ bool Autostart(const CmdLineArgs& args) } // Add player data to map settings - scriptInterface.SetProperty(settings, "PlayerData", playerData); + Script::SetProperty(rq, settings, "PlayerData", playerData); // Add map settings to game attributes - scriptInterface.SetProperty(attrs, "settings", settings); + Script::SetProperty(rq, attrs, "settings", settings); // Get optional playername CStrW userName = L"anonymous"; @@ -1490,9 +1490,9 @@ bool Autostart(const CmdLineArgs& args) std::vector triggerScriptsVector; JS::RootedValue triggerScripts(rq.cx); - if (scriptInterface.HasProperty(settings, "TriggerScripts")) + if (Script::HasProperty(rq, settings, "TriggerScripts")) { - scriptInterface.GetProperty(settings, "TriggerScripts", &triggerScripts); + Script::GetProperty(rq, settings, "TriggerScripts", &triggerScripts); Script::FromJSVal(rq, triggerScripts, triggerScriptsVector); } @@ -1509,7 +1509,7 @@ bool Autostart(const CmdLineArgs& args) if (victoryConditions.size() == 1 && victoryConditions[0] == "endless") victoryConditions.clear(); - scriptInterface.SetProperty(settings, "VictoryConditions", victoryConditions); + Script::SetProperty(rq, settings, "VictoryConditions", victoryConditions); for (const CStr& victory : victoryConditions) { @@ -1519,8 +1519,8 @@ bool Autostart(const CmdLineArgs& args) CStrW scriptPath = L"simulation/data/settings/victory_conditions/" + victory.FromUTF8() + L".json"; scriptInterface.ReadJSONFile(scriptPath, &scriptData); - if (!scriptData.isUndefined() && scriptInterface.GetProperty(scriptData, "Data", &data) && !data.isUndefined() - && scriptInterface.GetProperty(data, "Scripts", &victoryScripts) && !victoryScripts.isUndefined()) + if (!scriptData.isUndefined() && Script::GetProperty(rq, scriptData, "Data", &data) && !data.isUndefined() + && Script::GetProperty(rq, data, "Scripts", &victoryScripts) && !victoryScripts.isUndefined()) { std::vector victoryScriptsVector; Script::FromJSVal(rq, victoryScripts, victoryScriptsVector); @@ -1534,22 +1534,22 @@ bool Autostart(const CmdLineArgs& args) } Script::ToJSVal(rq, &triggerScripts, triggerScriptsVector); - scriptInterface.SetProperty(settings, "TriggerScripts", triggerScripts); + Script::SetProperty(rq, settings, "TriggerScripts", triggerScripts); int wonderDuration = 10; if (args.Has("autostart-wonderduration")) wonderDuration = args.Get("autostart-wonderduration").ToInt(); - scriptInterface.SetProperty(settings, "WonderDuration", wonderDuration); + Script::SetProperty(rq, settings, "WonderDuration", wonderDuration); int relicDuration = 10; if (args.Has("autostart-relicduration")) relicDuration = args.Get("autostart-relicduration").ToInt(); - scriptInterface.SetProperty(settings, "RelicDuration", relicDuration); + Script::SetProperty(rq, settings, "RelicDuration", relicDuration); int relicCount = 2; if (args.Has("autostart-reliccount")) relicCount = args.Get("autostart-reliccount").ToInt(); - scriptInterface.SetProperty(settings, "RelicCount", relicCount); + Script::SetProperty(rq, settings, "RelicCount", relicCount); if (args.Has("autostart-host")) { @@ -1639,7 +1639,7 @@ void CancelLoad(const CStrW& message) if (g_GUI && g_GUI->GetPageCount() && - pScriptInterface->HasProperty(global, "cancelOnLoadGameError")) + Script::HasProperty(rq, global, "cancelOnLoadGameError")) ScriptFunction::CallVoid(rq, global, "cancelOnLoadGameError", message); } diff --git a/source/ps/GameSetup/HWDetect.cpp b/source/ps/GameSetup/HWDetect.cpp index 17f9c87cfd..cb4739cf98 100644 --- a/source/ps/GameSetup/HWDetect.cpp +++ b/source/ps/GameSetup/HWDetect.cpp @@ -44,6 +44,7 @@ #include "ps/UserReport.h" #include "ps/VideoMode.h" #include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptInterface.h" #if OS_LINUX @@ -75,8 +76,8 @@ #endif -static void ReportSDL(const ScriptInterface& scriptInterface, JS::HandleValue settings); -static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleValue settings); +static void ReportSDL(const ScriptRequest& rq, JS::HandleValue settings); +static void ReportGLLimits(const ScriptRequest& rq, JS::HandleValue settings); void SetDisableAudio(bool disabled) { @@ -114,61 +115,61 @@ void RunHardwareDetection() // includes some fields that aren't directly useful for the hwdetect script) JS::RootedValue settings(rq.cx); - ScriptInterface::CreateObject(rq, &settings); + Script::CreateObject(rq, &settings); - scriptInterface.SetProperty(settings, "os_unix", OS_UNIX); - scriptInterface.SetProperty(settings, "os_bsd", OS_BSD); - scriptInterface.SetProperty(settings, "os_linux", OS_LINUX); - scriptInterface.SetProperty(settings, "os_android", OS_ANDROID); - scriptInterface.SetProperty(settings, "os_macosx", OS_MACOSX); - scriptInterface.SetProperty(settings, "os_win", OS_WIN); + Script::SetProperty(rq, settings, "os_unix", OS_UNIX); + Script::SetProperty(rq, settings, "os_bsd", OS_BSD); + Script::SetProperty(rq, settings, "os_linux", OS_LINUX); + Script::SetProperty(rq, settings, "os_android", OS_ANDROID); + Script::SetProperty(rq, settings, "os_macosx", OS_MACOSX); + Script::SetProperty(rq, settings, "os_win", OS_WIN); - scriptInterface.SetProperty(settings, "arch_ia32", ARCH_IA32); - scriptInterface.SetProperty(settings, "arch_amd64", ARCH_AMD64); - scriptInterface.SetProperty(settings, "arch_arm", ARCH_ARM); - scriptInterface.SetProperty(settings, "arch_aarch64", ARCH_AARCH64); - scriptInterface.SetProperty(settings, "arch_e2k", ARCH_E2K); - scriptInterface.SetProperty(settings, "arch_ppc64", ARCH_PPC64); + Script::SetProperty(rq, settings, "arch_ia32", ARCH_IA32); + Script::SetProperty(rq, settings, "arch_amd64", ARCH_AMD64); + Script::SetProperty(rq, settings, "arch_arm", ARCH_ARM); + Script::SetProperty(rq, settings, "arch_aarch64", ARCH_AARCH64); + Script::SetProperty(rq, settings, "arch_e2k", ARCH_E2K); + Script::SetProperty(rq, settings, "arch_ppc64", ARCH_PPC64); #ifdef NDEBUG - scriptInterface.SetProperty(settings, "build_debug", 0); + Script::SetProperty(rq, settings, "build_debug", 0); #else - scriptInterface.SetProperty(settings, "build_debug", 1); + Script::SetProperty(rq, settings, "build_debug", 1); #endif - scriptInterface.SetProperty(settings, "build_opengles", CONFIG2_GLES); + Script::SetProperty(rq, settings, "build_opengles", CONFIG2_GLES); - scriptInterface.SetProperty(settings, "build_datetime", std::string(__DATE__ " " __TIME__)); - scriptInterface.SetProperty(settings, "build_revision", std::wstring(svn_revision)); + Script::SetProperty(rq, settings, "build_datetime", std::string(__DATE__ " " __TIME__)); + Script::SetProperty(rq, settings, "build_revision", std::wstring(svn_revision)); - scriptInterface.SetProperty(settings, "build_msc", (int)MSC_VERSION); - scriptInterface.SetProperty(settings, "build_icc", (int)ICC_VERSION); - scriptInterface.SetProperty(settings, "build_gcc", (int)GCC_VERSION); - scriptInterface.SetProperty(settings, "build_clang", (int)CLANG_VERSION); + Script::SetProperty(rq, settings, "build_msc", (int)MSC_VERSION); + Script::SetProperty(rq, settings, "build_icc", (int)ICC_VERSION); + Script::SetProperty(rq, settings, "build_gcc", (int)GCC_VERSION); + Script::SetProperty(rq, settings, "build_clang", (int)CLANG_VERSION); - scriptInterface.SetProperty(settings, "gfx_card", gfx::CardName()); - scriptInterface.SetProperty(settings, "gfx_drv_ver", gfx::DriverInfo()); + Script::SetProperty(rq, settings, "gfx_card", gfx::CardName()); + Script::SetProperty(rq, settings, "gfx_drv_ver", gfx::DriverInfo()); #if CONFIG2_AUDIO if (g_SoundManager) { - scriptInterface.SetProperty(settings, "snd_card", g_SoundManager->GetSoundCardNames()); - scriptInterface.SetProperty(settings, "snd_drv_ver", g_SoundManager->GetOpenALVersion()); + Script::SetProperty(rq, settings, "snd_card", g_SoundManager->GetSoundCardNames()); + Script::SetProperty(rq, settings, "snd_drv_ver", g_SoundManager->GetOpenALVersion()); } #endif ReportSDL(scriptInterface, settings); ReportGLLimits(scriptInterface, settings); - scriptInterface.SetProperty(settings, "video_desktop_xres", g_VideoMode.GetDesktopXRes()); - scriptInterface.SetProperty(settings, "video_desktop_yres", g_VideoMode.GetDesktopYRes()); - scriptInterface.SetProperty(settings, "video_desktop_bpp", g_VideoMode.GetDesktopBPP()); - scriptInterface.SetProperty(settings, "video_desktop_freq", g_VideoMode.GetDesktopFreq()); + Script::SetProperty(rq, settings, "video_desktop_xres", g_VideoMode.GetDesktopXRes()); + Script::SetProperty(rq, settings, "video_desktop_yres", g_VideoMode.GetDesktopYRes()); + Script::SetProperty(rq, settings, "video_desktop_bpp", g_VideoMode.GetDesktopBPP()); + Script::SetProperty(rq, settings, "video_desktop_freq", g_VideoMode.GetDesktopFreq()); struct utsname un; uname(&un); - scriptInterface.SetProperty(settings, "uname_sysname", std::string(un.sysname)); - scriptInterface.SetProperty(settings, "uname_release", std::string(un.release)); - scriptInterface.SetProperty(settings, "uname_version", std::string(un.version)); - scriptInterface.SetProperty(settings, "uname_machine", std::string(un.machine)); + Script::SetProperty(rq, settings, "uname_sysname", std::string(un.sysname)); + Script::SetProperty(rq, settings, "uname_release", std::string(un.release)); + Script::SetProperty(rq, settings, "uname_version", std::string(un.version)); + Script::SetProperty(rq, settings, "uname_machine", std::string(un.machine)); #if OS_LINUX { @@ -176,43 +177,43 @@ void RunHardwareDetection() if (ifs.good()) { std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); - scriptInterface.SetProperty(settings, "linux_release", str); + Script::SetProperty(rq, settings, "linux_release", str); } } #endif - scriptInterface.SetProperty(settings, "cpu_identifier", std::string(cpu_IdentifierString())); - scriptInterface.SetProperty(settings, "cpu_frequency", os_cpu_ClockFrequency()); - scriptInterface.SetProperty(settings, "cpu_pagesize", (u32)os_cpu_PageSize()); - scriptInterface.SetProperty(settings, "cpu_largepagesize", (u32)os_cpu_LargePageSize()); - scriptInterface.SetProperty(settings, "cpu_numprocs", (u32)os_cpu_NumProcessors()); + Script::SetProperty(rq, settings, "cpu_identifier", std::string(cpu_IdentifierString())); + Script::SetProperty(rq, settings, "cpu_frequency", os_cpu_ClockFrequency()); + Script::SetProperty(rq, settings, "cpu_pagesize", (u32)os_cpu_PageSize()); + Script::SetProperty(rq, settings, "cpu_largepagesize", (u32)os_cpu_LargePageSize()); + Script::SetProperty(rq, settings, "cpu_numprocs", (u32)os_cpu_NumProcessors()); #if ARCH_X86_X64 - scriptInterface.SetProperty(settings, "cpu_numpackages", (u32)topology::NumPackages()); - scriptInterface.SetProperty(settings, "cpu_coresperpackage", (u32)topology::CoresPerPackage()); - scriptInterface.SetProperty(settings, "cpu_logicalpercore", (u32)topology::LogicalPerCore()); + Script::SetProperty(rq, settings, "cpu_numpackages", (u32)topology::NumPackages()); + Script::SetProperty(rq, settings, "cpu_coresperpackage", (u32)topology::CoresPerPackage()); + Script::SetProperty(rq, settings, "cpu_logicalpercore", (u32)topology::LogicalPerCore()); #endif - scriptInterface.SetProperty(settings, "numa_numnodes", (u32)numa_NumNodes()); - scriptInterface.SetProperty(settings, "numa_factor", numa_Factor()); - scriptInterface.SetProperty(settings, "numa_interleaved", numa_IsMemoryInterleaved()); + Script::SetProperty(rq, settings, "numa_numnodes", (u32)numa_NumNodes()); + Script::SetProperty(rq, settings, "numa_factor", numa_Factor()); + Script::SetProperty(rq, settings, "numa_interleaved", numa_IsMemoryInterleaved()); - scriptInterface.SetProperty(settings, "ram_total", (u32)os_cpu_MemorySize()); - scriptInterface.SetProperty(settings, "ram_total_os", (u32)os_cpu_QueryMemorySize()); + Script::SetProperty(rq, settings, "ram_total", (u32)os_cpu_MemorySize()); + Script::SetProperty(rq, settings, "ram_total_os", (u32)os_cpu_QueryMemorySize()); #if ARCH_X86_X64 - scriptInterface.SetProperty(settings, "x86_vendor", (u32)x86_x64::Vendor()); - scriptInterface.SetProperty(settings, "x86_model", (u32)x86_x64::Model()); - scriptInterface.SetProperty(settings, "x86_family", (u32)x86_x64::Family()); + Script::SetProperty(rq, settings, "x86_vendor", (u32)x86_x64::Vendor()); + Script::SetProperty(rq, settings, "x86_model", (u32)x86_x64::Model()); + Script::SetProperty(rq, settings, "x86_family", (u32)x86_x64::Family()); u32 caps0, caps1, caps2, caps3; x86_x64::GetCapBits(&caps0, &caps1, &caps2, &caps3); - scriptInterface.SetProperty(settings, "x86_caps[0]", caps0); - scriptInterface.SetProperty(settings, "x86_caps[1]", caps1); - scriptInterface.SetProperty(settings, "x86_caps[2]", caps2); - scriptInterface.SetProperty(settings, "x86_caps[3]", caps3); + Script::SetProperty(rq, settings, "x86_caps[0]", caps0); + Script::SetProperty(rq, settings, "x86_caps[1]", caps1); + Script::SetProperty(rq, settings, "x86_caps[2]", caps2); + Script::SetProperty(rq, settings, "x86_caps[3]", caps3); #endif - scriptInterface.SetProperty(settings, "timer_resolution", timer_Resolution()); + Script::SetProperty(rq, settings, "timer_resolution", timer_Resolution()); // The version should be increased for every meaningful change. const int reportVersion = 14; @@ -229,25 +230,25 @@ void RunHardwareDetection() ScriptFunction::CallVoid(rq, global, "RunHardwareDetection", settings); } -static void ReportSDL(const ScriptInterface& scriptInterface, JS::HandleValue settings) +static void ReportSDL(const ScriptRequest& rq, JS::HandleValue settings) { SDL_version build, runtime; SDL_VERSION(&build); char version[16]; snprintf(version, ARRAY_SIZE(version), "%d.%d.%d", build.major, build.minor, build.patch); - scriptInterface.SetProperty(settings, "sdl_build_version", version); + Script::SetProperty(rq, settings, "sdl_build_version", version); SDL_GetVersion(&runtime); snprintf(version, ARRAY_SIZE(version), "%d.%d.%d", runtime.major, runtime.minor, runtime.patch); - scriptInterface.SetProperty(settings, "sdl_runtime_version", version); + Script::SetProperty(rq, settings, "sdl_runtime_version", version); // This is null in atlas (and further the call triggers an assertion). const char* backend = g_VideoMode.GetWindow() ? GetSDLSubsystem(g_VideoMode.GetWindow()) : "none"; - scriptInterface.SetProperty(settings, "sdl_video_backend", backend ? backend : "unknown"); + Script::SetProperty(rq, settings, "sdl_video_backend", backend ? backend : "unknown"); } -static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleValue settings) +static void ReportGLLimits(const ScriptRequest& rq, JS::HandleValue settings) { const char* errstr = "(error)"; @@ -255,20 +256,20 @@ static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleVal GLint i = -1; \ glGetIntegerv(GL_##id, &i); \ if (ogl_SquelchError(GL_INVALID_ENUM)) \ - scriptInterface.SetProperty(settings, "GL_" #id, errstr); \ + Script::SetProperty(rq, settings, "GL_" #id, errstr); \ else \ - scriptInterface.SetProperty(settings, "GL_" #id, i); \ + Script::SetProperty(rq, settings, "GL_" #id, i); \ } while (false) #define INTEGER2(id) do { \ GLint i[2] = { -1, -1 }; \ glGetIntegerv(GL_##id, i); \ if (ogl_SquelchError(GL_INVALID_ENUM)) { \ - scriptInterface.SetProperty(settings, "GL_" #id "[0]", errstr); \ - scriptInterface.SetProperty(settings, "GL_" #id "[1]", errstr); \ + Script::SetProperty(rq, settings, "GL_" #id "[0]", errstr); \ + Script::SetProperty(rq, settings, "GL_" #id "[1]", errstr); \ } else { \ - scriptInterface.SetProperty(settings, "GL_" #id "[0]", i[0]); \ - scriptInterface.SetProperty(settings, "GL_" #id "[1]", i[1]); \ + Script::SetProperty(rq, settings, "GL_" #id "[0]", i[0]); \ + Script::SetProperty(rq, settings, "GL_" #id "[1]", i[1]); \ } \ } while (false) @@ -276,20 +277,20 @@ static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleVal GLfloat f = std::numeric_limits::quiet_NaN(); \ glGetFloatv(GL_##id, &f); \ if (ogl_SquelchError(GL_INVALID_ENUM)) \ - scriptInterface.SetProperty(settings, "GL_" #id, errstr); \ + Script::SetProperty(rq, settings, "GL_" #id, errstr); \ else \ - scriptInterface.SetProperty(settings, "GL_" #id, f); \ + Script::SetProperty(rq, settings, "GL_" #id, f); \ } while (false) #define FLOAT2(id) do { \ GLfloat f[2] = { std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN() }; \ glGetFloatv(GL_##id, f); \ if (ogl_SquelchError(GL_INVALID_ENUM)) { \ - scriptInterface.SetProperty(settings, "GL_" #id "[0]", errstr); \ - scriptInterface.SetProperty(settings, "GL_" #id "[1]", errstr); \ + Script::SetProperty(rq, settings, "GL_" #id "[0]", errstr); \ + Script::SetProperty(rq, settings, "GL_" #id "[1]", errstr); \ } else { \ - scriptInterface.SetProperty(settings, "GL_" #id "[0]", f[0]); \ - scriptInterface.SetProperty(settings, "GL_" #id "[1]", f[1]); \ + Script::SetProperty(rq, settings, "GL_" #id "[0]", f[0]); \ + Script::SetProperty(rq, settings, "GL_" #id "[1]", f[1]); \ } \ } while (false) @@ -297,34 +298,34 @@ static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleVal const char* c = (const char*)glGetString(GL_##id); \ if (!c) c = ""; \ if (ogl_SquelchError(GL_INVALID_ENUM)) c = errstr; \ - scriptInterface.SetProperty(settings, "GL_" #id, std::string(c)); \ + Script::SetProperty(rq, settings, "GL_" #id, std::string(c)); \ } while (false) #define QUERY(target, pname) do { \ GLint i = -1; \ pglGetQueryivARB(GL_##target, GL_##pname, &i); \ if (ogl_SquelchError(GL_INVALID_ENUM)) \ - scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, errstr); \ + Script::SetProperty(rq, settings, "GL_" #target ".GL_" #pname, errstr); \ else \ - scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, i); \ + Script::SetProperty(rq, settings, "GL_" #target ".GL_" #pname, i); \ } while (false) #define VERTEXPROGRAM(id) do { \ GLint i = -1; \ pglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \ if (ogl_SquelchError(GL_INVALID_ENUM)) \ - scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \ + Script::SetProperty(rq, settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \ else \ - scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \ + Script::SetProperty(rq, settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \ } while (false) #define FRAGMENTPROGRAM(id) do { \ GLint i = -1; \ pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \ if (ogl_SquelchError(GL_INVALID_ENUM)) \ - scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \ + Script::SetProperty(rq, settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \ else \ - scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \ + Script::SetProperty(rq, settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \ } while (false) #define BOOL(id) INTEGER(id) @@ -599,30 +600,30 @@ static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleVal #define GLXQCR_INTEGER(id) do { \ unsigned int i = UINT_MAX; \ if (pglXQueryCurrentRendererIntegerMESA(id, &i)) \ - scriptInterface.SetProperty(settings, #id, i); \ + Script::SetProperty(rq, settings, #id, i); \ } while (false) #define GLXQCR_INTEGER2(id) do { \ unsigned int i[2] = { UINT_MAX, UINT_MAX }; \ if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \ - scriptInterface.SetProperty(settings, #id "[0]", i[0]); \ - scriptInterface.SetProperty(settings, #id "[1]", i[1]); \ + Script::SetProperty(rq, settings, #id "[0]", i[0]); \ + Script::SetProperty(rq, settings, #id "[1]", i[1]); \ } \ } while (false) #define GLXQCR_INTEGER3(id) do { \ unsigned int i[3] = { UINT_MAX, UINT_MAX, UINT_MAX }; \ if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \ - scriptInterface.SetProperty(settings, #id "[0]", i[0]); \ - scriptInterface.SetProperty(settings, #id "[1]", i[1]); \ - scriptInterface.SetProperty(settings, #id "[2]", i[2]); \ + Script::SetProperty(rq, settings, #id "[0]", i[0]); \ + Script::SetProperty(rq, settings, #id "[1]", i[1]); \ + Script::SetProperty(rq, settings, #id "[2]", i[2]); \ } \ } while (false) #define GLXQCR_STRING(id) do { \ const char* str = pglXQueryCurrentRendererStringMESA(id); \ if (str) \ - scriptInterface.SetProperty(settings, #id ".string", str); \ + Script::SetProperty(rq, settings, #id ".string", str); \ } while (false) @@ -636,7 +637,7 @@ static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleVal const char* glxexts = glXQueryExtensionsString(dpy, scrnum); - scriptInterface.SetProperty(settings, "glx_extensions", glxexts); + Script::SetProperty(rq, settings, "glx_extensions", glxexts); if (strstr(glxexts, "GLX_MESA_query_renderer") && pglXQueryCurrentRendererIntegerMESA && pglXQueryCurrentRendererStringMESA) { diff --git a/source/ps/Mod.cpp b/source/ps/Mod.cpp index a3c3b3d0ec..f33125e818 100644 --- a/source/ps/Mod.cpp +++ b/source/ps/Mod.cpp @@ -26,6 +26,7 @@ #include "ps/GameSetup/GameSetup.h" #include "ps/GameSetup/Paths.h" #include "ps/Pyrogenesis.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptInterface.h" #include @@ -182,12 +183,12 @@ bool Mod::AreModsCompatible(const ScriptInterface& scriptInterface, const std::v JS::RootedValue modData(rq.cx); // Requested mod is not available, fail - if (!scriptInterface.HasProperty(availableMods, mod.c_str())) + if (!Script::HasProperty(rq, availableMods, mod.c_str())) { g_incompatibleMods.push_back(mod); continue; } - if (!scriptInterface.GetProperty(availableMods, mod.c_str(), &modData)) + if (!Script::GetProperty(rq, availableMods, mod.c_str(), &modData)) { g_incompatibleMods.push_back(mod); continue; @@ -196,9 +197,9 @@ bool Mod::AreModsCompatible(const ScriptInterface& scriptInterface, const std::v std::vector dependencies; CStr version; CStr name; - scriptInterface.GetProperty(modData, "dependencies", dependencies); - scriptInterface.GetProperty(modData, "version", version); - scriptInterface.GetProperty(modData, "name", name); + Script::GetProperty(rq, modData, "dependencies", dependencies); + Script::GetProperty(rq, modData, "version", version); + Script::GetProperty(rq, modData, "name", name); modNameVersions.emplace(name, version); modDependencies.emplace(mod, dependencies); @@ -303,8 +304,8 @@ void Mod::CacheEnabledModVersions(const shared_ptr& scriptContext CStr version; JS::RootedValue modData(rq.cx); - if (scriptInterface.GetProperty(availableMods, mod.c_str(), &modData)) - scriptInterface.GetProperty(modData, "version", version); + if (Script::GetProperty(rq, availableMods, mod.c_str(), &modData)) + Script::GetProperty(rq, modData, "version", version); g_LoadedModVersions.push_back({mod, version}); } @@ -325,13 +326,13 @@ JS::Value Mod::GetEngineInfo(const ScriptInterface& scriptInterface) JS::RootedValue mods(rq.cx, Mod::GetLoadedModsWithVersions(scriptInterface)); JS::RootedValue metainfo(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &metainfo, "engine_version", engine_version, "mods", mods); - scriptInterface.FreezeObject(metainfo, true); + Script::FreezeObject(rq, metainfo, true); return metainfo; } diff --git a/source/ps/ProfileViewer.cpp b/source/ps/ProfileViewer.cpp index 4affbbc1df..b50f17e372 100644 --- a/source/ps/ProfileViewer.cpp +++ b/source/ps/ProfileViewer.cpp @@ -35,6 +35,7 @@ #include "ps/Profile.h" #include "ps/Pyrogenesis.h" #include "renderer/Renderer.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptInterface.h" #include @@ -508,13 +509,13 @@ namespace ScriptRequest rq(m_ScriptInterface); JS::RootedValue t(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &t, "cols", DumpCols(table), "data", DumpRows(table)); - m_ScriptInterface.SetProperty(m_Root, table->GetTitle().c_str(), t); + Script::SetProperty(rq, m_Root, table->GetTitle().c_str(), t); } std::vector DumpCols(AbstractProfileTable* table) @@ -534,25 +535,25 @@ namespace ScriptRequest rq(m_ScriptInterface); JS::RootedValue data(rq.cx); - ScriptInterface::CreateObject(rq, &data); + Script::CreateObject(rq, &data); const std::vector& columns = table->GetColumns(); for (size_t r = 0; r < table->GetNumberRows(); ++r) { JS::RootedValue row(rq.cx); - ScriptInterface::CreateArray(rq, &row); + Script::CreateArray(rq, &row); - m_ScriptInterface.SetProperty(data, table->GetCellText(r, 0).c_str(), row); + Script::SetProperty(rq, data, table->GetCellText(r, 0).c_str(), row); if (table->GetChild(r)) { JS::RootedValue childRows(rq.cx, DumpRows(table->GetChild(r))); - m_ScriptInterface.SetPropertyInt(row, 0, childRows); + Script::SetPropertyInt(rq, row, 0, childRows); } for (size_t c = 1; c < columns.size(); ++c) - m_ScriptInterface.SetPropertyInt(row, c, table->GetCellText(r, c)); + Script::SetPropertyInt(rq, row, c, table->GetCellText(r, c)); } return data; diff --git a/source/ps/Replay.cpp b/source/ps/Replay.cpp index 1382fa0962..3aa225f01e 100644 --- a/source/ps/Replay.cpp +++ b/source/ps/Replay.cpp @@ -34,6 +34,7 @@ #include "ps/Mod.h" #include "ps/Util.h" #include "ps/VisualReplay.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptContext.h" #include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptStats.h" @@ -67,12 +68,12 @@ void CReplayLogger::StartGame(JS::MutableHandleValue attribs) ScriptRequest rq(m_ScriptInterface); // Add timestamp, since the file-modification-date can change - m_ScriptInterface.SetProperty(attribs, "timestamp", (double)std::time(nullptr)); + Script::SetProperty(rq, attribs, "timestamp", (double)std::time(nullptr)); // Add engine version and currently loaded mods for sanity checks when replaying - m_ScriptInterface.SetProperty(attribs, "engine_version", engine_version); + Script::SetProperty(rq, attribs, "engine_version", engine_version); JS::RootedValue mods(rq.cx, Mod::GetLoadedModsWithVersions(m_ScriptInterface)); - m_ScriptInterface.SetProperty(attribs, "mods", mods); + Script::SetProperty(rq, attribs, "mods", mods); m_Directory = createDateIndexSubdirectory(VisualReplay::GetDirectoryPath()); debug_printf("Writing replay to %s\n", m_Directory.string8().c_str()); @@ -165,7 +166,7 @@ void CReplayPlayer::CheckReplayMods(const ScriptInterface& scriptInterface, JS:: ScriptRequest rq(scriptInterface); std::vector> replayMods; - scriptInterface.GetProperty(attribs, "mods", replayMods); + Script::GetProperty(rq, attribs, "mods", replayMods); std::vector> enabledMods; JS::RootedValue enabledModsJS(rq.cx, Mod::GetLoadedModsWithVersions(scriptInterface)); @@ -265,7 +266,7 @@ void CReplayPlayer::Replay(const bool serializationtest, const int rejointesttur std::getline(*m_Stream, line); JS::RootedValue data(rq.cx); g_Game->GetSimulation2()->GetScriptInterface().ParseJSON(line, &data); - g_Game->GetSimulation2()->GetScriptInterface().FreezeObject(data, true); + Script::FreezeObject(rq, data, true); commands.emplace_back(SimulationCommand(player, rq.cx, data)); } else if (type == "hash" || type == "hash-quick") diff --git a/source/ps/SavedGame.cpp b/source/ps/SavedGame.cpp index 5f089001a1..8d0b6210e3 100644 --- a/source/ps/SavedGame.cpp +++ b/source/ps/SavedGame.cpp @@ -31,6 +31,7 @@ #include "ps/Game.h" #include "ps/Mod.h" #include "ps/Pyrogenesis.h" +#include "scriptinterface/Object.h" #include "scriptinterface/StructuredClone.h" #include "simulation2/Simulation2.h" @@ -83,7 +84,7 @@ Status SavedGames::Save(const CStrW& name, const CStrW& description, CSimulation JS::RootedValue metadata(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &metadata, "engine_version", engine_version, @@ -101,7 +102,7 @@ Status SavedGames::Save(const CStrW& name, const CStrW& description, CSimulation JS::RootedValue cameraMetadata(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &cameraMetadata, "PosX", cameraPosition.X, @@ -111,10 +112,10 @@ Status SavedGames::Save(const CStrW& name, const CStrW& description, CSimulation "RotY", cameraRotation.Y, "Zoom", g_Game->GetView()->GetCameraZoom()); - simulation.GetScriptInterface().SetProperty(guiMetadata, "camera", cameraMetadata); + Script::SetProperty(rq, guiMetadata, "camera", cameraMetadata); - simulation.GetScriptInterface().SetProperty(metadata, "gui", guiMetadata); - simulation.GetScriptInterface().SetProperty(metadata, "description", description); + Script::SetProperty(rq, metadata, "gui", guiMetadata); + Script::SetProperty(rq, metadata, "description", description); std::string metadataString = simulation.GetScriptInterface().StringifyJSON(&metadata, true); @@ -230,7 +231,7 @@ JS::Value SavedGames::GetSavedGames(const ScriptInterface& scriptInterface) ScriptRequest rq(scriptInterface); JS::RootedValue games(rq.cx); - ScriptInterface::CreateArray(rq, &games); + Script::CreateArray(rq, &games); Status err; @@ -266,13 +267,13 @@ JS::Value SavedGames::GetSavedGames(const ScriptInterface& scriptInterface) JS::RootedValue metadata(rq.cx, loader.GetMetadata()); JS::RootedValue game(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &game, "id", pathnames[i].Basename(), "metadata", metadata); - scriptInterface.SetPropertyInt(games, i, game); + Script::SetPropertyInt(rq, games, i, game); } return games; diff --git a/source/ps/VisualReplay.cpp b/source/ps/VisualReplay.cpp index f7cb9fb415..3f08c08e66 100644 --- a/source/ps/VisualReplay.cpp +++ b/source/ps/VisualReplay.cpp @@ -137,9 +137,9 @@ JS::HandleObject VisualReplay::ReloadReplayCache(const ScriptInterface& scriptIn OsPath fileName; double fileSize; double fileMtime; - scriptInterface.GetProperty(replay, "directory", fileName); - scriptInterface.GetProperty(replay, "fileSize", fileSize); - scriptInterface.GetProperty(replay, "fileMTime", fileMtime); + Script::GetProperty(rq, replay, "directory", fileName); + Script::GetProperty(rq, replay, "fileSize", fileSize); + Script::GetProperty(rq, replay, "fileMTime", fileMtime); fileList[fileName] = std::make_tuple(j, fileMtime, fileSize); } @@ -193,7 +193,7 @@ JS::HandleObject VisualReplay::ReloadReplayCache(const ScriptInterface& scriptIn CFileInfo fileInfo; GetFileInfo(replayFile, &fileInfo); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &replayData, "directory", directory.string(), @@ -240,7 +240,7 @@ JS::Value VisualReplay::GetReplays(const ScriptInterface& scriptInterface, bool JS::RootedObject replays(rq.cx, ReloadReplayCache(scriptInterface, compareFiles)); // Only take entries with data JS::RootedValue replaysWithoutNullEntries(rq.cx); - ScriptInterface::CreateArray(rq, &replaysWithoutNullEntries); + Script::CreateArray(rq, &replaysWithoutNullEntries); u32 replaysLength = 0; JS::GetArrayLength(rq.cx, replays, &replaysLength); @@ -248,8 +248,8 @@ JS::Value VisualReplay::GetReplays(const ScriptInterface& scriptInterface, bool { JS::RootedValue replay(rq.cx); JS_GetElement(rq.cx, replays, j, &replay); - if (scriptInterface.HasProperty(replay, "attribs")) - scriptInterface.SetPropertyInt(replaysWithoutNullEntries, i++, replay); + if (Script::HasProperty(rq, replay, "attribs")) + Script::SetPropertyInt(rq, replaysWithoutNullEntries, i++, replay); } return replaysWithoutNullEntries; } @@ -409,7 +409,7 @@ JS::Value VisualReplay::LoadReplayData(const ScriptInterface& scriptInterface, c // Return the actual data JS::RootedValue replayData(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &replayData, "directory", directory.string(), @@ -417,7 +417,7 @@ JS::Value VisualReplay::LoadReplayData(const ScriptInterface& scriptInterface, c "fileMTime", static_cast(fileInfo.MTime()), "duration", duration); - scriptInterface.SetProperty(replayData, "attribs", attribs); + Script::SetProperty(rq, replayData, "attribs", attribs); return replayData; } @@ -436,7 +436,7 @@ JS::Value VisualReplay::GetReplayAttributes(const ScriptInterface& scriptInterfa // Create empty JS object ScriptRequest rq(scriptInterface); JS::RootedValue attribs(rq.cx); - ScriptInterface::CreateObject(rq, &attribs); + Script::CreateObject(rq, &attribs); // Return empty object if file doesn't exist const OsPath replayFile = GetDirectoryPath() / directoryName / L"commands.txt"; diff --git a/source/ps/XMB/XMBStorage.cpp b/source/ps/XMB/XMBStorage.cpp index 04f141500e..c1044d542a 100644 --- a/source/ps/XMB/XMBStorage.cpp +++ b/source/ps/XMB/XMBStorage.cpp @@ -22,6 +22,7 @@ #include "lib/file/io/write_buffer.h" #include "lib/file/vfs/vfs.h" #include "ps/CLogger.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptConversions.h" #include "scriptinterface/ScriptExtraHeaders.h" #include "scriptinterface/ScriptInterface.h" @@ -217,7 +218,7 @@ bool JSNodeData::Setup(XMBStorageWriter& xmb, JS::HandleValue value) return true; std::vector props; - if (!scriptInterface.EnumeratePropertyNames(value, true, props)) + if (!Script::EnumeratePropertyNames(rq, value, true, props)) { LOGERROR("Failed to enumerate component properties."); return false; @@ -246,7 +247,7 @@ bool JSNodeData::Setup(XMBStorageWriter& xmb, JS::HandleValue value) name = std::string_view(prop.c_str()+1, prop.length()-1); JS::RootedValue child(rq.cx); - if (!scriptInterface.GetProperty(value, prop.c_str(), &child)) + if (!Script::GetProperty(rq, value, prop.c_str(), &child)) return false; if (attrib) @@ -278,7 +279,7 @@ bool JSNodeData::Setup(XMBStorageWriter& xmb, JS::HandleValue value) for (size_t i = 0; i < length; ++i) { JS::RootedValue arrayChild(rq.cx); - scriptInterface.GetPropertyInt(child, i, &arrayChild); + Script::GetPropertyInt(rq, child, i, &arrayChild); m_Children.emplace_back(xmb.GetElementName(std::string(name)), arrayChild); } } @@ -297,13 +298,13 @@ bool JSNodeData::Output(WriteBuffer& writeBuffer, JS::HandleValue value) const } case JSTYPE_OBJECT: { - if (!scriptInterface.HasProperty(value, "_string")) + if (!Script::HasProperty(rq, value, "_string")) { writeBuffer.Append("\0\0\0\0", 4); break; } JS::RootedValue actualValue(rq.cx); - if (!scriptInterface.GetProperty(value, "_string", &actualValue)) + if (!Script::GetProperty(rq, value, "_string", &actualValue)) return false; std::string strVal; if (!Script::FromJSVal(rq, actualValue, strVal)) diff --git a/source/ps/scripting/JSInterface_ModIo.cpp b/source/ps/scripting/JSInterface_ModIo.cpp index 567ca2ffea..d3c4c41bfd 100644 --- a/source/ps/scripting/JSInterface_ModIo.cpp +++ b/source/ps/scripting/JSInterface_ModIo.cpp @@ -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 @@ -46,7 +46,7 @@ void StartGetGameId() } // TODO: could provide a FromJSVal for ModIoModData -JS::Value GetMods(const ScriptInterface& scriptInterface) +JS::Value GetMods(const ScriptRequest& rq) { if (!g_ModIo) { @@ -54,24 +54,22 @@ JS::Value GetMods(const ScriptInterface& scriptInterface) return JS::NullValue(); } - ScriptRequest rq(scriptInterface); - const std::vector& availableMods = g_ModIo->GetMods(); JS::RootedValue mods(rq.cx); - ScriptInterface::CreateArray(rq, &mods, availableMods.size()); + Script::CreateArray(rq, &mods, availableMods.size()); u32 i = 0; for (const ModIoModData& mod : availableMods) { JS::RootedValue m(rq.cx); - ScriptInterface::CreateObject(rq, &m); + Script::CreateObject(rq, &m); for (const std::pair& prop : mod.properties) - scriptInterface.SetProperty(m, prop.first.c_str(), prop.second, true); + Script::SetProperty(rq, m, prop.first.c_str(), prop.second, true); - scriptInterface.SetProperty(m, "dependencies", mod.dependencies, true); - scriptInterface.SetPropertyInt(mods, i++, m); + Script::SetProperty(rq, m, "dependencies", mod.dependencies, true); + Script::SetPropertyInt(rq, mods, i++, m); } return mods; @@ -92,7 +90,7 @@ const std::map statusStrings = { }; // TODO: could provide a FromJSVal for DownloadProgressData -JS::Value GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate) +JS::Value GetDownloadProgress(const ScriptRequest& rq) { if (!g_ModIo) { @@ -100,16 +98,14 @@ JS::Value GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate) return JS::NullValue(); } - ScriptInterface* scriptInterface = pCmptPrivate->pScriptInterface; - ScriptRequest rq(scriptInterface); const DownloadProgressData& progress = g_ModIo->GetDownloadProgress(); JS::RootedValue progressData(rq.cx); - ScriptInterface::CreateObject(rq, &progressData); - scriptInterface->SetProperty(progressData, "status", statusStrings.at(progress.status), true); - scriptInterface->SetProperty(progressData, "progress", progress.progress, true); - scriptInterface->SetProperty(progressData, "error", progress.error, true); + Script::CreateObject(rq, &progressData); + Script::SetProperty(rq, progressData, "status", statusStrings.at(progress.status), true); + Script::SetProperty(rq, progressData, "progress", progress.progress, true); + Script::SetProperty(rq, progressData, "error", progress.error, true); return progressData; } diff --git a/source/ps/scripting/JSInterface_SavedGame.cpp b/source/ps/scripting/JSInterface_SavedGame.cpp index ab05fe6572..e02a1998f7 100644 --- a/source/ps/scripting/JSInterface_SavedGame.cpp +++ b/source/ps/scripting/JSInterface_SavedGame.cpp @@ -103,10 +103,10 @@ JS::Value StartSavedGame(const ScriptInterface& scriptInterface, const std::wstr JS::RootedValue gameContextMetadata(rqGame.cx, Script::CloneValueFromOtherCompartment(sim->GetScriptInterface(), scriptInterface, guiContextMetadata)); JS::RootedValue gameInitAttributes(rqGame.cx); - sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes); + Script::GetProperty(rqGame, gameContextMetadata, "initAttributes", &gameInitAttributes); int playerID; - sim->GetScriptInterface().GetProperty(gameContextMetadata, "playerID", playerID); + Script::GetProperty(rqGame, gameContextMetadata, "playerID", playerID); g_Game->SetPlayerID(playerID); g_Game->StartGame(&gameInitAttributes, savedState); diff --git a/source/ps/scripting/JSInterface_VFS.cpp b/source/ps/scripting/JSInterface_VFS.cpp index d508c3340e..2b9531b645 100644 --- a/source/ps/scripting/JSInterface_VFS.cpp +++ b/source/ps/scripting/JSInterface_VFS.cpp @@ -169,7 +169,7 @@ JS::Value ReadFile(const ScriptRequest& rq, const std::wstring& filename) } // Return file contents as an array of lines. Assume file is UTF-8 encoded text. -JS::Value ReadFileLines(const ScriptInterface& scriptInterface, const std::wstring& filename) +JS::Value ReadFileLines(const ScriptRequest& rq, const std::wstring& filename) { CVFSFile file; if (file.Load(g_VFS, filename) != PSRETURN_OK) @@ -183,10 +183,8 @@ JS::Value ReadFileLines(const ScriptInterface& scriptInterface, const std::wstri // split into array of strings (one per line) std::stringstream ss(contents); - ScriptRequest rq(scriptInterface); - JS::RootedValue line_array(rq.cx); - ScriptInterface::CreateArray(rq, &line_array); + Script::CreateArray(rq, &line_array); std::string line; int cur_line = 0; @@ -196,7 +194,7 @@ JS::Value ReadFileLines(const ScriptInterface& scriptInterface, const std::wstri // Decode each line as UTF-8 JS::RootedValue val(rq.cx); Script::ToJSVal(rq, &val, CStr(line).FromUTF8()); - scriptInterface.SetPropertyInt(line_array, cur_line++, val); + Script::SetPropertyInt(rq, line_array, cur_line++, val); } return line_array; diff --git a/source/rlinterface/RLInterface.cpp b/source/rlinterface/RLInterface.cpp index 0a136e2248..98e46932d6 100644 --- a/source/rlinterface/RLInterface.cpp +++ b/source/rlinterface/RLInterface.cpp @@ -26,6 +26,7 @@ #include "ps/Game.h" #include "ps/GameSetup/GameSetup.h" #include "ps/Loader.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpAIInterface.h" @@ -357,12 +358,12 @@ void Interface::ApplyMessage(const GameMessage& msg) else { JS::RootedValue initData(rq.cx); - scriptInterface.CreateObject(rq, &initData); - scriptInterface.SetProperty(initData, "attribs", attrs); + Script::CreateObject(rq, &initData); + Script::SetProperty(rq, initData, "attribs", attrs); JS::RootedValue playerAssignments(rq.cx); - scriptInterface.CreateObject(rq, &playerAssignments); - scriptInterface.SetProperty(initData, "playerAssignments", playerAssignments); + Script::CreateObject(rq, &playerAssignments); + Script::SetProperty(rq, initData, "playerAssignments", playerAssignments); g_GUI->SwitchPage(L"page_loading.xml", &scriptInterface, initData); m_NeedsGameState = true; diff --git a/source/scriptinterface/FunctionWrapper.h b/source/scriptinterface/FunctionWrapper.h index 941e718347..764af14b3a 100644 --- a/source/scriptinterface/FunctionWrapper.h +++ b/source/scriptinterface/FunctionWrapper.h @@ -18,9 +18,11 @@ #ifndef INCLUDED_FUNCTIONWRAPPER #define INCLUDED_FUNCTIONWRAPPER +#include "Object.h" #include "ScriptConversions.h" #include "ScriptExceptions.h" #include "ScriptInterface.h" +#include "ScriptRequest.h" /** * This class introduces templates to conveniently wrap C++ functions in JSNative functions. diff --git a/source/scriptinterface/Object.h b/source/scriptinterface/Object.h new file mode 100644 index 0000000000..48115b8655 --- /dev/null +++ b/source/scriptinterface/Object.h @@ -0,0 +1,233 @@ +/* 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 . + */ + +#ifndef INCLUDED_SCRIPTINTERFACE_OBJECT +#define INCLUDED_SCRIPTINTERFACE_OBJECT + +#include "ScriptConversions.h" +#include "ScriptRequest.h" +#include "ScriptTypes.h" + +#include "ps/CLogger.h" + +/** + * Wraps SM APIs for manipulating JS objects. + */ + +namespace Script +{ +/** + * Get the named property on the given object. + */ +template +inline bool GetProperty(const ScriptRequest& rq, JS::HandleValue obj, PropType name, JS::MutableHandleValue out) +{ + if (!obj.isObject()) + return false; + JS::RootedObject object(rq.cx, &obj.toObject()); + if constexpr (std::is_same_v) + { + JS::RootedId id(rq.cx, INT_TO_JSID(name)); + return JS_GetPropertyById(rq.cx, object, id, out); + } + else if constexpr (std::is_same_v) + return JS_GetProperty(rq.cx, object, name, out); + else + return JS_GetUCProperty(rq.cx, object, name, wcslen(name), out); +} + +template +inline bool GetProperty(const ScriptRequest& rq, JS::HandleValue obj, PropType name, T& out) +{ + JS::RootedValue val(rq.cx); + if (!GetProperty(rq, obj, name, &val)) + return false; + return FromJSVal(rq, val, out); +} +inline bool GetProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name, JS::MutableHandleObject out) +{ + JS::RootedValue val(rq.cx, JS::ObjectValue(*out.get())); + if (!GetProperty(rq, obj, name, &val)) + return false; + out.set(val.toObjectOrNull()); + return true; +} + +template +inline bool GetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, T& out) +{ + return GetProperty(rq, obj, name, out); +} +inline bool GetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, JS::MutableHandleValue out) +{ + return GetProperty(rq, obj, name, out); +} +/** + * Check the named property has been defined on the given object. + */ +inline bool HasProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name) +{ + if (!obj.isObject()) + return false; + JS::RootedObject object(rq.cx, &obj.toObject()); + + bool found; + if (!JS_HasProperty(rq.cx, object, name, &found)) + return false; + return found; +} + +/** + * Set the named property on the given object. + */ +template +inline bool SetProperty(const ScriptRequest& rq, JS::HandleValue obj, PropType name, JS::HandleValue value, bool constant = false, bool enumerable = true) +{ + uint attrs = 0; + if (constant) + attrs |= JSPROP_READONLY | JSPROP_PERMANENT; + if (enumerable) + attrs |= JSPROP_ENUMERATE; + + if (!obj.isObject()) + return false; + JS::RootedObject object(rq.cx, &obj.toObject()); + if constexpr (std::is_same_v) + { + JS::RootedId id(rq.cx, INT_TO_JSID(name)); + return JS_DefinePropertyById(rq.cx, object, id, value, attrs); + } + else if constexpr (std::is_same_v) + return JS_DefineProperty(rq.cx, object, name, value, attrs); + else + return JS_DefineUCProperty(rq.cx, object, name, value, attrs); +} + +template +inline bool SetProperty(const ScriptRequest& rq, JS::HandleValue obj, PropType name, const T& value, bool constant = false, bool enumerable = true) +{ + JS::RootedValue val(rq.cx); + Script::ToJSVal(rq, &val, value); + return SetProperty(rq, obj, name, val, constant, enumerable); +} + +template +inline bool SetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, const T& value, bool constant = false, bool enumerable = true) +{ + return SetProperty(rq, obj, name, value, constant, enumerable); +} + +inline bool FreezeObject(const ScriptRequest& rq, JS::HandleValue objVal, bool deep) +{ + if (!objVal.isObject()) + return false; + + JS::RootedObject obj(rq.cx, &objVal.toObject()); + + if (deep) + return JS_DeepFreezeObject(rq.cx, obj); + else + return JS_FreezeObject(rq.cx, obj); +} + +/** + * Returns all properties of the object, both own properties and inherited. + * This is essentially equivalent to calling Object.getOwnPropertyNames() + * and recursing up the prototype chain. + * NB: this does not return properties with symbol or numeric keys, as that would + * require a variant in the vector, and it's not useful for now. + * @param enumerableOnly - only return enumerable properties. + */ +inline bool EnumeratePropertyNames(const ScriptRequest& rq, JS::HandleValue objVal, bool enumerableOnly, std::vector& out) +{ + if (!objVal.isObjectOrNull()) + { + LOGERROR("EnumeratePropertyNames expected object type!"); + return false; + } + + JS::RootedObject obj(rq.cx, &objVal.toObject()); + JS::RootedIdVector props(rq.cx); + // This recurses up the prototype chain on its own. + if (!js::GetPropertyKeys(rq.cx, obj, enumerableOnly? 0 : JSITER_HIDDEN, &props)) + return false; + + out.reserve(out.size() + props.length()); + for (size_t i = 0; i < props.length(); ++i) + { + JS::RootedId id(rq.cx, props[i]); + JS::RootedValue val(rq.cx); + if (!JS_IdToValue(rq.cx, id, &val)) + return false; + + // Ignore integer properties for now. + // TODO: is this actually a thing in ECMAScript 6? + if (!val.isString()) + continue; + + std::string propName; + if (!FromJSVal(rq, val, propName)) + return false; + + out.emplace_back(std::move(propName)); + } + + return true; +} + +/** + * Create a plain object (i.e. {}). If it fails, returns undefined. + */ +inline JS::Value CreateObject(const ScriptRequest& rq) +{ + JS::RootedObject obj(rq.cx, JS_NewPlainObject(rq.cx)); + if (!obj) + return JS::UndefinedValue(); + return JS::ObjectValue(*obj.get()); +} + +inline bool CreateObject(const ScriptRequest& rq, JS::MutableHandleValue objectValue) +{ + objectValue.set(CreateObject(rq)); + return !objectValue.isNullOrUndefined(); +} + +/** + * Sets the given value to a new plain JS::Object, converts the arguments to JS::Values and sets them as properties. + * This is static so that callers like ToJSVal can use it with the JSContext directly instead of having to obtain the instance using GetScriptInterfaceAndCBData. + * Can throw an exception. + */ +template +inline bool CreateObject(const ScriptRequest& rq, JS::MutableHandleValue objectValue, const char* propertyName, const T& propertyValue, Args const&... args) +{ + JS::RootedValue val(rq.cx); + ToJSVal(rq, &val, propertyValue); + return CreateObject(rq, objectValue, args...) && SetProperty(rq, objectValue, propertyName, val, false, true); +} + +/** + * Sets the given value to a new JS object or Null Value in case of out-of-memory. + */ +inline bool CreateArray(const ScriptRequest& rq, JS::MutableHandleValue objectValue, size_t length = 0) +{ + objectValue.setObjectOrNull(JS::NewArrayObject(rq.cx, length)); + return !objectValue.isNullOrUndefined(); +} + +} // namespace Script + +#endif // INCLUDED_SCRIPTINTERFACE_Object diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index e2475e166c..26f3aecd2e 100644 --- a/source/scriptinterface/ScriptInterface.cpp +++ b/source/scriptinterface/ScriptInterface.cpp @@ -206,7 +206,7 @@ JS::Value deepfreeze(const ScriptInterface& scriptInterface, JS::HandleValue val return JS::UndefinedValue(); } - scriptInterface.FreezeObject(val, true); + Script::FreezeObject(rq, val, true); return val; } @@ -476,23 +476,6 @@ JSObject* ScriptInterface::CreateCustomObject(const std::string& typeName) const return JS_NewObjectWithGivenProto(rq.cx, it->second.m_Class, prototype); } -bool ScriptInterface::CreateObject_(const ScriptRequest& rq, JS::MutableHandleObject object) -{ - object.set(JS_NewPlainObject(rq.cx)); - - if (!object) - throw PSERROR_Scripting_CreateObjectFailed(); - - return true; -} - -void ScriptInterface::CreateArray(const ScriptRequest& rq, JS::MutableHandleValue objectValue, size_t length) -{ - objectValue.setObjectOrNull(JS::NewArrayObject(rq.cx, length)); - if (!objectValue.isObject()) - throw PSERROR_Scripting_CreateObjectFailed(); -} - bool ScriptInterface::SetGlobal_(const char* name, JS::HandleValue value, bool replace, bool constant, bool enumerate) { ScriptRequest rq(this); @@ -537,121 +520,6 @@ bool ScriptInterface::SetGlobal_(const char* name, JS::HandleValue value, bool r return JS_DefineProperty(rq.cx, global, name, value, attrs); } -bool ScriptInterface::SetProperty_(JS::HandleValue obj, const char* name, JS::HandleValue value, bool constant, bool enumerate) const -{ - ScriptRequest rq(this); - uint attrs = 0; - if (constant) - attrs |= JSPROP_READONLY | JSPROP_PERMANENT; - if (enumerate) - attrs |= JSPROP_ENUMERATE; - - if (!obj.isObject()) - return false; - JS::RootedObject object(rq.cx, &obj.toObject()); - - return JS_DefineProperty(rq.cx, object, name, value, attrs); -} - -bool ScriptInterface::SetProperty_(JS::HandleValue obj, const wchar_t* name, JS::HandleValue value, bool constant, bool enumerate) const -{ - ScriptRequest rq(this); - uint attrs = 0; - if (constant) - attrs |= JSPROP_READONLY | JSPROP_PERMANENT; - if (enumerate) - attrs |= JSPROP_ENUMERATE; - - if (!obj.isObject()) - return false; - JS::RootedObject object(rq.cx, &obj.toObject()); - - utf16string name16(name, name + wcslen(name)); - return JS_DefineUCProperty(rq.cx, object, reinterpret_cast(name16.c_str()), name16.length(), value, attrs); -} - -bool ScriptInterface::SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool constant, bool enumerate) const -{ - ScriptRequest rq(this); - uint attrs = 0; - if (constant) - attrs |= JSPROP_READONLY | JSPROP_PERMANENT; - if (enumerate) - attrs |= JSPROP_ENUMERATE; - - if (!obj.isObject()) - return false; - JS::RootedObject object(rq.cx, &obj.toObject()); - - JS::RootedId id(rq.cx, INT_TO_JSID(name)); - return JS_DefinePropertyById(rq.cx, object, id, value, attrs); -} - -bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, JS::MutableHandleObject out) const -{ - ScriptRequest rq(this); - return GetProperty(rq, obj, name, out); -} - -bool ScriptInterface::GetProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name, JS::MutableHandleObject out) -{ - JS::RootedValue val(rq.cx); - if (!GetProperty(rq, obj, name, &val)) - return false; - if (!val.isObject()) - { - LOGERROR("GetProperty failed: trying to get an object, but the property is not an object!"); - return false; - } - - out.set(&val.toObject()); - return true; -} - -bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, JS::MutableHandleValue out) const -{ - ScriptRequest rq(this); - return GetProperty(rq, obj, name, out); -} - -bool ScriptInterface::GetProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name, JS::MutableHandleValue out) -{ - if (!obj.isObject()) - return false; - JS::RootedObject object(rq.cx, &obj.toObject()); - - return JS_GetProperty(rq.cx, object, name, out); -} - -bool ScriptInterface::GetPropertyInt(JS::HandleValue obj, int name, JS::MutableHandleValue out) const -{ - ScriptRequest rq(this); - return GetPropertyInt(rq,obj, name, out); -} - -bool ScriptInterface::GetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, JS::MutableHandleValue out) -{ - JS::RootedId nameId(rq.cx, INT_TO_JSID(name)); - if (!obj.isObject()) - return false; - JS::RootedObject object(rq.cx, &obj.toObject()); - - return JS_GetPropertyById(rq.cx, object, nameId, out); -} - -bool ScriptInterface::HasProperty(JS::HandleValue obj, const char* name) const -{ - ScriptRequest rq(this); - if (!obj.isObject()) - return false; - JS::RootedObject object(rq.cx, &obj.toObject()); - - bool found; - if (!JS_HasProperty(rq.cx, object, name, &found)) - return false; - return found; -} - bool ScriptInterface::GetGlobalProperty(const ScriptRequest& rq, const std::string& name, JS::MutableHandleValue out) { // Try to get the object as a property of the global object. @@ -682,45 +550,6 @@ bool ScriptInterface::GetGlobalProperty(const ScriptRequest& rq, const std::stri return false; } -bool ScriptInterface::EnumeratePropertyNames(JS::HandleValue objVal, bool enumerableOnly, std::vector& out) const -{ - ScriptRequest rq(this); - - if (!objVal.isObjectOrNull()) - { - LOGERROR("EnumeratePropertyNames expected object type!"); - return false; - } - - JS::RootedObject obj(rq.cx, &objVal.toObject()); - JS::RootedIdVector props(rq.cx); - // This recurses up the prototype chain on its own. - if (!js::GetPropertyKeys(rq.cx, obj, enumerableOnly? 0 : JSITER_HIDDEN, &props)) - return false; - - out.reserve(out.size() + props.length()); - for (size_t i = 0; i < props.length(); ++i) - { - JS::RootedId id(rq.cx, props[i]); - JS::RootedValue val(rq.cx); - if (!JS_IdToValue(rq.cx, id, &val)) - return false; - - // Ignore integer properties for now. - // TODO: is this actually a thing in ECMAScript 6? - if (!val.isString()) - continue; - - std::string propName; - if (!Script::FromJSVal(rq, val, propName)) - return false; - - out.emplace_back(std::move(propName)); - } - - return true; -} - bool ScriptInterface::SetPrototype(JS::HandleValue objVal, JS::HandleValue protoVal) { ScriptRequest rq(this); @@ -731,20 +560,6 @@ bool ScriptInterface::SetPrototype(JS::HandleValue objVal, JS::HandleValue proto return JS_SetPrototype(rq.cx, obj, proto); } -bool ScriptInterface::FreezeObject(JS::HandleValue objVal, bool deep) const -{ - ScriptRequest rq(this); - if (!objVal.isObject()) - return false; - - JS::RootedObject obj(rq.cx, &objVal.toObject()); - - if (deep) - return JS_DeepFreezeObject(rq.cx, obj); - else - return JS_FreezeObject(rq.cx, obj); -} - bool ScriptInterface::LoadScript(const VfsPath& filename, const std::string& code) const { ScriptRequest rq(this); diff --git a/source/scriptinterface/ScriptInterface.h b/source/scriptinterface/ScriptInterface.h index 1def439195..843536f0f9 100644 --- a/source/scriptinterface/ScriptInterface.h +++ b/source/scriptinterface/ScriptInterface.h @@ -126,28 +126,6 @@ public: JSObject* CreateCustomObject(const std::string & typeName) const; void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs); - /** - * Sets the given value to a new plain JS::Object, converts the arguments to JS::Values and sets them as properties. - * This is static so that callers like ToJSVal can use it with the JSContext directly instead of having to obtain the instance using GetScriptInterfaceAndCBData. - * Can throw an exception. - */ - template - static bool CreateObject(const ScriptRequest& rq, JS::MutableHandleValue objectValue, Args const&... args) - { - JS::RootedObject obj(rq.cx); - - if (!CreateObject_(rq, &obj, args...)) - return false; - - objectValue.setObject(*obj); - return true; - } - - /** - * Sets the given value to a new JS object or Null Value in case of out-of-memory. - */ - static void CreateArray(const ScriptRequest& rq, JS::MutableHandleValue objectValue, size_t length = 0); - /** * Set the named property on the global object. * Optionally makes it {ReadOnly, DontEnum}. We do not allow to make it DontDelete, so that it can be hotloaded @@ -156,58 +134,6 @@ public: template bool SetGlobal(const char* name, const T& value, bool replace = false, bool constant = true, bool enumerate = true); - /** - * Set the named property on the given object. - * Optionally makes it {ReadOnly, DontDelete, DontEnum}. - */ - template - bool SetProperty(JS::HandleValue obj, const char* name, const T& value, bool constant = false, bool enumerate = true) const; - - /** - * Set the named property on the given object. - * Optionally makes it {ReadOnly, DontDelete, DontEnum}. - */ - template - bool SetProperty(JS::HandleValue obj, const wchar_t* name, const T& value, bool constant = false, bool enumerate = true) const; - - /** - * Set the integer-named property on the given object. - * Optionally makes it {ReadOnly, DontDelete, DontEnum}. - */ - template - bool SetPropertyInt(JS::HandleValue obj, int name, const T& value, bool constant = false, bool enumerate = true) const; - - /** - * Get the named property on the given object. - */ - template - bool GetProperty(JS::HandleValue obj, const char* name, T& out) const; - bool GetProperty(JS::HandleValue obj, const char* name, JS::MutableHandleValue out) const; - bool GetProperty(JS::HandleValue obj, const char* name, JS::MutableHandleObject out) const; - - template - static bool GetProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name, T& out); - static bool GetProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name, JS::MutableHandleValue out); - static bool GetProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name, JS::MutableHandleObject out); - - /** - * Get the integer-named property on the given object. - */ - template - bool GetPropertyInt(JS::HandleValue obj, int name, T& out) const; - bool GetPropertyInt(JS::HandleValue obj, int name, JS::MutableHandleValue out) const; - bool GetPropertyInt(JS::HandleValue obj, int name, JS::MutableHandleObject out) const; - - template - static bool GetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, T& out); - static bool GetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, JS::MutableHandleValue out); - static bool GetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, JS::MutableHandleObject out); - - /** - * Check the named property has been defined on the given object. - */ - bool HasProperty(JS::HandleValue obj, const char* name) const; - /** * Get an object from the global scope or any lexical scope. * This can return globally accessible objects even if they are not properties @@ -217,20 +143,8 @@ public: */ static bool GetGlobalProperty(const ScriptRequest& rq, const std::string& name, JS::MutableHandleValue out); - /** - * Returns all properties of the object, both own properties and inherited. - * This is essentially equivalent to calling Object.getOwnPropertyNames() - * and recursing up the prototype chain. - * NB: this does not return properties with symbol or numeric keys, as that would - * require a variant in the vector, and it's not useful for now. - * @param enumerableOnly - only return enumerable properties. - */ - bool EnumeratePropertyNames(JS::HandleValue objVal, bool enumerableOnly, std::vector& out) const; - bool SetPrototype(JS::HandleValue obj, JS::HandleValue proto); - bool FreezeObject(JS::HandleValue objVal, bool deep) const; - /** * Convert an object to a UTF-8 encoded string, either with JSON * (if pretty == true and there is no JSON error) or with toSource(). @@ -331,22 +245,7 @@ public: } private: - - static bool CreateObject_(const ScriptRequest& rq, JS::MutableHandleObject obj); - - template - static bool CreateObject_(const ScriptRequest& rq, JS::MutableHandleObject obj, const char* propertyName, const T& propertyValue, Args const&... args) - { - JS::RootedValue val(rq.cx); - Script::ToJSVal(rq, &val, propertyValue); - - return CreateObject_(rq, obj, args...) && JS_DefineProperty(rq.cx, obj, propertyName, val, JSPROP_ENUMERATE); - } - bool SetGlobal_(const char* name, JS::HandleValue value, bool replace, bool constant, bool enumerate); - bool SetProperty_(JS::HandleValue obj, const char* name, JS::HandleValue value, bool constant, bool enumerate) const; - bool SetProperty_(JS::HandleValue obj, const wchar_t* name, JS::HandleValue value, bool constant, bool enumerate) const; - bool SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool constant, bool enumerate) const; struct CustomType { @@ -372,66 +271,6 @@ bool ScriptInterface::SetGlobal(const char* name, const T& value, bool replace, return SetGlobal_(name, val, replace, constant, enumerate); } -template -bool ScriptInterface::SetProperty(JS::HandleValue obj, const char* name, const T& value, bool constant, bool enumerate) const -{ - ScriptRequest rq(this); - JS::RootedValue val(rq.cx); - Script::ToJSVal(rq, &val, value); - return SetProperty_(obj, name, val, constant, enumerate); -} - -template -bool ScriptInterface::SetProperty(JS::HandleValue obj, const wchar_t* name, const T& value, bool constant, bool enumerate) const -{ - ScriptRequest rq(this); - JS::RootedValue val(rq.cx); - Script::ToJSVal(rq, &val, value); - return SetProperty_(obj, name, val, constant, enumerate); -} - -template -bool ScriptInterface::SetPropertyInt(JS::HandleValue obj, int name, const T& value, bool constant, bool enumerate) const -{ - ScriptRequest rq(this); - JS::RootedValue val(rq.cx); - Script::ToJSVal(rq, &val, value); - return SetPropertyInt_(obj, name, val, constant, enumerate); -} - -template -bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, T& out) const -{ - ScriptRequest rq(this); - return GetProperty(rq, obj, name, out); -} - -template -bool ScriptInterface::GetProperty(const ScriptRequest& rq, JS::HandleValue obj, const char* name, T& out) -{ - JS::RootedValue val(rq.cx); - if (!GetProperty(rq, obj, name, &val)) - return false; - return Script::FromJSVal(rq, val, out); -} - -template -bool ScriptInterface::GetPropertyInt(JS::HandleValue obj, int name, T& out) const -{ - ScriptRequest rq(this); - return GetPropertyInt(rq, obj, name, out); -} - -template -bool ScriptInterface::GetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, T& out) -{ - JS::RootedValue val(rq.cx); - if (!GetPropertyInt(rq, obj, name, &val)) - return false; - return Script::FromJSVal(rq, val, out); -} - - template bool ScriptInterface::Eval(const char* code, T& ret) const { diff --git a/source/scriptinterface/tests/test_ScriptInterface.h b/source/scriptinterface/tests/test_ScriptInterface.h index 292e05f5fd..85a952f2cc 100644 --- a/source/scriptinterface/tests/test_ScriptInterface.h +++ b/source/scriptinterface/tests/test_ScriptInterface.h @@ -20,6 +20,7 @@ #include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "scriptinterface/StructuredClone.h" +#include "scriptinterface/Object.h" #include "ps/CLogger.h" @@ -122,11 +123,11 @@ public: JS::RootedValue prop_a(rq2.cx); JS::RootedValue prop_b(rq2.cx); JS::RootedValue prop_x1(rq2.cx); - TS_ASSERT(script2.GetProperty(obj2, "a", &prop_a)); - TS_ASSERT(script2.GetProperty(obj2, "b", &prop_b)); + TS_ASSERT(Script::GetProperty(rq2, obj2, "a", &prop_a)); + TS_ASSERT(Script::GetProperty(rq2, obj2, "b", &prop_b)); TS_ASSERT(prop_a.isObject()); TS_ASSERT(prop_b.isObject()); - TS_ASSERT(script2.GetProperty(prop_a, "0", &prop_x1)); + TS_ASSERT(Script::GetProperty(rq2, prop_a, "0", &prop_x1)); TS_ASSERT(prop_x1.get() == prop_a.get()); TS_ASSERT(prop_x1.get() == prop_b.get()); } @@ -168,13 +169,13 @@ public: // GetProperty JS::RootedValue* overload nbr = 0; - script.GetProperty(val, "0", &out); + Script::GetProperty(rq, val, "0", &out); Script::FromJSVal(rq, out, nbr); TS_ASSERT_EQUALS(nbr, 7); // GetPropertyInt JS::RootedValue* overload nbr = 0; - script.GetPropertyInt(val, 0, &out); + Script::GetPropertyInt(rq, val, 0, &out); Script::FromJSVal(rq, out, nbr); TS_ASSERT_EQUALS(nbr, 7); @@ -198,13 +199,13 @@ public: // GetProperty JS::MutableHandleValue overload nbr = 0; - script.GetProperty(val, "0", out); + Script::GetProperty(rq, val, "0", out); Script::FromJSVal(rq, out, nbr); TS_ASSERT_EQUALS(nbr, 7); // GetPropertyInt JS::MutableHandleValue overload nbr = 0; - script.GetPropertyInt(val, 0, out); + Script::GetPropertyInt(rq, val, 0, out); Script::FromJSVal(rq, out, nbr); TS_ASSERT_EQUALS(nbr, 7); } diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index f94c07c6c1..c0c3cd33b2 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -172,7 +172,7 @@ public: for (const SimulationCommand& command : commands) { JS::RootedValue tmpCommand(rqNew.cx, Script::CloneValueFromOtherCompartment(newScript, oldScript, command.data)); - newScript.FreezeObject(tmpCommand, true); + Script::FreezeObject(rqNew, tmpCommand, true); SimulationCommand cmd(command.player, rqNew.cx, tmpCommand); newCommands.emplace_back(std::move(cmd)); } @@ -210,10 +210,11 @@ bool CSimulation2Impl::LoadScripts(CComponentManager& componentManager, std::set bool CSimulation2Impl::LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue mapSettings, std::set* loadedScripts) { bool ok = true; - if (componentManager.GetScriptInterface().HasProperty(mapSettings, "TriggerScripts")) + ScriptRequest rq(componentManager.GetScriptInterface()); + if (Script::HasProperty(rq, mapSettings, "TriggerScripts")) { std::vector scriptNames; - componentManager.GetScriptInterface().GetProperty(mapSettings, "TriggerScripts", scriptNames); + Script::GetProperty(rq, mapSettings, "TriggerScripts", scriptNames); for (const std::string& triggerScript : scriptNames) { std::string scriptName = "maps/" + triggerScript; @@ -335,8 +336,9 @@ void CSimulation2Impl::ReportSerializationFailure( void CSimulation2Impl::InitRNGSeedSimulation() { u32 seed = 0; - if (!m_ComponentManager.GetScriptInterface().HasProperty(m_MapSettings, "Seed") || - !m_ComponentManager.GetScriptInterface().GetProperty(m_MapSettings, "Seed", seed)) + ScriptRequest rq(m_ComponentManager.GetScriptInterface()); + if (!Script::HasProperty(rq, m_MapSettings, "Seed") || + !Script::GetProperty(rq, m_MapSettings, "Seed", seed)) LOGWARNING("CSimulation2Impl::InitRNGSeedSimulation: No seed value specified - using %d", seed); m_ComponentManager.SetRNGSeed(seed); @@ -345,8 +347,9 @@ void CSimulation2Impl::InitRNGSeedSimulation() void CSimulation2Impl::InitRNGSeedAI() { u32 seed = 0; - if (!m_ComponentManager.GetScriptInterface().HasProperty(m_MapSettings, "AISeed") || - !m_ComponentManager.GetScriptInterface().GetProperty(m_MapSettings, "AISeed", seed)) + ScriptRequest rq(m_ComponentManager.GetScriptInterface()); + if (!Script::HasProperty(rq, m_MapSettings, "AISeed") || + !Script::GetProperty(rq, m_MapSettings, "AISeed", seed)) LOGWARNING("CSimulation2Impl::InitRNGSeedAI: No seed value specified - using %d", seed); CmpPtr cmpAIManager(m_SimContext, SYSTEM_ENTITY); @@ -413,9 +416,10 @@ void CSimulation2Impl::Update(int turnLength, const std::vectorGetScriptInterface()); JS::RootedValue mapSettingsCloned(rq2.cx, Script::CloneValueFromOtherCompartment(m_SecondaryComponentManager->GetScriptInterface(), scriptInterface, m_MapSettings)); ENSURE(LoadTriggerScripts(*m_SecondaryComponentManager, mapSettingsCloned, m_SecondaryLoadedScripts.get())); @@ -427,7 +431,7 @@ void CSimulation2Impl::Update(int turnLength, const std::vector mapReader = std::make_unique(); std::string mapType; - scriptInterface.GetProperty(m_InitAttributes, "mapType", mapType); + Script::GetProperty(rq, m_InitAttributes, "mapType", mapType); if (mapType == "random") { // TODO: support random map scripts @@ -436,7 +440,7 @@ void CSimulation2Impl::Update(int turnLength, const std::vectorLoadMap(mapfilename, *scriptInterface.GetContext(), JS::UndefinedHandleValue, @@ -738,7 +742,7 @@ void CSimulation2::InitGame() JS::RootedValue settings(rq.cx); JS::RootedValue tmpInitAttributes(rq.cx, GetInitAttributes()); - GetScriptInterface().GetProperty(tmpInitAttributes, "settings", &settings); + Script::GetProperty(rq, tmpInitAttributes, "settings", &settings); ScriptFunction::CallVoid(rq, global, "InitGame", settings); } @@ -846,7 +850,7 @@ void CSimulation2::LoadMapSettings() // Initialize here instead of in Update() ScriptFunction::CallVoid(rq, global, "LoadMapSettings", m->m_MapSettings); - GetScriptInterface().FreezeObject(m->m_InitAttributes, true); + Script::FreezeObject(rq, m->m_InitAttributes, true); GetScriptInterface().SetGlobal("InitAttributes", m->m_InitAttributes, true, true, true); if (!m->m_StartupScript.empty()) @@ -990,7 +994,7 @@ std::string CSimulation2::GetAIData() // Build single JSON string with array of AI data JS::RootedValue ais(rq.cx); - if (!ScriptInterface::CreateObject(rq, &ais, "AIData", aiData)) + if (!Script::CreateObject(rq, &ais, "AIData", aiData)) return std::string(); return scriptInterface.StringifyJSON(&ais); diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp index ca40074512..f1b3aeec87 100644 --- a/source/simulation2/components/CCmpAIManager.cpp +++ b/source/simulation2/components/CCmpAIManager.cpp @@ -115,39 +115,39 @@ private: JS::RootedValue objectWithConstructor(rq.cx); // object that should contain the constructor function JS::RootedValue global(rq.cx, rq.globalValue()); JS::RootedValue ctor(rq.cx); - if (!m_ScriptInterface->HasProperty(metadata, "moduleName")) + if (!Script::HasProperty(rq, metadata, "moduleName")) { LOGERROR("Failed to create AI player: %s: missing 'moduleName'", path.string8()); return false; } - m_ScriptInterface->GetProperty(metadata, "moduleName", moduleName); - if (!m_ScriptInterface->GetProperty(global, moduleName.c_str(), &objectWithConstructor) + Script::GetProperty(rq, metadata, "moduleName", moduleName); + if (!Script::GetProperty(rq, global, moduleName.c_str(), &objectWithConstructor) || objectWithConstructor.isUndefined()) { LOGERROR("Failed to create AI player: %s: can't find the module that should contain the constructor: '%s'", path.string8(), moduleName); return false; } - if (!m_ScriptInterface->GetProperty(metadata, "constructor", constructor)) + if (!Script::GetProperty(rq, metadata, "constructor", constructor)) { LOGERROR("Failed to create AI player: %s: missing 'constructor'", path.string8()); return false; } // Get the constructor function from the loaded scripts - if (!m_ScriptInterface->GetProperty(objectWithConstructor, constructor.c_str(), &ctor) + if (!Script::GetProperty(rq, objectWithConstructor, constructor.c_str(), &ctor) || ctor.isNull()) { LOGERROR("Failed to create AI player: %s: can't find constructor '%s'", path.string8(), constructor); return false; } - m_ScriptInterface->GetProperty(metadata, "useShared", m_UseSharedComponent); + Script::GetProperty(rq, metadata, "useShared", m_UseSharedComponent); // Set up the data to pass as the constructor argument JS::RootedValue settings(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &settings, "player", m_Player, @@ -157,7 +157,7 @@ private: if (!m_UseSharedComponent) { ENSURE(m_Worker.m_HasLoadedEntityTemplates); - m_ScriptInterface->SetProperty(settings, "templates", m_Worker.m_EntityTemplates, false); + Script::SetProperty(rq, settings, "templates", m_Worker.m_EntityTemplates, false); } JS::RootedValueVector argv(rq.cx); @@ -406,13 +406,13 @@ public: JS::RootedValue AIModule(rq.cx); JS::RootedValue global(rq.cx, rq.globalValue()); JS::RootedValue ctor(rq.cx); - if (!m_ScriptInterface->GetProperty(global, "API3", &AIModule) || AIModule.isUndefined()) + if (!Script::GetProperty(rq, global, "API3", &AIModule) || AIModule.isUndefined()) { LOGERROR("Failed to create shared AI component: %s: can't find module '%s'", path.string8(), "API3"); return false; } - if (!m_ScriptInterface->GetProperty(AIModule, "SharedScript", &ctor) + if (!Script::GetProperty(rq, AIModule, "SharedScript", &ctor) || ctor.isUndefined()) { LOGERROR("Failed to create shared AI component: %s: can't find constructor '%s'", path.string8(), "SharedScript"); @@ -421,19 +421,19 @@ public: // Set up the data to pass as the constructor argument JS::RootedValue playersID(rq.cx); - ScriptInterface::CreateObject(rq, &playersID); + Script::CreateObject(rq, &playersID); for (size_t i = 0; i < m_Players.size(); ++i) { JS::RootedValue val(rq.cx); Script::ToJSVal(rq, &val, m_Players[i]->m_Player); - m_ScriptInterface->SetPropertyInt(playersID, i, val, true); + Script::SetPropertyInt(rq, playersID, i, val, true); } ENSURE(m_HasLoadedEntityTemplates); JS::RootedValue settings(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &settings, "players", playersID, @@ -489,8 +489,8 @@ public: if (m_HasSharedComponent) { - m_ScriptInterface->SetProperty(state, "passabilityMap", m_PassabilityMapVal, true); - m_ScriptInterface->SetProperty(state, "territoryMap", m_TerritoryMapVal, true); + Script::SetProperty(rq, state, "passabilityMap", m_PassabilityMapVal, true); + Script::SetProperty(rq, state, "territoryMap", m_TerritoryMapVal, true); ScriptFunction::CallVoid(rq, m_SharedAIObj, "init", state); for (size_t i = 0; i < m_Players.size(); ++i) @@ -609,13 +609,13 @@ public: m_HasLoadedEntityTemplates = true; - ScriptInterface::CreateObject(rq, &m_EntityTemplates); + Script::CreateObject(rq, &m_EntityTemplates); JS::RootedValue val(rq.cx); for (size_t i = 0; i < templates.size(); ++i) { templates[i].second->ToJSVal(rq, false, &val); - m_ScriptInterface->SetProperty(m_EntityTemplates, templates[i].first.c_str(), val, true); + Script::SetProperty(rq, m_EntityTemplates, templates[i].first.c_str(), val, true); } } @@ -783,12 +783,12 @@ private: { PROFILE3("AI compute read state"); Script::ReadStructuredClone(rq, m_GameState, &state); - m_ScriptInterface->SetProperty(state, "passabilityMap", m_PassabilityMapVal, true); - m_ScriptInterface->SetProperty(state, "territoryMap", m_TerritoryMapVal, true); + Script::SetProperty(rq, state, "passabilityMap", m_PassabilityMapVal, true); + Script::SetProperty(rq, state, "territoryMap", m_TerritoryMapVal, true); } // It would be nice to do - // m_ScriptInterface->FreezeObject(state.get(), true); + // Script::FreezeObject(rq, state.get(), true); // to prevent AI scripts accidentally modifying the state and // affecting other AI scripts they share it with. But the performance // cost is far too high, so we won't do that. @@ -1088,14 +1088,14 @@ private: ScriptRequest rq(scriptInterface); JS::RootedValue classesVal(rq.cx); - ScriptInterface::CreateObject(rq, &classesVal); + Script::CreateObject(rq, &classesVal); std::map classes; cmpPathfinder->GetPassabilityClasses(classes); for (std::map::iterator it = classes.begin(); it != classes.end(); ++it) - scriptInterface.SetProperty(classesVal, it->first.c_str(), it->second, true); + Script::SetProperty(rq, classesVal, it->first.c_str(), it->second, true); - scriptInterface.SetProperty(state, "passabilityClasses", classesVal, true); + Script::SetProperty(rq, state, "passabilityClasses", classesVal, true); } CAIWorker m_Worker; diff --git a/source/simulation2/components/ICmpAIManager.cpp b/source/simulation2/components/ICmpAIManager.cpp index d598178bdb..e922f30e2e 100644 --- a/source/simulation2/components/ICmpAIManager.cpp +++ b/source/simulation2/components/ICmpAIManager.cpp @@ -65,12 +65,12 @@ public: std::wstring dirname = GetWstringFromWpath(*it); JS::RootedValue ai(rq.cx); - ScriptInterface::CreateObject(rq, &ai); + Script::CreateObject(rq, &ai); JS::RootedValue data(rq.cx); self->m_ScriptInterface.ReadJSONFile(pathname, &data); - self->m_ScriptInterface.SetProperty(ai, "id", dirname, true); - self->m_ScriptInterface.SetProperty(ai, "data", data, true); + Script::SetProperty(rq, ai, "id", dirname, true); + Script::SetProperty(rq, ai, "data", data, true); u32 length; JS::GetArrayLength(rq.cx, self->m_AIs, &length); JS_SetElement(rq.cx, self->m_AIs, length, ai); diff --git a/source/simulation2/scripting/EngineScriptConversions.cpp b/source/simulation2/scripting/EngineScriptConversions.cpp index 639351737e..0cab3ee6ba 100644 --- a/source/simulation2/scripting/EngineScriptConversions.cpp +++ b/source/simulation2/scripting/EngineScriptConversions.cpp @@ -17,6 +17,7 @@ #include "precompiled.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptConversions.h" #include "scriptinterface/ScriptInterface.h" @@ -73,10 +74,7 @@ template<> void Script::ToJSVal(const ScriptRequest& rq, JS::Mutabl // Prevent modifications to the object, so that it's safe to share between // components and to reconstruct on deserialization if (ret.isObject()) - { - JS::RootedObject obj(rq.cx, &ret.toObject()); - JS_DeepFreezeObject(rq.cx, obj); - } + Script::FreezeObject(rq, ret, true); } template<> void Script::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret, const CParamNode* const& val) @@ -112,7 +110,7 @@ template<> bool Script::FromJSVal(const ScriptRequest& rq, JS::HandleVa template<> void Script::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret, CColor const& val) { - ScriptInterface::CreateObject( + Script::CreateObject( rq, ret, "r", val.r, @@ -224,7 +222,7 @@ template<> void Script::ToJSVal >(const ScriptRequest& rq, JS::Mutable } JS::RootedValue data(rq.cx, JS::ObjectValue(*objArr)); - ScriptInterface::CreateObject( + Script::CreateObject( rq, ret, "width", val.m_W, @@ -245,7 +243,7 @@ template<> void Script::ToJSVal >(const ScriptRequest& rq, JS::Mutabl } JS::RootedValue data(rq.cx, JS::ObjectValue(*objArr)); - ScriptInterface::CreateObject( + Script::CreateObject( rq, ret, "width", val.m_W, diff --git a/source/simulation2/scripting/JSInterface_Simulation.cpp b/source/simulation2/scripting/JSInterface_Simulation.cpp index f6269ba295..23eab271d0 100644 --- a/source/simulation2/scripting/JSInterface_Simulation.cpp +++ b/source/simulation2/scripting/JSInterface_Simulation.cpp @@ -131,7 +131,7 @@ JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(const ScriptInterface& scri ScriptRequest rq(scriptInterface); JS::RootedValue edgeList(rq.cx); - ScriptInterface::CreateArray(rq, &edgeList); + Script::CreateArray(rq, &edgeList); int edgeListIndex = 0; float distanceThreshold = 10.0f; @@ -176,7 +176,7 @@ JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(const ScriptInterface& scri CFixedVector2D normal = -(nextCorner - corner).Perpendicular(); normal.Normalize(); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &edge, "begin", corner, @@ -185,7 +185,7 @@ JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(const ScriptInterface& scri "normal", normal, "order", "cw"); - scriptInterface.SetPropertyInt(edgeList, edgeListIndex++, edge); + Script::SetPropertyInt(rq, edgeList, edgeListIndex++, edge); } } return edgeList; diff --git a/source/simulation2/scripting/ScriptComponent.cpp b/source/simulation2/scripting/ScriptComponent.cpp index 5f5e4efe4e..9b504388fa 100644 --- a/source/simulation2/scripting/ScriptComponent.cpp +++ b/source/simulation2/scripting/ScriptComponent.cpp @@ -20,6 +20,7 @@ #include "ScriptComponent.h" #include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/Object.h" #include "simulation2/serialization/ISerializer.h" #include "simulation2/serialization/IDeserializer.h" @@ -31,8 +32,8 @@ CComponentTypeScript::CComponentTypeScript(const ScriptInterface& scriptInterfac void CComponentTypeScript::Init(const CParamNode& paramNode, entity_id_t ent) { ScriptRequest rq(m_ScriptInterface); - m_ScriptInterface.SetProperty(m_Instance, "entity", (int)ent, true, false); - m_ScriptInterface.SetProperty(m_Instance, "template", paramNode, true, false); + Script::SetProperty(rq, m_Instance, "entity", (int)ent, true, false); + Script::SetProperty(rq, m_Instance, "template", paramNode, true, false); ScriptFunction::CallVoid(rq, m_Instance, "Init"); } @@ -65,8 +66,8 @@ void CComponentTypeScript::Deserialize(const CParamNode& paramNode, IDeserialize { ScriptRequest rq(m_ScriptInterface); - m_ScriptInterface.SetProperty(m_Instance, "entity", (int)ent, true, false); - m_ScriptInterface.SetProperty(m_Instance, "template", paramNode, true, false); + Script::SetProperty(rq, m_Instance, "entity", (int)ent, true, false); + Script::SetProperty(rq, m_Instance, "template", paramNode, true, false); deserialize.ScriptObjectAssign("comp", m_Instance); } diff --git a/source/simulation2/serialization/DebugSerializer.cpp b/source/simulation2/serialization/DebugSerializer.cpp index 4badbd79fe..96f2d47d16 100644 --- a/source/simulation2/serialization/DebugSerializer.cpp +++ b/source/simulation2/serialization/DebugSerializer.cpp @@ -20,6 +20,7 @@ #include "DebugSerializer.h" #include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptInterface.h" #include "lib/secure_crt.h" @@ -153,7 +154,7 @@ void CDebugSerializer::PutScriptVal(const char* name, JS::MutableHandleValue val ScriptRequest rq(m_ScriptInterface); JS::RootedValue serialize(rq.cx); - if (m_ScriptInterface.GetProperty(value, "Serialize", &serialize) && !serialize.isNullOrUndefined()) + if (Script::GetProperty(rq, value, "Serialize", &serialize) && !serialize.isNullOrUndefined()) { // If the value has a Serialize property, pretty-parse that instead. // (this gives more accurate OOS reports). diff --git a/source/simulation2/serialization/SerializedScriptTypes.h b/source/simulation2/serialization/SerializedScriptTypes.h index f23bc0e839..d794b2450f 100644 --- a/source/simulation2/serialization/SerializedScriptTypes.h +++ b/source/simulation2/serialization/SerializedScriptTypes.h @@ -66,7 +66,7 @@ inline SPrototypeSerialization GetPrototypeInfo(const ScriptRequest& rq, JS::Han SPrototypeSerialization ret; JS::RootedValue constructor(rq.cx, JS::ObjectOrNullValue(JS_GetConstructor(rq.cx, prototype))); - if (!ScriptInterface::GetProperty(rq, constructor, "name", ret.name)) + if (!Script::GetProperty(rq, constructor, "name", ret.name)) throw PSERROR_Serialize_ScriptError("Could not get constructor name."); // Nothing to do for basic Object objects. diff --git a/source/simulation2/serialization/StdDeserializer.cpp b/source/simulation2/serialization/StdDeserializer.cpp index 611718f798..00217dda3c 100644 --- a/source/simulation2/serialization/StdDeserializer.cpp +++ b/source/simulation2/serialization/StdDeserializer.cpp @@ -23,8 +23,8 @@ #include "ps/CLogger.h" #include "ps/CStr.h" #include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptConversions.h" -#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptExtraHeaders.h" // For typed arrays and ArrayBuffer #include "simulation2/serialization/ISerializer.h" #include "simulation2/serialization/SerializedScriptTypes.h" diff --git a/source/simulation2/system/ComponentManager.cpp b/source/simulation2/system/ComponentManager.cpp index 3346f87bb5..b5e5c4f594 100644 --- a/source/simulation2/system/ComponentManager.cpp +++ b/source/simulation2/system/ComponentManager.cpp @@ -233,7 +233,7 @@ void CComponentManager::Script_RegisterComponentType_Common(int iid, const std:: } JS::RootedValue protoVal(rq.cx); - if (!m_ScriptInterface.GetProperty(ctor, "prototype", &protoVal)) + if (!Script::GetProperty(rq, ctor, "prototype", &protoVal)) { ScriptException::Raise(rq, "Failed to get property 'prototype'"); return; @@ -245,8 +245,8 @@ void CComponentManager::Script_RegisterComponentType_Common(int iid, const std:: } std::string schema = ""; - if (m_ScriptInterface.HasProperty(protoVal, "Schema")) - m_ScriptInterface.GetProperty(protoVal, "Schema", schema); + if (Script::HasProperty(rq, protoVal, "Schema")) + Script::GetProperty(rq, protoVal, "Schema", schema); // Construct a new ComponentType, using the wrapper's alloc functions ComponentType ct{ @@ -265,7 +265,7 @@ void CComponentManager::Script_RegisterComponentType_Common(int iid, const std:: // Find all the ctor prototype's On* methods, and subscribe to the appropriate messages: std::vector methods; - if (!m_ScriptInterface.EnumeratePropertyNames(protoVal, false, methods)) + if (!Script::EnumeratePropertyNames(rq, protoVal, false, methods)) { ScriptException::Raise(rq, "Failed to enumerate component properties."); return; diff --git a/source/simulation2/system/TurnManager.cpp b/source/simulation2/system/TurnManager.cpp index 807d611338..152d1f154d 100644 --- a/source/simulation2/system/TurnManager.cpp +++ b/source/simulation2/system/TurnManager.cpp @@ -26,6 +26,7 @@ #include "ps/CLogger.h" #include "ps/Replay.h" #include "ps/Util.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptExtraHeaders.h" // StructuredClone #include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" @@ -221,9 +222,10 @@ void CTurnManager::AddCommand(int client, int player, JS::HandleValue data, u32 return; } - m_Simulation2.GetScriptInterface().FreezeObject(data, true); - ScriptRequest rq(m_Simulation2.GetScriptInterface()); + + Script::FreezeObject(rq, data, true); + size_t command_in_turns = turn - (m_CurrentTurn+1); if (m_QueuedCommands.size() <= command_in_turns) m_QueuedCommands.resize(command_in_turns+1); @@ -294,7 +296,7 @@ void CTurnManager::QuickSave(JS::HandleValue GUIMetadata) 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); + Script::FreezeObject(rq, m_QuickSaveMetadata, true); LOGMESSAGERENDER("Quicksaved game"); } diff --git a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp index 55af31b097..9c33790bc2 100644 --- a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp @@ -43,6 +43,7 @@ #include "ps/World.h" #include "renderer/Renderer.h" #include "renderer/WaterManager.h" +#include "scriptinterface/Object.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpOwnership.h" @@ -108,10 +109,10 @@ QUERYHANDLER(GenerateMap) JS::RootedValue settings(rq.cx); scriptInterface.ParseJSON(*msg->settings, &settings); - scriptInterface.SetProperty(settings, "mapType", "random"); + Script::SetProperty(rq, settings, "mapType", "random"); JS::RootedValue attrs(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &attrs, "mapType", "random", @@ -136,24 +137,24 @@ QUERYHANDLER(GenerateMap) // Set up 8-element array of empty objects to satisfy init JS::RootedValue playerData(rq.cx); - ScriptInterface::CreateArray(rq, &playerData); + Script::CreateArray(rq, &playerData); for (int i = 0; i < 8; ++i) { JS::RootedValue player(rq.cx); - ScriptInterface::CreateObject(rq, &player); - scriptInterface.SetPropertyInt(playerData, i, player); + Script::CreateObject(rq, &player); + Script::SetPropertyInt(rq, playerData, i, player); } JS::RootedValue settings(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &settings, "mapType", "scenario", "PlayerData", playerData); JS::RootedValue attrs(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &attrs, "mapType", "scenario", @@ -179,7 +180,7 @@ MESSAGEHANDLER(LoadMap) JS::RootedValue attrs(rq.cx); - ScriptInterface::CreateObject( + Script::CreateObject( rq, &attrs, "mapType", "scenario",