1
0
forked from 0ad/0ad

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.
This commit is contained in:
wraitii 2021-05-13 17:23:52 +00:00
parent cb263b9f26
commit 0f60bf3a97
49 changed files with 661 additions and 766 deletions

View File

@ -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,

View File

@ -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<Entity> 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);

View File

@ -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;
}

View File

@ -216,7 +216,7 @@ void CGUIManager::SGUIPage::LoadPage(shared_ptr<ScriptContext> 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));
}

View File

@ -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,

View File

@ -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);

View File

@ -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 <string>
@ -184,7 +184,7 @@ template<> bool Script::FromJSVal<CGUIColor>(const ScriptRequest& rq, JS::Handle
template<> void Script::ToJSVal<CRect>(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<CGUISpriteInstance>(const ScriptRequest& rq, J
template<> void Script::ToJSVal<CSize2D>(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<CSize2D>(const ScriptRequest& rq, JS::HandleValue v, CSize2D& out)
@ -355,7 +355,7 @@ template<> bool Script::FromJSVal<CSize2D>(const ScriptRequest& rq, JS::HandleVa
template<> void Script::ToJSVal<CVector2D>(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<CVector2D>(const ScriptRequest& rq, JS::HandleValue v, CVector2D& out)

View File

@ -208,10 +208,10 @@ bool JSI_GUIProxy<T>::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;
}

View File

@ -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);

View File

@ -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;\

View File

@ -28,6 +28,7 @@
#include "scriptinterface/ScriptRequest.h"
#include "scriptinterface/ScriptInterface.h"
#include "scriptinterface/StructuredClone.h"
#include "scriptinterface/Object.h"
#include <memory>
@ -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);

View File

@ -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;

View File

@ -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<std::string> 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<std::string> 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<const glooxwrapper::string, SPlayer>& 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<JS::Value>(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<JS::Value>& 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<JS::Value>(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<JS::Value>& 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);

View File

@ -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);

View File

@ -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<const CStr, PlayerAssignment>& 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(

View File

@ -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<JS::Value>(message));
}

View File

@ -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

View File

@ -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",

View File

@ -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] }");

View File

@ -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");
}

View File

@ -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<CStr>& 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, &currentPlayer) || currentPlayer.isUndefined())
if (!Script::GetPropertyInt(rq, playerData, playerID-offset, &currentPlayer) || 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, &currentPlayer);
Script::CreateObject(rq, &currentPlayer);
}
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, &currentPlayer) || currentPlayer.isUndefined())
if (!Script::GetPropertyInt(rq, playerData, playerID-offset, &currentPlayer) || 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, &currentPlayer);
Script::CreateObject(rq, &currentPlayer);
}
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, &currentPlayer) || currentPlayer.isUndefined())
if (!Script::GetPropertyInt(rq, playerData, playerID-offset, &currentPlayer) || 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, &currentPlayer);
Script::CreateObject(rq, &currentPlayer);
}
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, &currentPlayer) || currentPlayer.isUndefined())
if (!Script::GetPropertyInt(rq, playerData, playerID-offset, &currentPlayer) || 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, &currentPlayer);
Script::CreateObject(rq, &currentPlayer);
}
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<CStrW> 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<CStrW> 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);
}

View File

@ -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<char>(ifs)), std::istreambuf_iterator<char>());
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<GLfloat>::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<GLfloat>::quiet_NaN(), std::numeric_limits<GLfloat>::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)
{

View File

@ -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 <algorithm>
@ -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<CStr> 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>& 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;
}

View File

@ -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 <algorithm>
@ -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<std::string> 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<ProfileColumn>& 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;

View File

@ -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<std::vector<CStr>> replayMods;
scriptInterface.GetProperty(attribs, "mods", replayMods);
Script::GetProperty(rq, attribs, "mods", replayMods);
std::vector<std::vector<CStr>> 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")

View File

@ -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;

View File

@ -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<double>(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";

View File

@ -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<std::string> 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))

View File

@ -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<ModIoModData>& 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<const std::string, std::string>& 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<DownloadProgressStatus, std::string> 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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<typename PropType>
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<int, PropType>)
{
JS::RootedId id(rq.cx, INT_TO_JSID(name));
return JS_GetPropertyById(rq.cx, object, id, out);
}
else if constexpr (std::is_same_v<const char*, PropType>)
return JS_GetProperty(rq.cx, object, name, out);
else
return JS_GetUCProperty(rq.cx, object, name, wcslen(name), out);
}
template<typename T, typename PropType>
inline bool GetProperty(const ScriptRequest& rq, JS::HandleValue obj, PropType name, T& out)
{
JS::RootedValue val(rq.cx);
if (!GetProperty<PropType>(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<typename T>
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<typename PropType>
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<int, PropType>)
{
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<const char*, PropType>)
return JS_DefineProperty(rq.cx, object, name, value, attrs);
else
return JS_DefineUCProperty(rq.cx, object, name, value, attrs);
}
template<typename T, typename PropType>
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<PropType>(rq, obj, name, val, constant, enumerable);
}
template<typename T>
inline bool SetPropertyInt(const ScriptRequest& rq, JS::HandleValue obj, int name, const T& value, bool constant = false, bool enumerable = true)
{
return SetProperty<T, int>(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<std::string>& 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<typename T, typename... Args>
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

View File

@ -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<const char16_t*>(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<std::string>& 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);

View File

@ -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<typename... Args>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<std::string>& 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<typename T, typename... Args>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, T& out) const
{
ScriptRequest rq(this);
return GetProperty(rq, obj, name, out);
}
template<typename T>
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<typename T>
bool ScriptInterface::GetPropertyInt(JS::HandleValue obj, int name, T& out) const
{
ScriptRequest rq(this);
return GetPropertyInt(rq, obj, name, out);
}
template<typename T>
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<typename T>
bool ScriptInterface::Eval(const char* code, T& ret) const
{

View File

@ -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);
}

View File

@ -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<VfsPath>* loadedScripts)
{
bool ok = true;
if (componentManager.GetScriptInterface().HasProperty(mapSettings, "TriggerScripts"))
ScriptRequest rq(componentManager.GetScriptInterface());
if (Script::HasProperty(rq, mapSettings, "TriggerScripts"))
{
std::vector<std::string> 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<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY);
@ -413,9 +416,10 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
ENSURE(LoadDefaultScripts(*m_SecondaryComponentManager, m_SecondaryLoadedScripts.get()));
ResetComponentState(*m_SecondaryComponentManager, false, false);
ScriptRequest rq(scriptInterface);
// Load the trigger scripts after we have loaded the simulation.
{
ScriptRequest rq(scriptInterface);
ScriptRequest rq2(m_SecondaryComponentManager->GetScriptInterface());
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<SimulationComman
std::unique_ptr<CMapReader> mapReader = std::make_unique<CMapReader>();
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::vector<SimulationComman
else
{
std::wstring mapFile;
scriptInterface.GetProperty(m_InitAttributes, "map", mapFile);
Script::GetProperty(rq, m_InitAttributes, "map", mapFile);
VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
mapReader->LoadMap(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);

View File

@ -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<std::string, pass_class_t> classes;
cmpPathfinder->GetPassabilityClasses(classes);
for (std::map<std::string, pass_class_t>::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;

View File

@ -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);

View File

@ -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<CParamNode>(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 CParamNode*>(const ScriptRequest& rq, JS::MutableHandleValue ret, const CParamNode* const& val)
@ -112,7 +110,7 @@ template<> bool Script::FromJSVal<CColor>(const ScriptRequest& rq, JS::HandleVa
template<> void Script::ToJSVal<CColor>(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<Grid<u8> >(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<Grid<u16> >(const ScriptRequest& rq, JS::Mutabl
}
JS::RootedValue data(rq.cx, JS::ObjectValue(*objArr));
ScriptInterface::CreateObject(
Script::CreateObject(
rq,
ret,
"width", val.m_W,

View File

@ -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;

View File

@ -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);
}

View File

@ -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).

View File

@ -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.

View File

@ -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"

View File

@ -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 = "<empty/>";
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<std::string> methods;
if (!m_ScriptInterface.EnumeratePropertyNames(protoVal, false, methods))
if (!Script::EnumeratePropertyNames(rq, protoVal, false, methods))
{
ScriptException::Raise(rq, "Failed to enumerate component properties.");
return;

View File

@ -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");
}

View File

@ -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",