mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Remove Script::CreateArray
It's better to construct a js-array from a `JS::RootedValueVector`. Because it is more strongly typed and the index doesn't has to be specified when appending an element. Some usages are replaced with `JS::RootedValueArray`. Fixes: #8702
This commit is contained in:
parent
fe9c0f6c2f
commit
df18e22277
14 changed files with 146 additions and 136 deletions
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -244,11 +244,16 @@ bool JSI_GUIProxy<T>::get(JSContext* cx, JS::HandleObject proxy, JS::HandleValue
|
|||
}
|
||||
else if (propName == "children")
|
||||
{
|
||||
Script::CreateArray(rq, vp);
|
||||
|
||||
for (size_t i = 0; i < e->m_Children.size(); ++i)
|
||||
Script::SetPropertyInt(rq, vp, i, e->m_Children[i]);
|
||||
JS::RootedValueVector children{rq.cx};
|
||||
|
||||
for (const auto& child : e->m_Children)
|
||||
{
|
||||
JS::RootedValue rootedChild{rq.cx};
|
||||
Script::ToJSVal(rq, &rootedChild, child);
|
||||
if (!children.append(rootedChild))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
vp.set(JS::ObjectValue(*JS::NewArrayObject(rq.cx, children)));
|
||||
return true;
|
||||
}
|
||||
else if (propName == "name")
|
||||
|
|
|
|||
|
|
@ -573,9 +573,7 @@ void XmppClient::handleOOB(const gloox::JID&, const gloox::OOB&)
|
|||
*/
|
||||
JS::Value XmppClient::GUIGetPlayerList(const ScriptRequest& rq)
|
||||
{
|
||||
JS::RootedValue ret(rq.cx);
|
||||
Script::CreateArray(rq, &ret);
|
||||
int j = 0;
|
||||
JS::RootedValueVector players{rq.cx};
|
||||
|
||||
for (const std::pair<const std::string, SPlayer>& p : m_PlayerMap)
|
||||
{
|
||||
|
|
@ -589,9 +587,10 @@ JS::Value XmppClient::GUIGetPlayerList(const ScriptRequest& rq)
|
|||
"rating", p.second.m_Rating,
|
||||
"role", p.second.m_Role);
|
||||
|
||||
Script::SetPropertyInt(rq, ret, j++, player);
|
||||
if (!players.append(player))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
return ret;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, players));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -601,9 +600,7 @@ JS::Value XmppClient::GUIGetPlayerList(const ScriptRequest& rq)
|
|||
*/
|
||||
JS::Value XmppClient::GUIGetGameList(const ScriptRequest& rq)
|
||||
{
|
||||
JS::RootedValue ret(rq.cx);
|
||||
Script::CreateArray(rq, &ret);
|
||||
int j = 0;
|
||||
JS::RootedValueVector games{rq.cx};
|
||||
|
||||
const char* stats[] = { "name", "hostUsername", "hostJID", "state", "hasPassword",
|
||||
"nbp", "maxnbp", "players", "mapName", "niceMapName", "mapSize", "mapType",
|
||||
|
|
@ -617,9 +614,10 @@ JS::Value XmppClient::GUIGetGameList(const ScriptRequest& rq)
|
|||
for (size_t i = 0; i < ARRAY_SIZE(stats); ++i)
|
||||
Script::SetProperty(rq, game, stats[i], t->findAttribute(stats[i]));
|
||||
|
||||
Script::SetPropertyInt(rq, ret, j++, game);
|
||||
if (!games.append(game))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
return ret;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, games));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -629,9 +627,7 @@ JS::Value XmppClient::GUIGetGameList(const ScriptRequest& rq)
|
|||
*/
|
||||
JS::Value XmppClient::GUIGetBoardList(const ScriptRequest& rq)
|
||||
{
|
||||
JS::RootedValue ret(rq.cx);
|
||||
Script::CreateArray(rq, &ret);
|
||||
int j = 0;
|
||||
JS::RootedValueVector boardList{rq.cx};
|
||||
|
||||
const char* attributes[] = { "name", "rank", "rating" };
|
||||
|
||||
|
|
@ -643,9 +639,10 @@ JS::Value XmppClient::GUIGetBoardList(const ScriptRequest& rq)
|
|||
for (size_t i = 0; i < ARRAY_SIZE(attributes); ++i)
|
||||
Script::SetProperty(rq, board, attributes[i], t->findAttribute(attributes[i]));
|
||||
|
||||
Script::SetPropertyInt(rq, ret, j++, board);
|
||||
if (!boardList.append(board))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
return ret;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, boardList));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -655,9 +652,7 @@ JS::Value XmppClient::GUIGetBoardList(const ScriptRequest& rq)
|
|||
*/
|
||||
JS::Value XmppClient::GUIGetProfile(const ScriptRequest& rq)
|
||||
{
|
||||
JS::RootedValue ret(rq.cx);
|
||||
Script::CreateArray(rq, &ret);
|
||||
int j = 0;
|
||||
JS::RootedValueVector profileData{rq.cx};
|
||||
|
||||
const char* stats[] = { "player", "rating", "totalGamesPlayed", "highestRating", "wins", "losses", "rank" };
|
||||
|
||||
|
|
@ -669,9 +664,10 @@ JS::Value XmppClient::GUIGetProfile(const ScriptRequest& rq)
|
|||
for (size_t i = 0; i < ARRAY_SIZE(stats); ++i)
|
||||
Script::SetProperty(rq, profile, stats[i], t->findAttribute(stats[i]));
|
||||
|
||||
Script::SetPropertyInt(rq, ret, j++, profile);
|
||||
if (!profileData.append(profile))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
return ret;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, profileData));
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
|
|
@ -735,14 +731,12 @@ 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);
|
||||
Script::CreateArray(rq, &messages);
|
||||
|
||||
int j = 0;
|
||||
JS::RootedValueVector messages{rq.cx};
|
||||
|
||||
for (const JS::Heap<JS::Value>& message : m_GuiMessageQueue)
|
||||
{
|
||||
Script::SetPropertyInt(rq, messages, j++, message);
|
||||
if (!messages.append(message))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
|
||||
// Store historic chat messages.
|
||||
// Only store relevant messages to minimize memory footprint.
|
||||
|
|
@ -770,7 +764,8 @@ JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& guiInterface)
|
|||
m_GuiMessageQueue.clear();
|
||||
|
||||
// Copy the messages over to the caller script interface.
|
||||
return Script::CloneValueFromOtherCompartment(guiInterface, *m_ScriptInterface, messages);
|
||||
return Script::CloneValueFromOtherCompartment(guiInterface, *m_ScriptInterface,
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, messages))});
|
||||
}
|
||||
|
||||
JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& guiInterface)
|
||||
|
|
@ -780,15 +775,17 @@ JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& guiInterfac
|
|||
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
|
||||
JS::RootedValue messages(rq.cx);
|
||||
Script::CreateArray(rq, &messages);
|
||||
JS::RootedValueVector messages{rq.cx};
|
||||
|
||||
int j = 0;
|
||||
for (const JS::Heap<JS::Value>& message : m_HistoricGuiMessages)
|
||||
Script::SetPropertyInt(rq, messages, j++, message);
|
||||
{
|
||||
if (!messages.append(message))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
|
||||
// Copy the messages over to the caller script interface.
|
||||
return Script::CloneValueFromOtherCompartment(guiInterface, *m_ScriptInterface, messages);
|
||||
return Script::CloneValueFromOtherCompartment(guiInterface, *m_ScriptInterface,
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, messages))});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -37,11 +37,9 @@ public:
|
|||
ScriptInterface script("Test", "Test", g_ScriptContext);
|
||||
ScriptRequest rq(script);
|
||||
|
||||
JS::RootedValue val(rq.cx);
|
||||
Script::CreateArray(rq, &val);
|
||||
Script::SetPropertyInt(rq, val, 0, 4);
|
||||
|
||||
CSimulationMessage msg(script, 1, 2, 3, val);
|
||||
JS::RootedValueArray<1> val{rq.cx, JS::ValueArray<1>{JS::NumberValue(4)}};
|
||||
CSimulationMessage msg(script, 1, 2, 3,
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, val))});
|
||||
TS_ASSERT_STR_EQUALS(msg.ToString(), "CSimulationMessage { m_Client: 1, m_Player: 2, m_Turn: 3, m_Data: [4] }");
|
||||
|
||||
size_t len = msg.GetSerializedLength();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -193,14 +193,13 @@ JS::Value MakeFreeTypeReport(const ScriptRequest& rq)
|
|||
|
||||
void ReportLibraries(const ScriptRequest& rq, JS::HandleValue settings)
|
||||
{
|
||||
JS::RootedValue librariesSettings(rq.cx);
|
||||
Script::CreateArray(rq, &librariesSettings);
|
||||
int libraryCount = 0;
|
||||
JS::RootedValueVector librariesSettings{rq.cx};
|
||||
|
||||
auto appendLibrary = [&rq, &librariesSettings, &libraryCount](const JS::Value& librarySettings)
|
||||
auto appendLibrary = [&rq, &librariesSettings](const JS::Value& librarySettings)
|
||||
{
|
||||
JS::RootedValue value(rq.cx, librarySettings);
|
||||
Script::SetPropertyInt(rq, librariesSettings, libraryCount++, value);
|
||||
if (!librariesSettings.append(value))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
};
|
||||
|
||||
appendLibrary(MakeSDLReport(rq));
|
||||
|
|
@ -230,7 +229,8 @@ void ReportLibraries(const ScriptRequest& rq, JS::HandleValue settings)
|
|||
.MakeReport());
|
||||
#endif
|
||||
|
||||
Script::SetProperty(rq, settings, "libraries", librariesSettings);
|
||||
Script::SetProperty(rq, settings, "libraries",
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, librariesSettings))});
|
||||
}
|
||||
|
||||
void WriteSystemInfo(Renderer::Backend::IDevice* device, const utsname& un)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -494,19 +494,23 @@ namespace
|
|||
|
||||
for (size_t r = 0; r < table->GetNumberRows(); ++r)
|
||||
{
|
||||
JS::RootedValue row(rq.cx);
|
||||
Script::CreateArray(rq, &row);
|
||||
JS::RootedValueVector row{rq.cx};
|
||||
if (!row.resize(columns.size() + 1))
|
||||
throw std::runtime_error{"Resize failed"};
|
||||
|
||||
Script::SetProperty(rq, data, table->GetCellText(r, 0).c_str(), row);
|
||||
|
||||
if (table->GetChild(r))
|
||||
{
|
||||
JS::RootedValue childRows(rq.cx, DumpRows(table->GetChild(r)));
|
||||
Script::SetPropertyInt(rq, row, 0, childRows);
|
||||
row[0].set(childRows);
|
||||
}
|
||||
|
||||
for (size_t c = 1; c < columns.size(); ++c)
|
||||
Script::SetPropertyInt(rq, row, c, table->GetCellText(r, c));
|
||||
{
|
||||
row[c].set(JS::StringValue(
|
||||
JS_NewStringCopyZ(rq.cx, table->GetCellText(r, c).c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -279,8 +279,7 @@ JS::Value SavedGames::GetSavedGames(const ScriptInterface& scriptInterface)
|
|||
PROFILE2("GetSavedGames");
|
||||
ScriptRequest rq(scriptInterface);
|
||||
|
||||
JS::RootedValue games(rq.cx);
|
||||
Script::CreateArray(rq, &games);
|
||||
JS::RootedValueVector games{rq.cx};
|
||||
|
||||
Status err;
|
||||
|
||||
|
|
@ -288,10 +287,10 @@ JS::Value SavedGames::GetSavedGames(const ScriptInterface& scriptInterface)
|
|||
err = vfs::GetPathnames(g_VFS, "saves/", L"*.0adsave", pathnames);
|
||||
WARN_IF_ERR(err);
|
||||
|
||||
for (size_t i = 0; i < pathnames.size(); ++i)
|
||||
for (const VfsPath& pathname : pathnames)
|
||||
{
|
||||
OsPath realPath;
|
||||
err = g_VFS->GetRealPath(pathnames[i], realPath);
|
||||
err = g_VFS->GetRealPath(pathname, realPath);
|
||||
if (err < 0)
|
||||
{
|
||||
DEBUG_WARN_ERR(err);
|
||||
|
|
@ -319,13 +318,14 @@ JS::Value SavedGames::GetSavedGames(const ScriptInterface& scriptInterface)
|
|||
Script::CreateObject(
|
||||
rq,
|
||||
&game,
|
||||
"id", pathnames[i].Basename(),
|
||||
"id", pathname.Basename(),
|
||||
"metadata", metadata);
|
||||
|
||||
Script::SetPropertyInt(rq, games, i, game);
|
||||
if (!games.append(game))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
|
||||
return games;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, games));
|
||||
}
|
||||
|
||||
bool SavedGames::DeleteSavedGame(const std::wstring& name)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -255,19 +255,20 @@ JS::Value VisualReplay::GetReplays(const ScriptInterface& scriptInterface, bool
|
|||
ScriptRequest rq(scriptInterface);
|
||||
JS::RootedObject replays(rq.cx, ReloadReplayCache(scriptInterface, compareFiles));
|
||||
// Only take entries with data
|
||||
JS::RootedValue replaysWithoutNullEntries(rq.cx);
|
||||
Script::CreateArray(rq, &replaysWithoutNullEntries);
|
||||
JS::RootedValueVector replaysWithoutNullEntries{rq.cx};
|
||||
|
||||
u32 replaysLength = 0;
|
||||
JS::GetArrayLength(rq.cx, replays, &replaysLength);
|
||||
for (u32 j = 0, i = 0; j < replaysLength; ++j)
|
||||
for (u32 j = 0; j < replaysLength; ++j)
|
||||
{
|
||||
JS::RootedValue replay(rq.cx);
|
||||
JS_GetElement(rq.cx, replays, j, &replay);
|
||||
if (Script::HasProperty(rq, replay, "attribs"))
|
||||
Script::SetPropertyInt(rq, replaysWithoutNullEntries, i++, replay);
|
||||
if (!Script::HasProperty(rq, replay, "attribs"))
|
||||
continue;
|
||||
if (!replaysWithoutNullEntries.append(replay))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
return replaysWithoutNullEntries;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, replaysWithoutNullEntries));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -70,10 +70,10 @@ JS::Value GetMods(const ScriptRequest& rq)
|
|||
|
||||
const std::vector<ModIoModData>& availableMods = g_ModIo->GetMods();
|
||||
|
||||
JS::RootedValue mods(rq.cx);
|
||||
Script::CreateArray(rq, &mods, availableMods.size());
|
||||
JS::RootedValueVector mods{rq.cx};
|
||||
if (!mods.reserve(availableMods.size()))
|
||||
throw std::runtime_error{"Reserve failed"};
|
||||
|
||||
u32 i = 0;
|
||||
for (const ModIoModData& mod : availableMods)
|
||||
{
|
||||
JS::RootedValue m(rq.cx);
|
||||
|
|
@ -83,10 +83,11 @@ JS::Value GetMods(const ScriptRequest& rq)
|
|||
Script::SetProperty(rq, m, prop.first.c_str(), prop.second, true);
|
||||
|
||||
Script::SetProperty(rq, m, "dependencies", mod.dependencies, true);
|
||||
Script::SetPropertyInt(rq, mods, i++, m);
|
||||
if (!mods.append(m))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
|
||||
return mods;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, mods));
|
||||
}
|
||||
|
||||
const std::map<DownloadProgressStatus, std::string> statusStrings = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -227,21 +227,20 @@ JS::Value ReadFileLines(const ScriptRequest& rq, const std::wstring& filename)
|
|||
// split into array of strings (one per line)
|
||||
std::stringstream ss(contents);
|
||||
|
||||
JS::RootedValue line_array(rq.cx);
|
||||
Script::CreateArray(rq, &line_array);
|
||||
JS::RootedValueVector lineArray{rq.cx};
|
||||
|
||||
std::string line;
|
||||
int cur_line = 0;
|
||||
|
||||
while (std::getline(ss, line))
|
||||
{
|
||||
// Decode each line as UTF-8
|
||||
JS::RootedValue val(rq.cx);
|
||||
Script::ToJSVal(rq, &val, CStr(line).FromUTF8());
|
||||
Script::SetPropertyInt(rq, line_array, cur_line++, val);
|
||||
if (!lineArray.append(val))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
|
||||
return line_array;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, lineArray));
|
||||
}
|
||||
|
||||
// Return file contents parsed as a JS Object
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -726,16 +726,19 @@ void CDevice::Report(const ScriptRequest& rq, JS::HandleValue settings)
|
|||
ReportAvailablePhysicalDevice(m_ChoosenDevice, rq, device);
|
||||
Script::SetProperty(rq, settings, "choosen_device", device);
|
||||
|
||||
JS::RootedValue availableDevices(rq.cx);
|
||||
Script::CreateArray(rq, &availableDevices, m_AvailablePhysicalDevices.size());
|
||||
for (size_t index = 0; index < m_AvailablePhysicalDevices.size(); ++index)
|
||||
JS::RootedValueVector availableDevices{rq.cx};
|
||||
if (!availableDevices.reserve(m_AvailablePhysicalDevices.size()))
|
||||
throw std::runtime_error{"Reserve failed"};
|
||||
for (const SAvailablePhysicalDevice& d : m_AvailablePhysicalDevices)
|
||||
{
|
||||
JS::RootedValue device(rq.cx);
|
||||
Script::CreateObject(rq, &device);
|
||||
ReportAvailablePhysicalDevice(m_AvailablePhysicalDevices[index], rq, device);
|
||||
Script::SetPropertyInt(rq, availableDevices, index, device);
|
||||
ReportAvailablePhysicalDevice(d, rq, device);
|
||||
if (!availableDevices.append(device))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
Script::SetProperty(rq, settings, "available_devices", availableDevices);
|
||||
Script::SetProperty(rq, settings, "available_devices",
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, availableDevices))});
|
||||
|
||||
Script::SetProperty(rq, settings, "instance_extensions", m_InstanceExtensions);
|
||||
Script::SetProperty(rq, settings, "validation_layers", m_ValidationLayers);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
#include <js/RootingAPI.h>
|
||||
#include <js/Value.h>
|
||||
#include <limits>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
|
@ -353,32 +354,38 @@ void ReportAvailablePhysicalDevice(const SAvailablePhysicalDevice& device,
|
|||
JS::RootedValue memory(rq.cx);
|
||||
Script::CreateObject(rq, &memory);
|
||||
|
||||
JS::RootedValue memoryTypes(rq.cx);
|
||||
Script::CreateArray(rq, &memoryTypes, device.memoryProperties.memoryTypeCount);
|
||||
for (uint32_t memoryTypeIndex = 0; memoryTypeIndex < device.memoryProperties.memoryTypeCount; ++memoryTypeIndex)
|
||||
JS::RootedValueVector memoryTypes{rq.cx};
|
||||
if (!memoryTypes.reserve(device.memoryProperties.memoryTypeCount))
|
||||
throw std::runtime_error{"Reserve failed"};
|
||||
for (const VkMemoryType& type : std::span{device.memoryProperties.memoryTypes,
|
||||
device.memoryProperties.memoryTypeCount})
|
||||
{
|
||||
const VkMemoryType& type = device.memoryProperties.memoryTypes[memoryTypeIndex];
|
||||
JS::RootedValue memoryType(rq.cx);
|
||||
Script::CreateObject(rq, &memoryType);
|
||||
Script::SetProperty(rq, memoryType, "propertyFlags", static_cast<uint32_t>(type.propertyFlags));
|
||||
Script::SetProperty(rq, memoryType, "heapIndex", type.heapIndex);
|
||||
Script::SetPropertyInt(rq, memoryTypes, memoryTypeIndex, memoryType);
|
||||
if (!memoryTypes.append(memoryType))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
JS::RootedValue memoryHeaps(rq.cx);
|
||||
Script::CreateArray(rq, &memoryHeaps, device.memoryProperties.memoryHeapCount);
|
||||
for (uint32_t memoryHeapIndex = 0; memoryHeapIndex < device.memoryProperties.memoryHeapCount; ++memoryHeapIndex)
|
||||
JS::RootedValueVector memoryHeaps{rq.cx};
|
||||
if (!memoryHeaps.reserve(device.memoryProperties.memoryHeapCount))
|
||||
throw std::runtime_error{"Reserve failed"};
|
||||
for (const VkMemoryHeap& heap : std::span{device.memoryProperties.memoryHeaps,
|
||||
device.memoryProperties.memoryHeapCount})
|
||||
{
|
||||
const VkMemoryHeap& heap = device.memoryProperties.memoryHeaps[memoryHeapIndex];
|
||||
JS::RootedValue memoryHeap(rq.cx);
|
||||
Script::CreateObject(rq, &memoryHeap);
|
||||
// We can't serialize uint64_t in JS, so put data in KiB.
|
||||
Script::SetProperty(rq, memoryHeap, "size", static_cast<uint32_t>(heap.size / 1024));
|
||||
Script::SetProperty(rq, memoryHeap, "flags", static_cast<uint32_t>(heap.flags));
|
||||
Script::SetPropertyInt(rq, memoryHeaps, memoryHeapIndex, memoryHeap);
|
||||
if (!memoryHeaps.append(memoryHeap))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
|
||||
Script::SetProperty(rq, memory, "types", memoryTypes);
|
||||
Script::SetProperty(rq, memory, "heaps", memoryHeaps);
|
||||
Script::SetProperty(rq, memory, "types",
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, memoryTypes))});
|
||||
Script::SetProperty(rq, memory, "heaps",
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, memoryHeaps))});
|
||||
Script::SetProperty(rq, settings, "memory", memory);
|
||||
|
||||
JS::RootedValue constants(rq.cx);
|
||||
|
|
@ -513,28 +520,33 @@ void ReportAvailablePhysicalDevice(const SAvailablePhysicalDevice& device,
|
|||
|
||||
Script::SetProperty(rq, settings, "features", features);
|
||||
|
||||
JS::RootedValue presentModes(rq.cx);
|
||||
Script::CreateArray(rq, &presentModes, device.presentModes.size());
|
||||
for (size_t index = 0; index < device.presentModes.size(); ++index)
|
||||
JS::RootedValueVector presentModes{rq.cx};
|
||||
if (!presentModes.reserve(device.presentModes.size()))
|
||||
throw std::runtime_error{"Reserve failed"};
|
||||
for (const VkPresentModeKHR& mode : device.presentModes)
|
||||
{
|
||||
Script::SetPropertyInt(
|
||||
rq, presentModes, index, static_cast<uint32_t>(device.presentModes[index]));
|
||||
if (!presentModes.append(JS::NumberValue(static_cast<uint32_t>(mode))))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
Script::SetProperty(rq, settings, "present_modes", presentModes);
|
||||
Script::SetProperty(rq, settings, "present_modes",
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, presentModes))});
|
||||
|
||||
JS::RootedValue surfaceFormats(rq.cx);
|
||||
Script::CreateArray(rq, &surfaceFormats, device.surfaceFormats.size());
|
||||
for (size_t index = 0; index < device.surfaceFormats.size(); ++index)
|
||||
JS::RootedValueVector surfaceFormats{rq.cx};
|
||||
if (!surfaceFormats.reserve(device.surfaceFormats.size()))
|
||||
throw std::runtime_error{"Reserve failed"};
|
||||
for (const VkSurfaceFormatKHR& format : device.surfaceFormats)
|
||||
{
|
||||
JS::RootedValue surfaceFormat(rq.cx);
|
||||
Script::CreateObject(rq, &surfaceFormat);
|
||||
Script::SetProperty(
|
||||
rq, surfaceFormat, "format", static_cast<uint32_t>(device.surfaceFormats[index].format));
|
||||
rq, surfaceFormat, "format", static_cast<uint32_t>(format.format));
|
||||
Script::SetProperty(
|
||||
rq, surfaceFormat, "color_space", static_cast<uint32_t>(device.surfaceFormats[index].colorSpace));
|
||||
Script::SetPropertyInt(rq, surfaceFormats, index, surfaceFormat);
|
||||
rq, surfaceFormat, "color_space", static_cast<uint32_t>(format.colorSpace));
|
||||
if (!surfaceFormats.append(surfaceFormat))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
Script::SetProperty(rq, settings, "surface_formats", surfaceFormats);
|
||||
Script::SetProperty(rq, settings, "surface_formats",
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, surfaceFormats))});
|
||||
|
||||
JS::RootedValue surfaceCapabilities(rq.cx);
|
||||
Script::CreateObject(rq, &surfaceCapabilities);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -271,15 +271,6 @@ inline bool CreateObject(const ScriptRequest& rq, JS::MutableHandleValue objectV
|
|||
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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -148,9 +148,7 @@ JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(const ScriptInterface& scri
|
|||
ENSURE(sim);
|
||||
|
||||
ScriptRequest rq(scriptInterface);
|
||||
JS::RootedValue edgeList(rq.cx);
|
||||
Script::CreateArray(rq, &edgeList);
|
||||
int edgeListIndex = 0;
|
||||
JS::RootedValueVector edgeList{rq.cx};
|
||||
|
||||
const float distanceThreshold{g_ConfigDB.Get("gui.session.snaptoedgesdistancethreshold", 10.0f)};
|
||||
CFixedVector2D entityPos(x, z);
|
||||
|
|
@ -202,10 +200,11 @@ JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(const ScriptInterface& scri
|
|||
"normal", normal,
|
||||
"order", "cw");
|
||||
|
||||
Script::SetPropertyInt(rq, edgeList, edgeListIndex++, edge);
|
||||
if (!edgeList.append(edge))
|
||||
throw std::runtime_error{"Append failed"};
|
||||
}
|
||||
}
|
||||
return edgeList;
|
||||
return JS::ObjectValue(*JS::NewArrayObject(rq.cx, edgeList));
|
||||
}
|
||||
|
||||
std::vector<entity_id_t> PickSimilarPlayerEntities(const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -163,14 +163,13 @@ QUERYHANDLER(GenerateMap)
|
|||
ScriptRequest rq(scriptInterface);
|
||||
|
||||
// Set up 8-element array of empty objects to satisfy init
|
||||
JS::RootedValue playerData(rq.cx);
|
||||
Script::CreateArray(rq, &playerData);
|
||||
JS::RootedValueArray<8> playerData{rq.cx};
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
for (JS::Value& p : playerData.get().elements)
|
||||
{
|
||||
JS::RootedValue player(rq.cx);
|
||||
Script::CreateObject(rq, &player);
|
||||
Script::SetPropertyInt(rq, playerData, i, player);
|
||||
p = player;
|
||||
}
|
||||
|
||||
JS::RootedValue settings(rq.cx);
|
||||
|
|
@ -178,7 +177,8 @@ QUERYHANDLER(GenerateMap)
|
|||
rq,
|
||||
&settings,
|
||||
"mapType", "scenario",
|
||||
"PlayerData", playerData);
|
||||
"PlayerData",
|
||||
JS::RootedValue{rq.cx, JS::ObjectValue(*JS::NewArrayObject(rq.cx, playerData))});
|
||||
|
||||
JS::RootedValue attrs(rq.cx);
|
||||
Script::CreateObject(
|
||||
|
|
|
|||
Loading…
Reference in a new issue