From cb346e207b288ba319aec8d929591eb9ff2ce9e0 Mon Sep 17 00:00:00 2001 From: wraitii Date: Tue, 2 Mar 2021 20:01:14 +0000 Subject: [PATCH] Refactor all usage of RegisterFunction to ScriptFunction::Register - Replace ScriptInterface::RegisterFunction with ScriptFunction::Register - Mostly removing unused cmpPrivate* - Some usage introduces specific getters (mapgenerator, AIWorker, XmppClient,...) - Several passthrough functions are simply removed in favour of calling the original, reducing duplication - Make use of ScriptRequest/ScriptInterface capabilities where relevant. - Make JSI_* headers only expose necessary functions, lightening them considerably and reducing duplication - Reuse namespaces in JSI_* implementations directly, reducing visual noise there Follows f3aedf88a6 Differential Revision: https://code.wildfiregames.com/D3626 This was SVN commit r24983. --- source/graphics/CameraController.cpp | 1 - source/graphics/GameView.cpp | 1 - source/graphics/MapGenerator.cpp | 92 ++-- source/graphics/MapGenerator.h | 23 +- .../scripting/JSInterface_GameView.cpp | 53 ++- .../graphics/scripting/JSInterface_GameView.h | 27 +- .../gui/Scripting/JSInterface_GUIManager.cpp | 67 ++- source/gui/Scripting/JSInterface_GUIManager.h | 16 +- source/gui/Scripting/ScriptFunctions.cpp | 38 +- source/i18n/scripting/JSInterface_L10n.cpp | 204 +++------ source/i18n/scripting/JSInterface_L10n.h | 414 +---------------- source/lobby/IXmppClient.h | 10 +- source/lobby/XmppClient.cpp | 30 +- source/lobby/XmppClient.h | 10 +- source/lobby/scripting/JSInterface_Lobby.cpp | 420 +++--------------- source/lobby/scripting/JSInterface_Lobby.h | 49 +- .../network/scripting/JSInterface_Network.cpp | 95 ++-- .../network/scripting/JSInterface_Network.h | 31 +- source/ps/ModIo.cpp | 2 +- source/ps/ModIo.h | 2 +- source/ps/VisualReplay.cpp | 12 +- source/ps/VisualReplay.h | 11 +- source/ps/scripting/JSInterface_ConfigDB.cpp | 60 +-- source/ps/scripting/JSInterface_ConfigDB.h | 20 +- source/ps/scripting/JSInterface_Console.cpp | 6 +- source/ps/scripting/JSInterface_Debug.cpp | 34 +- source/ps/scripting/JSInterface_Debug.h | 14 +- source/ps/scripting/JSInterface_Game.cpp | 68 +-- source/ps/scripting/JSInterface_Game.h | 20 +- source/ps/scripting/JSInterface_Main.cpp | 58 +-- source/ps/scripting/JSInterface_Main.h | 17 +- source/ps/scripting/JSInterface_ModIo.cpp | 90 ++-- source/ps/scripting/JSInterface_ModIo.h | 12 +- source/ps/scripting/JSInterface_SavedGame.cpp | 50 ++- source/ps/scripting/JSInterface_SavedGame.h | 12 +- .../ps/scripting/JSInterface_UserReport.cpp | 26 +- source/ps/scripting/JSInterface_UserReport.h | 12 +- source/ps/scripting/JSInterface_VFS.cpp | 147 +++--- source/ps/scripting/JSInterface_VFS.h | 40 +- .../ps/scripting/JSInterface_VisualReplay.cpp | 59 +-- .../ps/scripting/JSInterface_VisualReplay.h | 12 +- .../scripting/JSInterface_Renderer.cpp | 25 +- .../renderer/scripting/JSInterface_Renderer.h | 9 +- source/scriptinterface/NativeWrapperDecls.h | 10 - source/scriptinterface/ScriptInterface.cpp | 127 ++---- source/scriptinterface/ScriptInterface.h | 7 +- .../simulation2/components/CCmpAIManager.cpp | 65 +-- .../components/tests/test_scripts.h | 3 +- .../scripting/JSInterface_Simulation.cpp | 68 +-- .../scripting/JSInterface_Simulation.h | 19 +- .../scripting/JSInterface_Sound.cpp | 87 ++-- .../scripting/JSInterface_Sound.h | 4 +- 52 files changed, 820 insertions(+), 1969 deletions(-) diff --git a/source/graphics/CameraController.cpp b/source/graphics/CameraController.cpp index 4bc592d67c..b65a7703b8 100644 --- a/source/graphics/CameraController.cpp +++ b/source/graphics/CameraController.cpp @@ -21,7 +21,6 @@ #include "graphics/HFTracer.h" #include "graphics/Terrain.h" -#include "graphics/scripting/JSInterface_GameView.h" #include "lib/input.h" #include "lib/timer.h" #include "maths/MathUtil.h" diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index b17589e979..860370d55e 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -35,7 +35,6 @@ #include "graphics/TerritoryTexture.h" #include "graphics/Unit.h" #include "graphics/UnitManager.h" -#include "graphics/scripting/JSInterface_GameView.h" #include "lib/input.h" #include "lib/timer.h" #include "lobby/IXmppClient.h" diff --git a/source/graphics/MapGenerator.cpp b/source/graphics/MapGenerator.cpp index 718ef8b6d5..e992f236c9 100644 --- a/source/graphics/MapGenerator.cpp +++ b/source/graphics/MapGenerator.cpp @@ -32,6 +32,7 @@ #include "ps/Profile.h" #include "ps/Threading.h" #include "ps/scripting/JSInterface_VFS.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptContext.h" #include "scriptinterface/ScriptConversions.h" #include "scriptinterface/ScriptInterface.h" @@ -160,6 +161,11 @@ bool CMapGeneratorWorker::Run() return true; } +#define REGISTER_MAPGEN_FUNC(func) \ + ScriptFunction::Register<&CMapGeneratorWorker::func, ScriptFunction::ObjectFromCBData>(rq, #func); +#define REGISTER_MAPGEN_FUNC_NAME(func, name) \ + ScriptFunction::Register<&CMapGeneratorWorker::func, ScriptFunction::ObjectFromCBData>(rq, name); + void CMapGeneratorWorker::InitScriptInterface(const u32 seed) { m_ScriptInterface->SetCallbackData(static_cast(this)); @@ -174,9 +180,10 @@ void CMapGeneratorWorker::InitScriptInterface(const u32 seed) m_ScriptInterface->LoadGlobalScripts(); // File loading - m_ScriptInterface->RegisterFunction("LoadLibrary"); - m_ScriptInterface->RegisterFunction("LoadHeightmapImage"); - m_ScriptInterface->RegisterFunction("LoadMapTerrain"); + ScriptRequest rq(m_ScriptInterface); + REGISTER_MAPGEN_FUNC_NAME(LoadScripts, "LoadLibrary"); + REGISTER_MAPGEN_FUNC_NAME(LoadHeightmap, "LoadHeightmapImage"); + REGISTER_MAPGEN_FUNC(LoadMapTerrain); // Engine constants @@ -190,25 +197,30 @@ void CMapGeneratorWorker::InitScriptInterface(const u32 seed) void CMapGeneratorWorker::RegisterScriptFunctions_MapGenerator() { + ScriptRequest rq(m_ScriptInterface); + // Template functions - m_ScriptInterface->RegisterFunction("GetTemplate"); - m_ScriptInterface->RegisterFunction("TemplateExists"); - m_ScriptInterface->RegisterFunction, std::string, bool, CMapGeneratorWorker::FindTemplates>("FindTemplates"); - m_ScriptInterface->RegisterFunction, std::string, bool, CMapGeneratorWorker::FindActorTemplates>("FindActorTemplates"); + REGISTER_MAPGEN_FUNC(GetTemplate); + REGISTER_MAPGEN_FUNC(TemplateExists); + REGISTER_MAPGEN_FUNC(FindTemplates); + REGISTER_MAPGEN_FUNC(FindActorTemplates); // Progression and profiling - m_ScriptInterface->RegisterFunction("SetProgress"); - m_ScriptInterface->RegisterFunction("GetMicroseconds"); - m_ScriptInterface->RegisterFunction("ExportMap"); + REGISTER_MAPGEN_FUNC(SetProgress); + REGISTER_MAPGEN_FUNC(GetMicroseconds); + REGISTER_MAPGEN_FUNC(ExportMap); } +#undef REGISTER_MAPGEN_FUNC +#undef REGISTER_MAPGEN_FUNC_NAME + int CMapGeneratorWorker::GetProgress() { std::lock_guard lock(m_WorkerMutex); return m_Progress; } -double CMapGeneratorWorker::GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +double CMapGeneratorWorker::GetMicroseconds() { return JS_Now(); } @@ -219,61 +231,47 @@ ScriptInterface::StructuredClone CMapGeneratorWorker::GetResults() return m_MapData; } -bool CMapGeneratorWorker::LoadLibrary(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& name) +void CMapGeneratorWorker::ExportMap(JS::HandleValue data) { - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - return self->LoadScripts(name); -} - -void CMapGeneratorWorker::ExportMap(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data) -{ - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - // Copy results - std::lock_guard lock(self->m_WorkerMutex); - self->m_MapData = self->m_ScriptInterface->WriteStructuredClone(data); - self->m_Progress = 0; + std::lock_guard lock(m_WorkerMutex); + m_MapData = m_ScriptInterface->WriteStructuredClone(data); + m_Progress = 0; } -void CMapGeneratorWorker::SetProgress(ScriptInterface::CmptPrivate* pCmptPrivate, int progress) +void CMapGeneratorWorker::SetProgress(int progress) { - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - // Copy data - std::lock_guard lock(self->m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); - if (progress >= self->m_Progress) - self->m_Progress = progress; + if (progress >= m_Progress) + m_Progress = progress; else - LOGWARNING("The random map script tried to reduce the loading progress from %d to %d", self->m_Progress, progress); + LOGWARNING("The random map script tried to reduce the loading progress from %d to %d", m_Progress, progress); } -CParamNode CMapGeneratorWorker::GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName) +CParamNode CMapGeneratorWorker::GetTemplate(const std::string& templateName) { - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - const CParamNode& templateRoot = self->m_TemplateLoader.GetTemplateFileData(templateName).GetChild("Entity"); + const CParamNode& templateRoot = m_TemplateLoader.GetTemplateFileData(templateName).GetChild("Entity"); if (!templateRoot.IsOk()) LOGERROR("Invalid template found for '%s'", templateName.c_str()); return templateRoot; } -bool CMapGeneratorWorker::TemplateExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName) +bool CMapGeneratorWorker::TemplateExists(const std::string& templateName) { - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - return self->m_TemplateLoader.TemplateExists(templateName); + return m_TemplateLoader.TemplateExists(templateName); } -std::vector CMapGeneratorWorker::FindTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories) +std::vector CMapGeneratorWorker::FindTemplates(const std::string& path, bool includeSubdirectories) { - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - return self->m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES); + return m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES); } -std::vector CMapGeneratorWorker::FindActorTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories) +std::vector CMapGeneratorWorker::FindActorTemplates(const std::string& path, bool includeSubdirectories) { - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - return self->m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES); + return m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES); } bool CMapGeneratorWorker::LoadScripts(const VfsPath& libraryName) @@ -314,7 +312,7 @@ bool CMapGeneratorWorker::LoadScripts(const VfsPath& libraryName) return true; } -JS::Value CMapGeneratorWorker::LoadHeightmap(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& filename) +JS::Value CMapGeneratorWorker::LoadHeightmap(const VfsPath& filename) { std::vector heightmap; if (LoadHeightmapImageVfs(filename, heightmap) != INFO::OK) @@ -323,18 +321,16 @@ JS::Value CMapGeneratorWorker::LoadHeightmap(ScriptInterface::CmptPrivate* pCmpt return JS::UndefinedValue(); } - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - ScriptRequest rq(self->m_ScriptInterface); + ScriptRequest rq(m_ScriptInterface); JS::RootedValue returnValue(rq.cx); ToJSVal_vector(rq, &returnValue, heightmap); return returnValue; } // See CMapReader::UnpackTerrain, CMapReader::ParseTerrain for the reordering -JS::Value CMapGeneratorWorker::LoadMapTerrain(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& filename) +JS::Value CMapGeneratorWorker::LoadMapTerrain(const VfsPath& filename) { - CMapGeneratorWorker* self = static_cast(pCmptPrivate->pCBData); - ScriptRequest rq(self->m_ScriptInterface); + ScriptRequest rq(m_ScriptInterface); if (!VfsFileExists(filename)) { diff --git a/source/graphics/MapGenerator.h b/source/graphics/MapGenerator.h index 5e8243fa76..d99a25bc19 100644 --- a/source/graphics/MapGenerator.h +++ b/source/graphics/MapGenerator.h @@ -133,55 +133,50 @@ private: */ bool LoadScripts(const VfsPath& libraryName); - /** - * Recursively load all script files in the given folder. - */ - static bool LoadLibrary(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& name); - /** * Finalize map generation and pass results from the script to the engine. */ - static void ExportMap(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data); + void ExportMap(JS::HandleValue data); /** * Load an image file and return it as a height array. */ - static JS::Value LoadHeightmap(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& src); + JS::Value LoadHeightmap(const VfsPath& src); /** * Load an Atlas terrain file (PMP) returning textures and heightmap. */ - static JS::Value LoadMapTerrain(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& filename); + JS::Value LoadMapTerrain(const VfsPath& filename); /** * Sets the map generation progress, which is one of multiple stages determining the loading screen progress. */ - static void SetProgress(ScriptInterface::CmptPrivate* pCmptPrivate, int progress); + void SetProgress(int progress); /** * Microseconds since the epoch. */ - static double GetMicroseconds(ScriptInterface::CmptPrivate* pCmptPrivate); + double GetMicroseconds(); /** * Return the template data of the given template name. */ - static CParamNode GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName); + CParamNode GetTemplate(const std::string& templateName); /** * Check whether the given template exists. */ - static bool TemplateExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName); + bool TemplateExists(const std::string& templateName); /** * Returns all template names of simulation entity templates. */ - static std::vector FindTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories); + std::vector FindTemplates(const std::string& path, bool includeSubdirectories); /** * Returns all template names of actors. */ - static std::vector FindActorTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories); + std::vector FindActorTemplates(const std::string& path, bool includeSubdirectories); /** * Perform map generation in an independent thread. diff --git a/source/graphics/scripting/JSInterface_GameView.cpp b/source/graphics/scripting/JSInterface_GameView.cpp index 1337acce48..1d08b6921f 100644 --- a/source/graphics/scripting/JSInterface_GameView.cpp +++ b/source/graphics/scripting/JSInterface_GameView.cpp @@ -22,13 +22,18 @@ #include "graphics/Camera.h" #include "graphics/GameView.h" #include "graphics/Terrain.h" +#include "maths/FixedVector3D.h" #include "ps/Game.h" #include "ps/World.h" #include "ps/CLogger.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" +#include "simulation2/helpers/Position.h" +namespace JSI_GameView +{ #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \ -bool JSI_GameView::Get##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) \ +bool Get##NAME##Enabled() \ { \ if (!g_Game || !g_Game->GetView()) \ { \ @@ -38,7 +43,7 @@ bool JSI_GameView::Get##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmpt return g_Game->GetView()->Get##NAME##Enabled(); \ } \ \ -void JSI_GameView::Set##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool Enabled) \ +void Set##NAME##Enabled(bool Enabled) \ { \ if (!g_Game || !g_Game->GetView()) \ { \ @@ -56,10 +61,10 @@ IMPLEMENT_BOOLEAN_SCRIPT_SETTING(ConstrainCamera); #define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \ -scriptInterface.RegisterFunction("GameView_Get" #NAME "Enabled"); \ -scriptInterface.RegisterFunction("GameView_Set" #NAME "Enabled"); + ScriptFunction::Register<&Get##NAME##Enabled>(rq, "GameView_Get" #NAME "Enabled"); \ + ScriptFunction::Register<&Set##NAME##Enabled>(rq, "GameView_Set" #NAME "Enabled"); -void JSI_GameView::RegisterScriptFunctions_Settings(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions_Settings(const ScriptRequest& rq) { REGISTER_BOOLEAN_SCRIPT_SETTING(Culling); REGISTER_BOOLEAN_SCRIPT_SETTING(LockCullCamera); @@ -68,9 +73,8 @@ void JSI_GameView::RegisterScriptFunctions_Settings(const ScriptInterface& scrip #undef REGISTER_BOOLEAN_SCRIPT_SETTING -JS::Value JSI_GameView::GetCameraPivot(ScriptInterface::CmptPrivate* pCmptPrivate) +JS::Value GetCameraPivot(const ScriptRequest& rq) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); CVector3D pivot(-1, -1, -1); if (g_Game && g_Game->GetView()) pivot = g_Game->GetView()->GetCameraPivot(); @@ -83,7 +87,7 @@ JS::Value JSI_GameView::GetCameraPivot(ScriptInterface::CmptPrivate* pCmptPrivat /** * Move camera to a 2D location. */ -void JSI_GameView::CameraMoveTo(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_pos_t x, entity_pos_t z) +void CameraMoveTo(entity_pos_t x, entity_pos_t z) { if (!g_Game || !g_Game->GetWorld() || !g_Game->GetView() || !g_Game->GetWorld()->GetTerrain()) return; @@ -101,7 +105,7 @@ void JSI_GameView::CameraMoveTo(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat /** * Set the camera to look at the given location. */ -void JSI_GameView::SetCameraTarget(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float x, float y, float z) +void SetCameraTarget(float x, float y, float z) { if (!g_Game || !g_Game->GetView()) return; @@ -111,7 +115,7 @@ void JSI_GameView::SetCameraTarget(ScriptInterface::CmptPrivate* UNUSED(pCmptPri /** * Set the data (position, orientation and zoom) of the camera. */ -void JSI_GameView::SetCameraData(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom) +void SetCameraData(entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom) { if (!g_Game || !g_Game->GetView()) return; @@ -125,7 +129,7 @@ void JSI_GameView::SetCameraData(ScriptInterface::CmptPrivate* UNUSED(pCmptPriva * Start / stop camera following mode. * @param entityid unit id to follow. If zero, stop following mode */ -void JSI_GameView::CameraFollow(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_id_t entityid) +void CameraFollow(entity_id_t entityid) { if (!g_Game || !g_Game->GetView()) return; @@ -137,7 +141,7 @@ void JSI_GameView::CameraFollow(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat * Start / stop first-person camera following mode. * @param entityid unit id to follow. If zero, stop following mode. */ -void JSI_GameView::CameraFollowFPS(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_id_t entityid) +void CameraFollowFPS(entity_id_t entityid) { if (!g_Game || !g_Game->GetView()) return; @@ -145,7 +149,7 @@ void JSI_GameView::CameraFollowFPS(ScriptInterface::CmptPrivate* UNUSED(pCmptPri g_Game->GetView()->FollowEntity(entityid, true); } -entity_id_t JSI_GameView::GetFollowedEntity(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +entity_id_t GetFollowedEntity() { if (!g_Game || !g_Game->GetView()) return INVALID_ENTITY; @@ -153,22 +157,23 @@ entity_id_t JSI_GameView::GetFollowedEntity(ScriptInterface::CmptPrivate* UNUSED return g_Game->GetView()->GetFollowedEntity(); } -CFixedVector3D JSI_GameView::GetTerrainAtScreenPoint(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int x, int y) +CFixedVector3D GetTerrainAtScreenPoint(int x, int y) { CVector3D pos = g_Game->GetView()->GetCamera()->GetWorldCoordinates(x, y, true); return CFixedVector3D(fixed::FromFloat(pos.X), fixed::FromFloat(pos.Y), fixed::FromFloat(pos.Z)); } -void JSI_GameView::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - RegisterScriptFunctions_Settings(scriptInterface); + RegisterScriptFunctions_Settings(rq); - scriptInterface.RegisterFunction("GetCameraPivot"); - scriptInterface.RegisterFunction("CameraMoveTo"); - scriptInterface.RegisterFunction("SetCameraTarget"); - scriptInterface.RegisterFunction("SetCameraData"); - scriptInterface.RegisterFunction("CameraFollow"); - scriptInterface.RegisterFunction("CameraFollowFPS"); - scriptInterface.RegisterFunction("GetFollowedEntity"); - scriptInterface.RegisterFunction("GetTerrainAtScreenPoint"); + ScriptFunction::Register<&GetCameraPivot>(rq, "GetCameraPivot"); + ScriptFunction::Register<&CameraMoveTo>(rq, "CameraMoveTo"); + ScriptFunction::Register<&SetCameraTarget>(rq, "SetCameraTarget"); + ScriptFunction::Register<&SetCameraData>(rq, "SetCameraData"); + ScriptFunction::Register<&CameraFollow>(rq, "CameraFollow"); + ScriptFunction::Register<&CameraFollowFPS>(rq, "CameraFollowFPS"); + ScriptFunction::Register<&GetFollowedEntity>(rq, "GetFollowedEntity"); + ScriptFunction::Register<&GetTerrainAtScreenPoint>(rq, "GetTerrainAtScreenPoint"); +} } diff --git a/source/graphics/scripting/JSInterface_GameView.h b/source/graphics/scripting/JSInterface_GameView.h index 135dbec15d..aba909de11 100644 --- a/source/graphics/scripting/JSInterface_GameView.h +++ b/source/graphics/scripting/JSInterface_GameView.h @@ -18,34 +18,11 @@ #ifndef INCLUDED_JSINTERFACE_GAMEVIEW #define INCLUDED_JSINTERFACE_GAMEVIEW -#include "maths/FixedVector3D.h" -#include "scriptinterface/ScriptInterface.h" -#include "simulation2/helpers/Position.h" -#include "simulation2/system/Entity.h" - -#define DECLARE_BOOLEAN_SCRIPT_SETTING(NAME) \ - bool Get##NAME##Enabled(ScriptInterface::CmptPrivate* pCmptPrivate); \ - void Set##NAME##Enabled(ScriptInterface::CmptPrivate* pCmptPrivate, bool Enabled); +class ScriptRequest; namespace JSI_GameView { - void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); - void RegisterScriptFunctions_Settings(const ScriptInterface& scriptInterface); - - DECLARE_BOOLEAN_SCRIPT_SETTING(Culling); - DECLARE_BOOLEAN_SCRIPT_SETTING(LockCullCamera); - DECLARE_BOOLEAN_SCRIPT_SETTING(ConstrainCamera); - - JS::Value GetCameraPivot(ScriptInterface::CmptPrivate* pCmptPrivate); - void CameraMoveTo(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t z); - void SetCameraTarget(ScriptInterface::CmptPrivate* pCmptPrivate, float x, float y, float z); - void SetCameraData(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom); - void CameraFollow(ScriptInterface::CmptPrivate* pCmptPrivate, entity_id_t entityid); - void CameraFollowFPS(ScriptInterface::CmptPrivate* pCmptPrivate, entity_id_t entityid); - entity_id_t GetFollowedEntity(ScriptInterface::CmptPrivate* pCmptPrivate); - CFixedVector3D GetTerrainAtScreenPoint(ScriptInterface::CmptPrivate* pCmptPrivate, int x, int y); + void RegisterScriptFunctions(const ScriptRequest& rq); } -#undef DECLARE_BOOLEAN_SCRIPT_SETTING - #endif // INCLUDED_JSINTERFACE_GAMEVIEW diff --git a/source/gui/Scripting/JSInterface_GUIManager.cpp b/source/gui/Scripting/JSInterface_GUIManager.cpp index 6055461a16..958f6a7051 100644 --- a/source/gui/Scripting/JSInterface_GUIManager.cpp +++ b/source/gui/Scripting/JSInterface_GUIManager.cpp @@ -23,21 +23,24 @@ #include "gui/GUIManager.h" #include "gui/ObjectBases/IGUIObject.h" #include "ps/GameSetup/Config.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" +namespace JSI_GUIManager +{ // Note that the initData argument may only contain clonable data. // Functions aren't supported for example! -void JSI_GUIManager::PushGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction) +void PushGuiPage(const ScriptInterface& scriptInterface, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction) { - g_GUI->PushPage(name, pCmptPrivate->pScriptInterface->WriteStructuredClone(initData), callbackFunction); + g_GUI->PushPage(name, scriptInterface.WriteStructuredClone(initData), callbackFunction); } -void JSI_GUIManager::SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData) +void SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData) { g_GUI->SwitchPage(name, pCmptPrivate->pScriptInterface, initData); } -void JSI_GUIManager::PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue args) +void PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue args) { if (g_GUI->GetPageCount() < 2) { @@ -49,61 +52,41 @@ void JSI_GUIManager::PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS:: g_GUI->PopPage(pCmptPrivate->pScriptInterface->WriteStructuredClone(args)); } -JS::Value JSI_GUIManager::GetGUIObjectByName(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name) -{ - CGUI* guiPage = static_cast(pCmptPrivate->pCBData); - - IGUIObject* guiObj = guiPage->FindObjectByName(name); - if (!guiObj) - return JS::UndefinedValue(); - - return JS::ObjectValue(*guiObj->GetJSObject()); -} - -void JSI_GUIManager::SetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName, JS::HandleValue function) -{ - CGUI* guiPage = static_cast(pCmptPrivate->pCBData); - guiPage->SetGlobalHotkey(hotkeyTag, eventName, function); -} - -void JSI_GUIManager::UnsetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName) -{ - CGUI* guiPage = static_cast(pCmptPrivate->pCBData); - guiPage->UnsetGlobalHotkey(hotkeyTag, eventName); -} - -std::wstring JSI_GUIManager::SetCursor(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name) +std::wstring SetCursor(const std::wstring& name) { std::wstring old = g_CursorName; g_CursorName = name; return old; } -void JSI_GUIManager::ResetCursor(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void ResetCursor() { g_CursorName = g_DefaultCursor; } -bool JSI_GUIManager::TemplateExists(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& templateName) +bool TemplateExists(const std::string& templateName) { return g_GUI->TemplateExists(templateName); } -CParamNode JSI_GUIManager::GetTemplate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& templateName) +CParamNode GetTemplate(const std::string& templateName) { return g_GUI->GetTemplate(templateName); } -void JSI_GUIManager::RegisterScriptFunctions(const ScriptInterface& scriptInterface) + +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("PushGuiPage"); - scriptInterface.RegisterFunction("SwitchGuiPage"); - scriptInterface.RegisterFunction("SetGlobalHotkey"); - scriptInterface.RegisterFunction("UnsetGlobalHotkey"); - scriptInterface.RegisterFunction("PopGuiPage"); - scriptInterface.RegisterFunction("GetGUIObjectByName"); - scriptInterface.RegisterFunction("SetCursor"); - scriptInterface.RegisterFunction("ResetCursor"); - scriptInterface.RegisterFunction("TemplateExists"); - scriptInterface.RegisterFunction("GetTemplate"); + ScriptFunction::Register<&PushGuiPage>(rq, "PushGuiPage"); + ScriptFunction::Register<&SwitchGuiPage>(rq, "SwitchGuiPage"); + ScriptFunction::Register<&PopGuiPage>(rq, "PopGuiPage"); + ScriptFunction::Register<&SetCursor>(rq, "SetCursor"); + ScriptFunction::Register<&ResetCursor>(rq, "ResetCursor"); + ScriptFunction::Register<&TemplateExists>(rq, "TemplateExists"); + ScriptFunction::Register<&GetTemplate>(rq, "GetTemplate"); + + ScriptFunction::Register<&CGUI::FindObjectByName, &ScriptFunction::ObjectFromCBData>(rq, "GetGUIObjectByName"); + ScriptFunction::Register<&CGUI::SetGlobalHotkey, &ScriptFunction::ObjectFromCBData>(rq, "SetGlobalHotkey"); + ScriptFunction::Register<&CGUI::UnsetGlobalHotkey, &ScriptFunction::ObjectFromCBData>(rq, "UnsetGlobalHotkey"); +} } diff --git a/source/gui/Scripting/JSInterface_GUIManager.h b/source/gui/Scripting/JSInterface_GUIManager.h index a88b929226..4dcb0051aa 100644 --- a/source/gui/Scripting/JSInterface_GUIManager.h +++ b/source/gui/Scripting/JSInterface_GUIManager.h @@ -18,23 +18,11 @@ #ifndef INCLUDED_JSI_GUIMANAGER #define INCLUDED_JSI_GUIMANAGER -#include "scriptinterface/ScriptInterface.h" -#include "simulation2/system/ParamNode.h" +class ScriptRequest; namespace JSI_GUIManager { - void PushGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction); - void SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData); - void PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue args); - JS::Value GetGUIObjectByName(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name); - void SetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName, JS::HandleValue function); - void UnsetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName); - std::wstring SetCursor(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name); - void ResetCursor(ScriptInterface::CmptPrivate* pCmptPrivate); - bool TemplateExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName); - CParamNode GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName); - - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_GUIMANAGER diff --git a/source/gui/Scripting/ScriptFunctions.cpp b/source/gui/Scripting/ScriptFunctions.cpp index 7c38be982a..cce9b409c1 100644 --- a/source/gui/Scripting/ScriptFunctions.cpp +++ b/source/gui/Scripting/ScriptFunctions.cpp @@ -53,24 +53,24 @@ void GuiScriptingInit(ScriptInterface& scriptInterface) ScriptRequest rq(scriptInterface); JSI_GUISize::RegisterScriptClass(scriptInterface); - JSI_ConfigDB::RegisterScriptFunctions(scriptInterface); + JSI_ConfigDB::RegisterScriptFunctions(rq); JSI_Console::RegisterScriptFunctions(rq); - JSI_Debug::RegisterScriptFunctions(scriptInterface); - JSI_GUIManager::RegisterScriptFunctions(scriptInterface); - JSI_Game::RegisterScriptFunctions(scriptInterface); - JSI_GameView::RegisterScriptFunctions(scriptInterface); - JSI_Hotkey::RegisterScriptFunctions(scriptInterface); - JSI_L10n::RegisterScriptFunctions(scriptInterface); - JSI_Lobby::RegisterScriptFunctions(scriptInterface); - JSI_Main::RegisterScriptFunctions(scriptInterface); - JSI_Mod::RegisterScriptFunctions(scriptInterface); - JSI_ModIo::RegisterScriptFunctions(scriptInterface); - JSI_Network::RegisterScriptFunctions(scriptInterface); - JSI_Renderer::RegisterScriptFunctions(scriptInterface); - JSI_SavedGame::RegisterScriptFunctions(scriptInterface); - JSI_Simulation::RegisterScriptFunctions(scriptInterface); - JSI_Sound::RegisterScriptFunctions(scriptInterface); - JSI_UserReport::RegisterScriptFunctions(scriptInterface); - JSI_VFS::RegisterScriptFunctions_GUI(scriptInterface); - JSI_VisualReplay::RegisterScriptFunctions(scriptInterface); + JSI_Debug::RegisterScriptFunctions(rq); + JSI_GUIManager::RegisterScriptFunctions(rq); + JSI_Game::RegisterScriptFunctions(rq); + JSI_GameView::RegisterScriptFunctions(rq); + JSI_Hotkey::RegisterScriptFunctions(rq); + JSI_L10n::RegisterScriptFunctions(rq); + JSI_Lobby::RegisterScriptFunctions(rq); + JSI_Main::RegisterScriptFunctions(rq); + JSI_Mod::RegisterScriptFunctions(rq); + JSI_ModIo::RegisterScriptFunctions(rq); + JSI_Network::RegisterScriptFunctions(rq); + JSI_Renderer::RegisterScriptFunctions(rq); + JSI_SavedGame::RegisterScriptFunctions(rq); + JSI_Simulation::RegisterScriptFunctions(rq); + JSI_Sound::RegisterScriptFunctions(rq); + JSI_UserReport::RegisterScriptFunctions(rq); + JSI_VFS::RegisterScriptFunctions_GUI(rq); + JSI_VisualReplay::RegisterScriptFunctions(rq); } diff --git a/source/i18n/scripting/JSInterface_L10n.cpp b/source/i18n/scripting/JSInterface_L10n.cpp index af25d65946..79e0c5d2e8 100644 --- a/source/i18n/scripting/JSInterface_L10n.cpp +++ b/source/i18n/scripting/JSInterface_L10n.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 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 @@ -21,169 +21,81 @@ #include "i18n/L10n.h" #include "lib/utf8.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" -// Returns a translation of the specified English string into the current language. -std::wstring JSI_L10n::Translate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString) +namespace JSI_L10n { - return wstring_from_utf8(g_L10n.Translate(utf8_from_wstring(sourceString))); +L10n* L10nGetter(const ScriptRequest&, JS::CallArgs&) +{ + if (!g_L10n.IsInitialised()) + { + LOGERROR("Trying to access g_L10n when it's not initialized!"); + return nullptr; + } + return &g_L10n.GetSingleton(); } -// Returns a translation of the specified English string, for the specified context. -std::wstring JSI_L10n::TranslateWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& sourceString) +std::vector TranslateArray(const std::vector& sourceArray) { - return wstring_from_utf8(g_L10n.TranslateWithContext(context, utf8_from_wstring(sourceString))); -} - -// Return a translated version of the given strings (singular and plural) depending on an integer value. -std::wstring JSI_L10n::TranslatePlural(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number) -{ - return wstring_from_utf8(g_L10n.TranslatePlural(utf8_from_wstring(singularSourceString), utf8_from_wstring(pluralSourceString), number)); -} - -// Return a translated version of the given strings (singular and plural) depending on an integer value, for the specified context. -std::wstring JSI_L10n::TranslatePluralWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number) -{ - return wstring_from_utf8(g_L10n.TranslatePluralWithContext(context, utf8_from_wstring(singularSourceString), utf8_from_wstring(pluralSourceString), number)); -} - -// Return a translated version of the given string, localizing it line by line. -std::wstring JSI_L10n::TranslateLines(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString) -{ - return wstring_from_utf8(g_L10n.TranslateLines(utf8_from_wstring(sourceString))); -} - -// Return a translated version of the items in the specified array. -std::vector JSI_L10n::TranslateArray(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::vector& sourceArray) -{ - std::vector translatedArray; - for (const std::wstring& elem : sourceArray) - translatedArray.push_back(wstring_from_utf8(g_L10n.Translate(utf8_from_wstring(elem)))); + std::vector translatedArray; + if (g_L10n.IsInitialised()) + for (const std::string& elem : sourceArray) + translatedArray.push_back(g_L10n.Translate(elem)); return translatedArray; } -std::wstring JSI_L10n::GetFallbackToAvailableDictLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.GetFallbackToAvailableDictLocale(locale); -} - // Return a localized version of a time given in milliseconds. -std::wstring JSI_L10n::FormatMillisecondsIntoDateStringLocal(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString) +std::string FormatMillisecondsIntoDateStringLocal(UDate milliseconds, const std::string& formatString) { - return wstring_from_utf8(g_L10n.FormatMillisecondsIntoDateString(milliseconds, utf8_from_wstring(formatString), true)); + return g_L10n.FormatMillisecondsIntoDateString(milliseconds, formatString, true); } // Return a localized version of a duration or a time in GMT given in milliseconds. -std::wstring JSI_L10n::FormatMillisecondsIntoDateStringGMT(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString) +std::string FormatMillisecondsIntoDateStringGMT(UDate milliseconds, const std::string& formatString) { - return wstring_from_utf8(g_L10n.FormatMillisecondsIntoDateString(milliseconds, utf8_from_wstring(formatString), false)); + return g_L10n.FormatMillisecondsIntoDateString(milliseconds, formatString, false); } -// Return a localized version of the given decimal number. -std::wstring JSI_L10n::FormatDecimalNumberIntoString(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), double number) +void RegisterScriptFunctions(const ScriptRequest& rq) { - return wstring_from_utf8(g_L10n.FormatDecimalNumberIntoString(number)); +#define REGISTER_L10N(name) \ + ScriptFunction::Register<&L10n::name, &L10nGetter>(rq, #name); +#define REGISTER_L10N_FUNC(func, name) \ + ScriptFunction::Register(rq, name); + + REGISTER_L10N(Translate) + REGISTER_L10N(TranslateWithContext) + REGISTER_L10N(TranslatePlural) + REGISTER_L10N(TranslatePluralWithContext) + REGISTER_L10N(TranslateLines) + ScriptFunction::Register<&TranslateArray>(rq, "TranslateArray"); + ScriptFunction::Register<&FormatMillisecondsIntoDateStringLocal>(rq, "FormatMillisecondsIntoDateStringLocal"); + ScriptFunction::Register<&FormatMillisecondsIntoDateStringGMT>(rq, "FormatMillisecondsIntoDateStringGMT"); + REGISTER_L10N(FormatDecimalNumberIntoString) + + REGISTER_L10N(GetSupportedLocaleBaseNames) + REGISTER_L10N(GetSupportedLocaleDisplayNames) + REGISTER_L10N_FUNC(&L10n::GetCurrentLocaleString, "GetCurrentLocale"); + REGISTER_L10N(GetAllLocales) + // Select the appropriate overload. + REGISTER_L10N_FUNC(static_cast(&L10n::GetDictionaryLocale), "GetDictionaryLocale"); + REGISTER_L10N(GetDictionariesForLocale) + + REGISTER_L10N(UseLongStrings) + REGISTER_L10N(GetLocaleLanguage) + REGISTER_L10N(GetLocaleBaseName) + REGISTER_L10N(GetLocaleCountry) + REGISTER_L10N(GetLocaleScript) + // Select the appropriate overload. + REGISTER_L10N_FUNC(static_cast(&L10n::GetFallbackToAvailableDictLocale), "GetFallbackToAvailableDictLocale"); + + // Select the appropriate overloads. + REGISTER_L10N_FUNC(static_cast(&L10n::ValidateLocale), "ValidateLocale"); + REGISTER_L10N_FUNC(static_cast(&L10n::SaveLocale), "SaveLocale"); + REGISTER_L10N(ReevaluateCurrentLocaleAndReload) +#undef REGISTER_L10N +#undef REGISTER_L10N_FUNC } - -std::vector JSI_L10n::GetSupportedLocaleBaseNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - return g_L10n.GetSupportedLocaleBaseNames(); -} - -std::vector JSI_L10n::GetSupportedLocaleDisplayNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - return g_L10n.GetSupportedLocaleDisplayNames(); -} - -std::string JSI_L10n::GetCurrentLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - return g_L10n.GetCurrentLocaleString(); -} - -bool JSI_L10n::UseLongStrings(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - return g_L10n.UseLongStrings(); -} - -std::vector JSI_L10n::GetAllLocales(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - return g_L10n.GetAllLocales(); -} - -std::string JSI_L10n::GetDictionaryLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& configLocale) -{ - return g_L10n.GetDictionaryLocale(configLocale); -} - -std::vector JSI_L10n::GetDictionariesForLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.GetDictionariesForLocale(locale); -} - -std::string JSI_L10n::GetLocaleLanguage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.GetLocaleLanguage(locale); -} - -std::string JSI_L10n::GetLocaleBaseName(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.GetLocaleBaseName(locale); -} - -std::string JSI_L10n::GetLocaleCountry(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.GetLocaleCountry(locale); -} - -std::string JSI_L10n::GetLocaleScript(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.GetLocaleScript(locale); -} - -bool JSI_L10n::ValidateLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.ValidateLocale(locale); -} - -bool JSI_L10n::SaveLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale) -{ - return g_L10n.SaveLocale(locale); -} - -void JSI_L10n::ReevaluateCurrentLocaleAndReload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - g_L10n.ReevaluateCurrentLocaleAndReload(); -} - - -void JSI_L10n::RegisterScriptFunctions(const ScriptInterface& scriptInterface) -{ - scriptInterface.RegisterFunction("Translate"); - scriptInterface.RegisterFunction("TranslateWithContext"); - scriptInterface.RegisterFunction("TranslatePlural"); - scriptInterface.RegisterFunction("TranslatePluralWithContext"); - scriptInterface.RegisterFunction("TranslateLines"); - scriptInterface.RegisterFunction, std::vector, &TranslateArray>("TranslateArray"); - scriptInterface.RegisterFunction("FormatMillisecondsIntoDateStringLocal"); - scriptInterface.RegisterFunction("FormatMillisecondsIntoDateStringGMT"); - scriptInterface.RegisterFunction("FormatDecimalNumberIntoString"); - - scriptInterface.RegisterFunction, &GetSupportedLocaleBaseNames>("GetSupportedLocaleBaseNames"); - scriptInterface.RegisterFunction, &GetSupportedLocaleDisplayNames>("GetSupportedLocaleDisplayNames"); - scriptInterface.RegisterFunction("GetCurrentLocale"); - scriptInterface.RegisterFunction, &GetAllLocales>("GetAllLocales"); - scriptInterface.RegisterFunction("GetDictionaryLocale"); - scriptInterface.RegisterFunction, std::string, &GetDictionariesForLocale>("GetDictionariesForLocale"); - - scriptInterface.RegisterFunction("UseLongStrings"); - scriptInterface.RegisterFunction("GetLocaleLanguage"); - scriptInterface.RegisterFunction("GetLocaleBaseName"); - scriptInterface.RegisterFunction("GetLocaleCountry"); - scriptInterface.RegisterFunction("GetLocaleScript"); - scriptInterface.RegisterFunction("GetFallbackToAvailableDictLocale"); - - scriptInterface.RegisterFunction("ValidateLocale"); - scriptInterface.RegisterFunction("SaveLocale"); - scriptInterface.RegisterFunction("ReevaluateCurrentLocaleAndReload"); } diff --git a/source/i18n/scripting/JSInterface_L10n.h b/source/i18n/scripting/JSInterface_L10n.h index 484e35c041..e26860bf38 100644 --- a/source/i18n/scripting/JSInterface_L10n.h +++ b/source/i18n/scripting/JSInterface_L10n.h @@ -18,8 +18,7 @@ #ifndef INCLUDED_JSINTERFACE_L10N #define INCLUDED_JSINTERFACE_L10N -#include "lib/external_libraries/icu.h" -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; /** * Namespace for the functions of the JavaScript interface for @@ -37,419 +36,12 @@ namespace JSI_L10n * internationalization and localization into the specified JavaScript * context. * - * @param ScriptInterface JavaScript context where RegisterScriptFunctions() + * @param ScriptRequest Script Request where RegisterScriptFunctions() * registers the functions. * * @sa GuiScriptingInit() */ - void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); - - /** - * Returns the translation of the specified string to the - * @link L10n::GetCurrentLocale() current locale@endlink. - * - * This is a JavaScript interface to L10n::Translate(). - * - * @param pCmptPrivate JavaScript context. - * @param sourceString String to translate to the current locale. - * @return Translation of @p sourceString to the current locale, or - * @p sourceString if there is no translation available. - */ - std::wstring Translate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString); - - /** - * Returns the translation of the specified string to the - * @link L10n::GetCurrentLocale() current locale@endlink in the specified - * context. - * - * This is a JavaScript interface to L10n::TranslateWithContext(). - * - * @param pCmptPrivate JavaScript context. - * @param context Context where the string is used. See - * http://www.gnu.org/software/gettext/manual/html_node/Contexts.html - * @param sourceString String to translate to the current locale. - * @return Translation of @p sourceString to the current locale in the - * specified @p context, or @p sourceString if there is no - * translation available. - */ - std::wstring TranslateWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& sourceString); - - /** - * Returns the translation of the specified string to the - * @link L10n::GetCurrentLocale() current locale@endlink based on the - * specified number. - * - * This is a JavaScript interface to L10n::TranslatePlural(). - * - * @param pCmptPrivate JavaScript context. - * @param singularSourceString String to translate to the current locale, - * in English' singular form. - * @param pluralSourceString String to translate to the current locale, in - * English' plural form. - * @param number Number that determines the required form of the translation - * (or the English string if no translation is available). - * @return Translation of the source string to the current locale for the - * specified @p number, or either @p singularSourceString (if - * @p number is 1) or @p pluralSourceString (if @p number is not 1) - * if there is no translation available. - */ - std::wstring TranslatePlural(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number); - - /** - * Returns the translation of the specified string to the - * @link L10n::GetCurrentLocale() current locale@endlink in the specified - * context, based on the specified number. - * - * This is a JavaScript interface to L10n::TranslatePluralWithContext(). - * - * @param pCmptPrivate JavaScript context. - * @param context Context where the string is used. See - * http://www.gnu.org/software/gettext/manual/html_node/Contexts.html - * @param singularSourceString String to translate to the current locale, - * in English' singular form. - * @param pluralSourceString String to translate to the current locale, in - * English' plural form. - * @param number Number that determines the required form of the translation - * (or the English string if no translation is available). * - * @return Translation of the source string to the current locale in the - * specified @p context and for the specified @p number, or either - * @p singularSourceString (if @p number is 1) or - * @p pluralSourceString (if @p number is not 1) if there is no - * translation available. - */ - std::wstring TranslatePluralWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number); - - /** - * Translates a text line by line to the - * @link L10n::GetCurrentLocale() current locale@endlink. - * - * TranslateLines() is helpful when you need to translate a plain text file - * after you load it. - * - * This is a JavaScript interface to L10n::TranslateLines(). - * - * @param pCmptPrivate JavaScript context. - * @param sourceString Text to translate to the current locale. - * @return Line by line translation of @p sourceString to the current - * locale. Some of the lines in the returned text may be in English - * because there was not translation available for them. - */ - std::wstring TranslateLines(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString); - - /** - * Translate each of the strings of a JavaScript array to the - * @link L10n::GetCurrentLocale() current locale@endlink. - * - * This is a helper function that loops through the items of the input array - * and calls L10n::Translate() on each of them. - * - * @param pCmptPrivate JavaScript context. - * @param sourceArray JavaScript array of strings to translate to the - * current locale. - * @return Item by item translation of @p sourceArray to the current locale. - * Some of the items in the returned array may be in English because - * there was not translation available for them. - */ - std::vector TranslateArray(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::vector& sourceArray); - - /** - * Returns the specified date converted to the local timezone using the specified date format. - * - * This is a JavaScript interface to - * L10n::FormatMillisecondsIntoDateString(). - * - * @param pCmptPrivate JavaScript context. - * @param milliseconds Date specified as a UNIX timestamp in milliseconds - * (not seconds). If you have a JavaScript @c Date object, you can - * use @c Date.getTime() to obtain the UNIX time in milliseconds. - * @param formatString Date format string defined using ICU date formatting - * symbols. Usually, you internationalize the format string and - * get it translated before you pass it to - * FormatMillisecondsIntoDateString(). - * @return String containing the specified date with the specified date - * format. - * - * @sa http://en.wikipedia.org/wiki/Unix_time - * @sa https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table - */ - std::wstring FormatMillisecondsIntoDateStringLocal(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString); - - /** - * Returns the specified date in GMT using the specified date format. - * - * This is a JavaScript interface to - * L10n::FormatMillisecondsIntoDateString(). - * - * @param pCmptPrivate JavaScript context. - * @param milliseconds Date specified as a UNIX timestamp in milliseconds - * (not seconds). If you have a JavaScript @c Date object, you can - * use @c Date.getTime() to obtain the UNIX time in milliseconds. - * @param formatString Date format string defined using ICU date formatting - * symbols. Usually, you internationalize the format string and - * get it translated before you pass it to - * FormatMillisecondsIntoDateString(). - * @return String containing the specified date with the specified date - * format. - * - * @sa http://en.wikipedia.org/wiki/Unix_time - * @sa https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table - */ - std::wstring FormatMillisecondsIntoDateStringGMT(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString); - - /** - * Returns the specified floating-point number as a string, with the number - * formatted as a decimal number using the - * @link L10n::GetCurrentLocale() current locale@endlink. - * - * This is a JavaScript interface to L10n::FormatDecimalNumberIntoString(). - * - * @param pCmptPrivate JavaScript context. - * @param number Number to format. - * @return Decimal number formatted using the current locale. - */ - std::wstring FormatDecimalNumberIntoString(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), double number); - - /** - * Returns an array of supported locale codes sorted alphabetically. - * - * A locale code is a string such as "de" or "pt_BR". - * - * If yours is a development copy (the 'config/dev.cfg' file is found in the - * virtual filesystem), the output array may include the special "long" - * locale code. - * - * This is a JavaScript interface to L10n::GetSupportedLocaleBaseNames(). - * - * @param pCmptPrivate JavaScript context. - * @return Array of supported locale codes. - * - * @sa GetSupportedLocaleDisplayNames() - * @sa GetAllLocales() - * @sa GetCurrentLocale() - * - * @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale - */ - std::vector GetSupportedLocaleBaseNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - - /** - * Returns an array of supported locale names sorted alphabetically by - * locale code. - * - * A locale code is a string such as "de" or "pt_BR". - * - * If yours is a development copy (the 'config/dev.cfg' file is found in the - * virtual filesystem), the output array may include the special "Long - * Strings" locale name. - * - * This is a JavaScript interface to L10n::GetSupportedLocaleDisplayNames(). - * - * @param pCmptPrivate JavaScript context. - * @return Array of supported locale codes. - * - * @sa GetSupportedLocaleBaseNames() - * - * @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale - */ - std::vector GetSupportedLocaleDisplayNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - - /** - * Returns the code of the current locale. - * - * A locale code is a string such as "de" or "pt_BR". - * - * This is a JavaScript interface to L10n::GetCurrentLocaleString(). - * - * @param pCmptPrivate JavaScript context. - * - * @sa GetSupportedLocaleBaseNames() - * @sa GetAllLocales() - * @sa ReevaluateCurrentLocaleAndReload() - */ - std::string GetCurrentLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - - /** - * Returns an array of locale codes supported by ICU. - * - * A locale code is a string such as "de" or "pt_BR". - * - * This is a JavaScript interface to L10n::GetAllLocales(). - * - * @param pCmptPrivate JavaScript context. - * @return Array of supported locale codes. - * - * @sa GetSupportedLocaleBaseNames() - * @sa GetCurrentLocale() - * - * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a073d70df8c9c8d119c0d42d70de24137 - */ - std::vector GetAllLocales(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - - /** - * Returns the code of the recommended locale for the current user that the - * game supports. - * - * "That the game supports" means both that a translation file is available - * for that locale and that the locale code is either supported by ICU or - * the special "long" locale code. - * - * The mechanism to select a recommended locale follows this logic: - * 1. First see if the game supports the specified locale,\n - * @p configLocale. - * 2. Otherwise, check the system locale and see if the game supports\n - * that locale. - * 3. Else, return the default locale, 'en_US'. - * - * This is a JavaScript interface to L10n::GetDictionaryLocale(std::string). - * - * @param pCmptPrivate JavaScript context. - * @param configLocale Locale to check for support first. Pass an empty - * string to check the system locale directly. - * @return Code of a locale that the game supports. - * - * @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale - */ - std::string GetDictionaryLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& configLocale); - - /** - * Returns an array of paths to files in the virtual filesystem that provide - * translations for the specified locale code. - * - * This is a JavaScript interface to L10n::GetDictionariesForLocale(). - * - * @param pCmptPrivate JavaScript context. - * @param locale Locale code. - * @return Array of paths to files in the virtual filesystem that provide - * translations for @p locale. - */ - std::vector GetDictionariesForLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - /** - * Returns the ISO-639 language code of the specified locale code. - * - * For example, if you specify the 'en_US' locate, it returns 'en'. - * - * This is a JavaScript interface to L10n::GetLocaleLanguage(). - * - * @param pCmptPrivate JavaScript context. - * @param locale Locale code. - * @return Language code. - * - * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#af36d821adced72a870d921ebadd0ca93 - */ - std::string GetLocaleLanguage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - /** - * Returns the programmatic code of the entire locale without keywords. - * - * This is a JavaScript interface to L10n::GetLocaleBaseName(). - * - * @param pCmptPrivate JavaScript context. - * @param locale Locale code. - * @return Locale code without keywords. - * - * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a4c1acbbdf95dc15599db5f322fa4c4d0 - */ - std::string GetLocaleBaseName(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - /** - * Returns the ISO-3166 country code of the specified locale code. - * - * For example, if you specify the 'en_US' locate, it returns 'US'. - * - * This is a JavaScript interface to L10n::GetLocaleCountry(). - * - * @param pCmptPrivate JavaScript context. - * @param locale Locale code. - * @return Country code. - * - * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#ae3f1fc415c00d4f0ab33288ceadccbf9 - */ - std::string GetLocaleCountry(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - /** - * Returns the ISO-15924 abbreviation script code of the specified locale code. - * - * This is a JavaScript interface to L10n::GetLocaleScript(). - * - * @param pCmptPrivate JavaScript context. - * @param locale Locale code. - * @return Script code. - * - * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a5e0145a339d30794178a1412dcc55abe - */ - std::string GetLocaleScript(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - - std::wstring GetFallbackToAvailableDictLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - /** - * Returns @c true if the current locale is the special "Long Strings" - * locale. It returns @c false otherwise. - * - * This is a JavaScript interface to L10n::UseLongStrings(). - * - * @param pCmptPrivate JavaScript context. * - * @return Whether the current locale is the special "Long Strings" - * (@c true) or not (@c false). - */ - bool UseLongStrings(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - - /** - * Returns @c true if the locale is supported by both ICU and the game. It - * returns @c false otherwise. - * - * It returns @c true if both of these conditions are true: - * 1. ICU has resources for that locale (which also ensures it's a valid\n - * locale string). - * 2. Either a dictionary for language_country or for language is\n - * available. - * - * This is a JavaScript interface to L10n::ValidateLocale(const std::string&). - * - * @param pCmptPrivate JavaScript context. - * @param locale Locale to check. - * @return Whether @p locale is supported by both ICU and the game (@c true) - * or not (@c false). - */ - bool ValidateLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - /** - * Saves the specified locale in the game configuration file. - * - * The next time that the game starts, the game uses the locale in the - * configuration file if there are translation files available for it. - * - * SaveLocale() checks the validity of the specified locale with - * ValidateLocale(). If the specified locale is not valid, SaveLocale() - * returns @c false and does not save the locale to the configuration file. - * - * This is a JavaScript interface to L10n::SaveLocale(). - * - * @param pCmptPrivate JavaScript context. - * @param locale Locale to save to the configuration file. - * @return Whether the specified locale is valid (@c true) or not - * (@c false). - */ - bool SaveLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale); - - /** - * Determines the best, supported locale for the current user, makes it the - * current game locale and reloads the translations dictionary with - * translations for that locale. - * - * To determine the best locale, ReevaluateCurrentLocaleAndReload(): - * 1. Checks the user game configuration. - * 2. If the locale is not defined there, it checks the system locale. - * 3. If none of those locales are supported by the game, the default\n - * locale, 'en_US', is used. - * - * This is a JavaScript interface to L10n::ReevaluateCurrentLocaleAndReload(). - * - * @param pCmptPrivate JavaScript context. - * - * @sa GetCurrentLocale() - */ - void ReevaluateCurrentLocaleAndReload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSINTERFACE_L10N diff --git a/source/lobby/IXmppClient.h b/source/lobby/IXmppClient.h index b17cce624b..365e90b5fa 100644 --- a/source/lobby/IXmppClient.h +++ b/source/lobby/IXmppClient.h @@ -44,7 +44,7 @@ public: virtual void SendIqChangeStateGame(const std::string& nbp, const std::string& players) = 0; virtual void SendIqLobbyAuth(const std::string& to, const std::string& token) = 0; virtual void SetNick(const std::string& nick) = 0; - virtual void GetNick(std::string& nick) = 0; + virtual std::string GetNick() = 0; virtual void kick(const std::string& nick, const std::string& reason) = 0; virtual void ban(const std::string& nick, const std::string& reason) = 0; virtual void SetPresence(const std::string& presence) = 0; @@ -52,10 +52,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 void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; - virtual void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; - virtual void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; - virtual void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 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 GuiPollNewMessages(const ScriptInterface& scriptInterface) = 0; virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface) = 0; diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index 6f081ace8a..2560be5eaf 100644 --- a/source/lobby/XmppClient.cpp +++ b/source/lobby/XmppClient.cpp @@ -559,11 +559,12 @@ void XmppClient::handleOOB(const glooxwrapper::JID&, const glooxwrapper::OOB&) * * @return A JS array containing all known players and their presences */ -void XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) +JS::Value XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface) { ScriptRequest rq(scriptInterface); - ScriptInterface::CreateArray(rq, ret); + JS::RootedValue ret(rq.cx); + ScriptInterface::CreateArray(rq, &ret); int j = 0; for (const std::pair& p : m_PlayerMap) @@ -580,6 +581,7 @@ void XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::Mu scriptInterface.SetPropertyInt(ret, j++, player); } + return ret; } /** @@ -587,11 +589,12 @@ void XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::Mu * * @return A JS array containing all known games */ -void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) +JS::Value XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface) { ScriptRequest rq(scriptInterface); - ScriptInterface::CreateArray(rq, ret); + JS::RootedValue ret(rq.cx); + ScriptInterface::CreateArray(rq, &ret); int j = 0; const char* stats[] = { "name", "hostUsername", "state", "hasPassword", @@ -608,6 +611,7 @@ void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::Muta scriptInterface.SetPropertyInt(ret, j++, game); } + return ret; } /** @@ -615,11 +619,12 @@ void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::Muta * * @return A JS array containing all known leaderboard data */ -void XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) +JS::Value XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface) { ScriptRequest rq(scriptInterface); - ScriptInterface::CreateArray(rq, ret); + JS::RootedValue ret(rq.cx); + ScriptInterface::CreateArray(rq, &ret); int j = 0; const char* attributes[] = { "name", "rank", "rating" }; @@ -634,6 +639,7 @@ void XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface, JS::Mut scriptInterface.SetPropertyInt(ret, j++, board); } + return ret; } /** @@ -641,11 +647,12 @@ void XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface, JS::Mut * * @return A JS array containing the specific user's profile data */ -void XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) +JS::Value XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface) { ScriptRequest rq(scriptInterface); - ScriptInterface::CreateArray(rq, ret); + JS::RootedValue ret(rq.cx); + ScriptInterface::CreateArray(rq, &ret); int j = 0; const char* stats[] = { "player", "rating", "totalGamesPlayed", "highestRating", "wins", "losses", "rank" }; @@ -660,6 +667,7 @@ void XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface, JS::Mutab scriptInterface.SetPropertyInt(ret, j++, profile); } + return ret; } /***************************************************** @@ -1157,12 +1165,10 @@ void XmppClient::SetNick(const std::string& nick) /** * Get current nickname. - * - * @param nick Variable to store the nickname in. */ -void XmppClient::GetNick(std::string& nick) +std::string XmppClient::GetNick() { - nick = m_mucRoom->nick().to_string(); + return m_mucRoom->nick().to_string(); } /** diff --git a/source/lobby/XmppClient.h b/source/lobby/XmppClient.h index 6af6ce173b..28888fa152 100644 --- a/source/lobby/XmppClient.h +++ b/source/lobby/XmppClient.h @@ -91,7 +91,7 @@ public: void SendIqChangeStateGame(const std::string& nbp, const std::string& players); void SendIqLobbyAuth(const std::string& to, const std::string& token); void SetNick(const std::string& nick); - void GetNick(std::string& nick); + std::string GetNick(); void kick(const std::string& nick, const std::string& reason); void ban(const std::string& nick, const std::string& reason); void SetPresence(const std::string& presence); @@ -100,10 +100,10 @@ public: std::wstring GetRating(const std::string& nickname); const std::wstring& GetSubject(); - void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); - void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); - void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); - void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); + JS::Value GUIGetPlayerList(const ScriptInterface& scriptInterface); + JS::Value GUIGetGameList(const ScriptInterface& scriptInterface); + JS::Value GUIGetBoardList(const ScriptInterface& scriptInterface); + JS::Value GUIGetProfile(const ScriptInterface& scriptInterface); void SendStunEndpointToHost(const StunClient::StunEndpoint& stunEndpoint, const std::string& hostJID); diff --git a/source/lobby/scripting/JSInterface_Lobby.cpp b/source/lobby/scripting/JSInterface_Lobby.cpp index 3727773aec..ddce4acfb0 100644 --- a/source/lobby/scripting/JSInterface_Lobby.cpp +++ b/source/lobby/scripting/JSInterface_Lobby.cpp @@ -26,68 +26,31 @@ #include "ps/CLogger.h" #include "ps/CStr.h" #include "ps/Util.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "third_party/encryption/pkcs5_pbkdf2.h" #include -void JSI_Lobby::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +namespace JSI_Lobby { - // Lobby functions - scriptInterface.RegisterFunction("HasXmppClient"); - scriptInterface.RegisterFunction("SetRankedGame"); -#if CONFIG2_LOBBY // Allow the lobby to be disabled - scriptInterface.RegisterFunction("StartXmppClient"); - scriptInterface.RegisterFunction("StartRegisterXmppClient"); - scriptInterface.RegisterFunction("StopXmppClient"); - scriptInterface.RegisterFunction("ConnectXmppClient"); - scriptInterface.RegisterFunction("DisconnectXmppClient"); - scriptInterface.RegisterFunction("IsXmppClientConnected"); - scriptInterface.RegisterFunction("SendGetBoardList"); - scriptInterface.RegisterFunction("SendGetProfile"); - scriptInterface.RegisterFunction("SendRegisterGame"); - scriptInterface.RegisterFunction("SendGameReport"); - scriptInterface.RegisterFunction("SendUnregisterGame"); - scriptInterface.RegisterFunction("SendChangeStateGame"); - scriptInterface.RegisterFunction("GetPlayerList"); - scriptInterface.RegisterFunction("GetGameList"); - scriptInterface.RegisterFunction("GetBoardList"); - scriptInterface.RegisterFunction("GetProfile"); - scriptInterface.RegisterFunction("LobbyGuiPollNewMessages"); - scriptInterface.RegisterFunction("LobbyGuiPollHistoricMessages"); - scriptInterface.RegisterFunction("LobbyGuiPollHasPlayerListUpdate"); - scriptInterface.RegisterFunction("LobbySendMessage"); - scriptInterface.RegisterFunction("LobbySetPlayerPresence"); - scriptInterface.RegisterFunction("LobbySetNick"); - scriptInterface.RegisterFunction("LobbyGetNick"); - scriptInterface.RegisterFunction("LobbyKick"); - scriptInterface.RegisterFunction("LobbyBan"); - scriptInterface.RegisterFunction("LobbyGetPlayerPresence"); - scriptInterface.RegisterFunction("LobbyGetPlayerRole"); - scriptInterface.RegisterFunction("LobbyGetPlayerRating"); - scriptInterface.RegisterFunction("EncryptPassword"); - scriptInterface.RegisterFunction("LobbyGetRoomSubject"); -#endif // CONFIG2_LOBBY -} - -bool JSI_Lobby::HasXmppClient(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +bool HasXmppClient() { return g_XmppClient; } -void JSI_Lobby::SetRankedGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool isRanked) +void SetRankedGame(bool isRanked) { g_rankedGame = isRanked; } #if CONFIG2_LOBBY -void JSI_Lobby::StartXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize) +void StartXmppClient(const ScriptRequest& rq, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize) { if (g_XmppClient) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Cannot call StartXmppClient with an already initialized XmppClient!"); return; } @@ -104,11 +67,10 @@ void JSI_Lobby::StartXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, cons g_rankedGame = true; } -void JSI_Lobby::StartRegisterXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password) +void StartRegisterXmppClient(const ScriptRequest& rq, const std::wstring& username, const std::wstring& password) { if (g_XmppClient) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Cannot call StartRegisterXmppClient with an already initialized XmppClient!"); return; } @@ -124,11 +86,10 @@ void JSI_Lobby::StartRegisterXmppClient(ScriptInterface::CmptPrivate* pCmptPriva true); } -void JSI_Lobby::StopXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate) +void StopXmppClient(const ScriptRequest& rq) { if (!g_XmppClient) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Cannot call StopXmppClient without an initialized XmppClient!"); return; } @@ -137,79 +98,20 @@ void JSI_Lobby::StopXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate) g_rankedGame = false; } -void JSI_Lobby::ConnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate) +//////////////////////////////////////////////// +//////////////////////////////////////////////// + +IXmppClient* XmppGetter(const ScriptRequest&, JS::CallArgs&) { if (!g_XmppClient) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call ConnectXmppClient without an initialized XmppClient!"); - return; + LOGERROR("Cannot use XMPPClient functions without an initialized XmppClient!"); + return nullptr; } - - g_XmppClient->connect(); + return g_XmppClient; } -void JSI_Lobby::DisconnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call DisconnectXmppClient without an initialized XmppClient!"); - return; - } - - g_XmppClient->disconnect(); -} - -bool JSI_Lobby::IsXmppClientConnected(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call IsXmppClientConnected without an initialized XmppClient!"); - return false; - } - - return g_XmppClient->isConnected(); -} - -void JSI_Lobby::SendGetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call SendGetBoardList without an initialized XmppClient!"); - return; - } - - g_XmppClient->SendIqGetBoardList(); -} - -void JSI_Lobby::SendGetProfile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& player) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call SendGetProfile without an initialized XmppClient!"); - return; - } - - g_XmppClient->SendIqGetProfile(utf8_from_wstring(player)); -} - -void JSI_Lobby::SendGameReport(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call SendGameReport without an initialized XmppClient!"); - return; - } - - g_XmppClient->SendIqGameReport(*(pCmptPrivate->pScriptInterface), data); -} - -void JSI_Lobby::SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data) +void SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data) { if (!g_XmppClient) { @@ -228,235 +130,15 @@ void JSI_Lobby::SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS: g_XmppClient->SendIqRegisterGame(*(pCmptPrivate->pScriptInterface), data); } -void JSI_Lobby::SendUnregisterGame(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call SendUnregisterGame without an initialized XmppClient!"); - return; - } - - g_XmppClient->SendIqUnregisterGame(); -} - -void JSI_Lobby::SendChangeStateGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nbp, const std::wstring& players) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call SendChangeStateGame without an initialized XmppClient!"); - return; - } - - g_XmppClient->SendIqChangeStateGame(utf8_from_wstring(nbp), utf8_from_wstring(players)); -} - -JS::Value JSI_Lobby::GetPlayerList(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - ScriptRequest rq(pCmptPrivate->pScriptInterface); - - if (!g_XmppClient) - { - ScriptException::Raise(rq, "Cannot call GetPlayerList without an initialized XmppClient!"); - return JS::UndefinedValue(); - } - - JS::RootedValue playerList(rq.cx); - g_XmppClient->GUIGetPlayerList(*(pCmptPrivate->pScriptInterface), &playerList); - - return playerList; -} - -JS::Value JSI_Lobby::GetGameList(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - ScriptRequest rq(pCmptPrivate->pScriptInterface); - - if (!g_XmppClient) - { - ScriptException::Raise(rq, "Cannot call GetGameList without an initialized XmppClient!"); - return JS::UndefinedValue(); - } - - JS::RootedValue gameList(rq.cx); - g_XmppClient->GUIGetGameList(*(pCmptPrivate->pScriptInterface), &gameList); - - return gameList; -} - -JS::Value JSI_Lobby::GetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - ScriptRequest rq(pCmptPrivate->pScriptInterface); - - if (!g_XmppClient) - { - ScriptException::Raise(rq, "Cannot call GetBoardList without an initialized XmppClient!"); - return JS::UndefinedValue(); - } - - JS::RootedValue boardList(rq.cx); - g_XmppClient->GUIGetBoardList(*(pCmptPrivate->pScriptInterface), &boardList); - - return boardList; -} - -JS::Value JSI_Lobby::GetProfile(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - ScriptRequest rq(pCmptPrivate->pScriptInterface); - - if (!g_XmppClient) - { - ScriptException::Raise(rq, "Cannot call GetProfile without an initialized XmppClient!"); - return JS::UndefinedValue(); - } - - JS::RootedValue profileFetch(rq.cx); - g_XmppClient->GUIGetProfile(*(pCmptPrivate->pScriptInterface), &profileFetch); - - return profileFetch; -} - -bool JSI_Lobby::LobbyGuiPollHasPlayerListUpdate(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyGuiPollHasPlayerListUpdate without an initialized XmppClient!"); - return false; - } - - return g_XmppClient->GuiPollHasPlayerListUpdate(); -} - -JS::Value JSI_Lobby::LobbyGuiPollNewMessages(ScriptInterface::CmptPrivate* pCmptPrivate) +// Unlike other functions, this one just returns Undefined if XmppClient isn't initialised. +JS::Value GuiPollNewMessages(const ScriptInterface& scriptInterface) { if (!g_XmppClient) return JS::UndefinedValue(); - return g_XmppClient->GuiPollNewMessages(*(pCmptPrivate->pScriptInterface)); + return g_XmppClient->GuiPollNewMessages(scriptInterface); } -JS::Value JSI_Lobby::LobbyGuiPollHistoricMessages(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyGuiPollHistoricMessages without an initialized XmppClient!"); - return JS::UndefinedValue(); - } - - return g_XmppClient->GuiPollHistoricMessages(*(pCmptPrivate->pScriptInterface)); -} - -void JSI_Lobby::LobbySendMessage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& message) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbySendMessage without an initialized XmppClient!"); - return; - } - - g_XmppClient->SendMUCMessage(utf8_from_wstring(message)); -} - -void JSI_Lobby::LobbySetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& presence) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbySetPlayerPresence without an initialized XmppClient!"); - return; - } - - g_XmppClient->SetPresence(utf8_from_wstring(presence)); -} - -void JSI_Lobby::LobbySetNick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbySetNick without an initialized XmppClient!"); - return; - } - - g_XmppClient->SetNick(utf8_from_wstring(nick)); -} - -std::wstring JSI_Lobby::LobbyGetNick(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyGetNick without an initialized XmppClient!"); - return std::wstring(); - } - - std::string nick; - g_XmppClient->GetNick(nick); - return wstring_from_utf8(nick); -} - -void JSI_Lobby::LobbyKick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyKick without an initialized XmppClient!"); - return; - } - - g_XmppClient->kick(utf8_from_wstring(nick), utf8_from_wstring(reason)); -} - -void JSI_Lobby::LobbyBan(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyBan without an initialized XmppClient!"); - return; - } - - g_XmppClient->ban(utf8_from_wstring(nick), utf8_from_wstring(reason)); -} - -const char* JSI_Lobby::LobbyGetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyGetPlayerPresence without an initialized XmppClient!"); - return ""; - } - - return g_XmppClient->GetPresence(utf8_from_wstring(nickname)); -} - -const char* JSI_Lobby::LobbyGetPlayerRole(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyGetPlayerRole without an initialized XmppClient!"); - return ""; - } - - return g_XmppClient->GetRole(utf8_from_wstring(nickname)); -} - -std::wstring JSI_Lobby::LobbyGetPlayerRating(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyGetPlayerRating without an initialized XmppClient!"); - return std::wstring(); - } - - return g_XmppClient->GetRating(utf8_from_wstring(nickname)); -} // Non-public secure PBKDF2 hash function with salting and 1,337 iterations // @@ -470,7 +152,7 @@ std::wstring JSI_Lobby::LobbyGetPlayerRating(ScriptInterface::CmptPrivate* pCmpt // the new hashing method. Dropping the old hashing code can only be done either by giving users // a way to reset their password, or by keeping track of successful password updates and dropping // old unused accounts after some time. -std::string JSI_Lobby::EncryptPassword(const std::string& password, const std::string& username) +std::string EncryptPassword(const std::string& password, const std::string& username) { ENSURE(sodium_init() >= 0); @@ -500,21 +182,51 @@ std::string JSI_Lobby::EncryptPassword(const std::string& password, const std::s return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase(); } -std::wstring JSI_Lobby::EncryptPassword(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& pass, const std::wstring& user) -{ - return wstring_from_utf8(JSI_Lobby::EncryptPassword(utf8_from_wstring(pass), utf8_from_wstring(user))); -} - -std::wstring JSI_Lobby::LobbyGetRoomSubject(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_XmppClient) - { - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "Cannot call LobbyGetRoomSubject without an initialized XmppClient!"); - return std::wstring(); - } - - return g_XmppClient->GetSubject(); -} - #endif + +void RegisterScriptFunctions(const ScriptRequest& rq) +{ + // Lobby functions + ScriptFunction::Register<&HasXmppClient>(rq, "HasXmppClient"); + ScriptFunction::Register<&SetRankedGame>(rq, "SetRankedGame"); +#if CONFIG2_LOBBY // Allow the lobby to be disabled + ScriptFunction::Register<&StartXmppClient>(rq, "StartXmppClient"); + ScriptFunction::Register<&StartRegisterXmppClient>(rq, "StartRegisterXmppClient"); + ScriptFunction::Register<&StopXmppClient>(rq, "StopXmppClient"); + +#define REGISTER_XMPP(func, name) \ + ScriptFunction::Register<&IXmppClient::func, &XmppGetter>(rq, name) + + REGISTER_XMPP(connect, "ConnectXmppClient"); + REGISTER_XMPP(disconnect, "DisconnectXmppClient"); + REGISTER_XMPP(isConnected, "IsXmppClientConnected"); + REGISTER_XMPP(SendIqGetBoardList, "SendGetBoardList"); + REGISTER_XMPP(SendIqGetProfile, "SendGetProfile"); + REGISTER_XMPP(SendIqGameReport, "SendGameReport"); + ScriptFunction::Register<&SendRegisterGame>(rq, "SendRegisterGame"); + REGISTER_XMPP(SendIqUnregisterGame, "SendUnregisterGame"); + REGISTER_XMPP(SendIqChangeStateGame, "SendChangeStateGame"); + REGISTER_XMPP(GUIGetPlayerList, "GetPlayerList"); + REGISTER_XMPP(GUIGetGameList, "GetGameList"); + REGISTER_XMPP(GUIGetBoardList, "GetBoardList"); + REGISTER_XMPP(GUIGetProfile, "GetProfile"); + + ScriptFunction::Register<&GuiPollNewMessages>(rq, "LobbyGuiPollNewMessages"); + REGISTER_XMPP(GuiPollHistoricMessages, "LobbyGuiPollHistoricMessages"); + REGISTER_XMPP(GuiPollHasPlayerListUpdate, "LobbyGuiPollHasPlayerListUpdate"); + REGISTER_XMPP(SendMUCMessage, "LobbySendMessage"); + REGISTER_XMPP(SetPresence, "LobbySetPlayerPresence"); + REGISTER_XMPP(SetNick, "LobbySetNick"); + REGISTER_XMPP(GetNick, "LobbyGetNick"); + REGISTER_XMPP(kick, "LobbyKick"); + REGISTER_XMPP(ban, "LobbyBan"); + REGISTER_XMPP(GetPresence, "LobbyGetPlayerPresence"); + REGISTER_XMPP(GetRole, "LobbyGetPlayerRole"); + REGISTER_XMPP(GetRating, "LobbyGetPlayerRating"); + REGISTER_XMPP(GetSubject, "LobbyGetRoomSubject"); +#undef REGISTER_XMPP + + ScriptFunction::Register<&EncryptPassword>(rq, "EncryptPassword"); +#endif // CONFIG2_LOBBY +} +} diff --git a/source/lobby/scripting/JSInterface_Lobby.h b/source/lobby/scripting/JSInterface_Lobby.h index cedbdc353b..5eba1ecc91 100644 --- a/source/lobby/scripting/JSInterface_Lobby.h +++ b/source/lobby/scripting/JSInterface_Lobby.h @@ -18,56 +18,11 @@ #ifndef INCLUDED_JSI_LOBBY #define INCLUDED_JSI_LOBBY -#include "lib/config2.h" -#include "scriptinterface/ScriptInterface.h" - -#include +class ScriptRequest; namespace JSI_Lobby { - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); - - bool HasXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate); - bool IsRankedGame(ScriptInterface::CmptPrivate* pCmptPrivate); - void SetRankedGame(ScriptInterface::CmptPrivate* pCmptPrivate, bool isRanked); - -#if CONFIG2_LOBBY - void StartXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize); - void StartRegisterXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password); - void StopXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate); - void ConnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate); - void DisconnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate); - bool IsXmppClientConnected(ScriptInterface::CmptPrivate* pCmptPrivate); - void SendGetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate); - void SendGetProfile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& player); - void SendGameReport(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data); - void SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data); - void SendUnregisterGame(ScriptInterface::CmptPrivate* pCmptPrivate); - void SendChangeStateGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nbp, const std::wstring& players); - JS::Value GetPlayerList(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value GetGameList(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value GetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value GetProfile(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value LobbyGuiPollNewMessages(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value LobbyGuiPollHistoricMessages(ScriptInterface::CmptPrivate* pCmptPrivate); - bool LobbyGuiPollHasPlayerListUpdate(ScriptInterface::CmptPrivate* pCmptPrivate); - void LobbySendMessage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& message); - void LobbySetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& presence); - void LobbySetNick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick); - std::wstring LobbyGetNick(ScriptInterface::CmptPrivate* pCmptPrivate); - void LobbyKick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason); - void LobbyBan(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason); - const char* LobbyGetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname); - const char* LobbyGetPlayerRole(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname); - std::wstring LobbyGetPlayerRating(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname); - std::wstring LobbyGetRoomSubject(ScriptInterface::CmptPrivate* pCmptPrivate); - - // Non-public secure PBKDF2 hash function with salting and 1,337 iterations - std::string EncryptPassword(const std::string& password, const std::string& username); - - // Public hash interface. - std::wstring EncryptPassword(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& pass, const std::wstring& user); -#endif // CONFIG2_LOBBY + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_LOBBY diff --git a/source/network/scripting/JSInterface_Network.cpp b/source/network/scripting/JSInterface_Network.cpp index 3c7f94e684..f6fd82b2ab 100644 --- a/source/network/scripting/JSInterface_Network.cpp +++ b/source/network/scripting/JSInterface_Network.cpp @@ -31,31 +31,34 @@ #include "ps/Game.h" #include "ps/GUID.h" #include "ps/Util.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "third_party/encryption/pkcs5_pbkdf2.h" -u16 JSI_Network::GetDefaultPort(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +namespace JSI_Network +{ +u16 GetDefaultPort() { return PS_DEFAULT_PORT; } -bool JSI_Network::IsNetController(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +bool IsNetController() { return !!g_NetClient && g_NetClient->IsController(); } -bool JSI_Network::HasNetServer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +bool HasNetServer() { return !!g_NetServer; } -bool JSI_Network::HasNetClient(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +bool HasNetClient() { return !!g_NetClient; } -CStr JSI_Network::HashPassword(const CStr& password) +CStr HashPassword(const CStr& password) { if (password.empty()) return password; @@ -84,7 +87,7 @@ CStr JSI_Network::HashPassword(const CStr& password) return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase(); } -void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName, bool useSTUN, const CStr& password) +void StartNetworkHost(const ScriptRequest& rq, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName, bool useSTUN, const CStr& password) { ENSURE(!g_NetClient); ENSURE(!g_NetServer); @@ -109,7 +112,6 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c // This is using port variable to store return value, do not pass serverPort itself. if (!StunClient::FindStunEndpointHost(ip, port)) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Failed to host via STUN."); SAFE_DELETE(g_NetServer); return; @@ -120,7 +122,6 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c if (!g_NetServer->SetupConnection(serverPort)) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Failed to start server"); SAFE_DELETE(g_NetServer); return; @@ -144,14 +145,13 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c if (!g_NetClient->SetupConnection(nullptr)) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Failed to connect to server"); SAFE_DELETE(g_NetClient); SAFE_DELETE(g_Game); } } -void JSI_Network::StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID) +void StartNetworkJoin(const ScriptRequest& rq, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID) { ENSURE(!g_NetClient); ENSURE(!g_NetServer); @@ -165,14 +165,18 @@ void JSI_Network::StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, c if (!g_NetClient->SetupConnection(nullptr)) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Failed to connect to server"); SAFE_DELETE(g_NetClient); SAFE_DELETE(g_Game); } } -void JSI_Network::StartNetworkJoinLobby(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& playerName, const CStr& hostJID, const CStr& password) +/** + * Requires XmppClient to send iq request to the server to get server's ip and port based on passed password. + * This is needed to not force server to share it's public ip with all potential clients in the lobby. + * XmppClient will also handle logic after receiving the answer. + */ +void StartNetworkJoinLobby(const CStrW& playerName, const CStr& hostJID, const CStr& password) { ENSURE(!!g_XmppClient); ENSURE(!g_NetClient); @@ -188,7 +192,7 @@ void JSI_Network::StartNetworkJoinLobby(ScriptInterface::CmptPrivate* UNUSED(pCm g_XmppClient->SendIqGetConnectionData(hostJID, hashedPass.c_str()); } -void JSI_Network::DisconnectNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void DisconnectNetworkGame() { // TODO: we ought to do async reliable disconnections @@ -197,7 +201,7 @@ void JSI_Network::DisconnectNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCm SAFE_DELETE(g_Game); } -CStr JSI_Network::GetPlayerGUID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +CStr GetPlayerGUID() { if (!g_NetClient) return "local"; @@ -205,7 +209,7 @@ CStr JSI_Network::GetPlayerGUID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat return g_NetClient->GetGUID(); } -JS::Value JSI_Network::PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPrivate) +JS::Value PollNetworkClient(const ScriptInterface& scriptInterface) { if (!g_NetClient) return JS::UndefinedValue(); @@ -214,62 +218,62 @@ JS::Value JSI_Network::PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPriv ScriptRequest rqNet(g_NetClient->GetScriptInterface()); JS::RootedValue pollNet(rqNet.cx); g_NetClient->GuiPoll(&pollNet); - return pCmptPrivate->pScriptInterface->CloneValueFromOtherCompartment(g_NetClient->GetScriptInterface(), pollNet); + return scriptInterface.CloneValueFromOtherCompartment(g_NetClient->GetScriptInterface(), pollNet); } -void JSI_Network::SetNetworkGameAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs1) +void SetNetworkGameAttributes(const ScriptInterface& scriptInterface, JS::HandleValue attribs1) { ENSURE(g_NetClient); // TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere (with no obvious reason). - ScriptRequest rq(pCmptPrivate->pScriptInterface); + ScriptRequest rq(scriptInterface); JS::RootedValue attribs(rq.cx, attribs1); - g_NetClient->SendGameSetupMessage(&attribs, *(pCmptPrivate->pScriptInterface)); + g_NetClient->SendGameSetupMessage(&attribs, scriptInterface); } -void JSI_Network::AssignNetworkPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int playerID, const CStr& guid) +void AssignNetworkPlayer(int playerID, const CStr& guid) { ENSURE(g_NetClient); g_NetClient->SendAssignPlayerMessage(playerID, guid); } -void JSI_Network::KickPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& playerName, bool ban) +void KickPlayer(const CStrW& playerName, bool ban) { ENSURE(g_NetClient); g_NetClient->SendKickPlayerMessage(playerName, ban); } -void JSI_Network::SendNetworkChat(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& message) +void SendNetworkChat(const CStrW& message) { ENSURE(g_NetClient); g_NetClient->SendChatMessage(message); } -void JSI_Network::SendNetworkReady(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int message) +void SendNetworkReady(int message) { ENSURE(g_NetClient); g_NetClient->SendReadyMessage(message); } -void JSI_Network::ClearAllPlayerReady (ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void ClearAllPlayerReady () { ENSURE(g_NetClient); g_NetClient->SendClearAllReadyMessage(); } -void JSI_Network::StartNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void StartNetworkGame() { ENSURE(g_NetClient); g_NetClient->SendStartGameMessage(); } -void JSI_Network::SetTurnLength(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int length) +void SetTurnLength(int length) { if (g_NetServer) g_NetServer->SetTurnLength(length); @@ -277,24 +281,25 @@ void JSI_Network::SetTurnLength(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat LOGERROR("Only network host can change turn length"); } -void JSI_Network::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("GetDefaultPort"); - scriptInterface.RegisterFunction("IsNetController"); - scriptInterface.RegisterFunction("HasNetServer"); - scriptInterface.RegisterFunction("HasNetClient"); - scriptInterface.RegisterFunction("StartNetworkHost"); - scriptInterface.RegisterFunction("StartNetworkJoin"); - scriptInterface.RegisterFunction("StartNetworkJoinLobby"); - scriptInterface.RegisterFunction("DisconnectNetworkGame"); - scriptInterface.RegisterFunction("GetPlayerGUID"); - scriptInterface.RegisterFunction("PollNetworkClient"); - scriptInterface.RegisterFunction("SetNetworkGameAttributes"); - scriptInterface.RegisterFunction("AssignNetworkPlayer"); - scriptInterface.RegisterFunction("KickPlayer"); - scriptInterface.RegisterFunction("SendNetworkChat"); - scriptInterface.RegisterFunction("SendNetworkReady"); - scriptInterface.RegisterFunction("ClearAllPlayerReady"); - scriptInterface.RegisterFunction("StartNetworkGame"); - scriptInterface.RegisterFunction("SetTurnLength"); + ScriptFunction::Register<&GetDefaultPort>(rq, "GetDefaultPort"); + ScriptFunction::Register<&IsNetController>(rq, "IsNetController"); + ScriptFunction::Register<&HasNetServer>(rq, "HasNetServer"); + ScriptFunction::Register<&HasNetClient>(rq, "HasNetClient"); + ScriptFunction::Register<&StartNetworkHost>(rq, "StartNetworkHost"); + ScriptFunction::Register<&StartNetworkJoin>(rq, "StartNetworkJoin"); + ScriptFunction::Register<&StartNetworkJoinLobby>(rq, "StartNetworkJoinLobby"); + ScriptFunction::Register<&DisconnectNetworkGame>(rq, "DisconnectNetworkGame"); + ScriptFunction::Register<&GetPlayerGUID>(rq, "GetPlayerGUID"); + ScriptFunction::Register<&PollNetworkClient>(rq, "PollNetworkClient"); + ScriptFunction::Register<&SetNetworkGameAttributes>(rq, "SetNetworkGameAttributes"); + ScriptFunction::Register<&AssignNetworkPlayer>(rq, "AssignNetworkPlayer"); + ScriptFunction::Register<&KickPlayer>(rq, "KickPlayer"); + ScriptFunction::Register<&SendNetworkChat>(rq, "SendNetworkChat"); + ScriptFunction::Register<&SendNetworkReady>(rq, "SendNetworkReady"); + ScriptFunction::Register<&ClearAllPlayerReady>(rq, "ClearAllPlayerReady"); + ScriptFunction::Register<&StartNetworkGame>(rq, "StartNetworkGame"); + ScriptFunction::Register<&SetTurnLength>(rq, "SetTurnLength"); +} } diff --git a/source/network/scripting/JSInterface_Network.h b/source/network/scripting/JSInterface_Network.h index de49ab0aee..23456b9d97 100644 --- a/source/network/scripting/JSInterface_Network.h +++ b/source/network/scripting/JSInterface_Network.h @@ -18,38 +18,11 @@ #ifndef INCLUDED_JSI_NETWORK #define INCLUDED_JSI_NETWORK -#include "lib/types.h" -#include "ps/CStr.h" -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_Network { - u16 GetDefaultPort(ScriptInterface::CmptPrivate* pCmptPrivate); - bool IsNetController(ScriptInterface::CmptPrivate* pCmptPrivate); - bool HasNetServer(ScriptInterface::CmptPrivate* pCmptPrivate); - bool HasNetClient(ScriptInterface::CmptPrivate* pCmptPrivate); - void StartNetworkGame(ScriptInterface::CmptPrivate* pCmptPrivate); - void SetNetworkGameAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs1); - void StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName, bool useSTUN, const CStr& password); - void StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID); - /** - * Requires XmppClient to send iq request to the server to get server's ip and port based on passed password. - * This is needed to not force server to share it's public ip with all potential clients in the lobby. - * XmppClient will also handle logic after receiving the answer. - */ - void StartNetworkJoinLobby(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& hostJID, const CStr& password); - void DisconnectNetworkGame(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPrivate); - CStr GetPlayerGUID(ScriptInterface::CmptPrivate* pCmptPrivate); - void KickPlayer(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, bool ban); - void AssignNetworkPlayer(ScriptInterface::CmptPrivate* pCmptPrivate, int playerID, const CStr& guid); - void ClearAllPlayerReady (ScriptInterface::CmptPrivate* pCmptPrivate); - void SendNetworkChat(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& message); - void SendNetworkReady(ScriptInterface::CmptPrivate* pCmptPrivate, int message); - void SetTurnLength(ScriptInterface::CmptPrivate* pCmptPrivate, int length); - - CStr HashPassword(const CStr& password); - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_NETWORK diff --git a/source/ps/ModIo.cpp b/source/ps/ModIo.cpp index 2a45c5dff5..365b155b44 100644 --- a/source/ps/ModIo.cpp +++ b/source/ps/ModIo.cpp @@ -296,7 +296,7 @@ void ModIo::StartListMods() m_DownloadProgressData.status = DownloadProgressStatus::LISTING; } -void ModIo::StartDownloadMod(size_t idx) +void ModIo::StartDownloadMod(u32 idx) { // Don't start such a request during active downloads. if (m_DownloadProgressData.status == DownloadProgressStatus::GAMEID || diff --git a/source/ps/ModIo.h b/source/ps/ModIo.h index 5242e712c8..ec335e6e3c 100644 --- a/source/ps/ModIo.h +++ b/source/ps/ModIo.h @@ -133,7 +133,7 @@ public: // Async requests void StartGetGameId(); void StartListMods(); - void StartDownloadMod(size_t idx); + void StartDownloadMod(u32 idx); /** * Advance the current async request and perform final steps if the download is complete. diff --git a/source/ps/VisualReplay.cpp b/source/ps/VisualReplay.cpp index 71f504148d..4c61829015 100644 --- a/source/ps/VisualReplay.cpp +++ b/source/ps/VisualReplay.cpp @@ -425,10 +425,10 @@ bool VisualReplay::DeleteReplay(const OsPath& replayDirectory) return DirectoryExists(directory) && DeleteDirectory(directory) == INFO::OK; } -JS::Value VisualReplay::GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName) +JS::Value VisualReplay::GetReplayAttributes(const ScriptInterface& scriptInterface, const OsPath& directoryName) { // Create empty JS object - ScriptRequest rq(pCmptPrivate->pScriptInterface); + ScriptRequest rq(scriptInterface); JS::RootedValue attribs(rq.cx); ScriptInterface::CreateObject(rq, &attribs); @@ -444,7 +444,7 @@ JS::Value VisualReplay::GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptP // Read and return first line std::getline(*replayStream, line); - pCmptPrivate->pScriptInterface->ParseJSON(line, &attribs); + scriptInterface.ParseJSON(line, &attribs); SAFE_DELETE(replayStream);; return attribs; } @@ -482,12 +482,12 @@ bool VisualReplay::HasReplayMetadata(const OsPath& directoryName) return fileInfo.Size() > 0; } -JS::Value VisualReplay::GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName) +JS::Value VisualReplay::GetReplayMetadata(const ScriptInterface& scriptInterface, const OsPath& directoryName) { if (!HasReplayMetadata(directoryName)) return JS::NullValue(); - ScriptRequest rq(pCmptPrivate->pScriptInterface); + ScriptRequest rq(scriptInterface); JS::RootedValue metadata(rq.cx); std::ifstream* stream = new std::ifstream(OsString(GetDirectoryPath() / directoryName / L"metadata.json").c_str()); @@ -496,7 +496,7 @@ JS::Value VisualReplay::GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPri std::getline(*stream, line); stream->close(); SAFE_DELETE(stream); - pCmptPrivate->pScriptInterface->ParseJSON(line, &metadata); + scriptInterface.ParseJSON(line, &metadata); return metadata; } diff --git a/source/ps/VisualReplay.h b/source/ps/VisualReplay.h index 640b4aa8fc..9b4f70ece8 100644 --- a/source/ps/VisualReplay.h +++ b/source/ps/VisualReplay.h @@ -15,15 +15,16 @@ * along with 0 A.D. If not, see . */ -#ifndef INCLUDED_REPlAY -#define INCLUDED_REPlAY +#ifndef INCLUDED_VISUAL_REPLAY +#define INCLUDED_VISUAL_REPLAY #include "lib/os_path.h" -#include "scriptinterface/ScriptInterface.h" class CSimulation2; class CGUIManager; +class ScriptInterface; + /** * Contains functions for visually replaying past games. */ @@ -104,7 +105,7 @@ bool DeleteReplay(const OsPath& replayFile); /** * Returns the parsed header of the replay file (commands.txt). */ -JS::Value GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName); +JS::Value GetReplayAttributes(const ScriptInterface& scriptInterface, const OsPath& directoryName); /** * Returns whether or not the metadata / summary screen data has been saved properly when the game ended. @@ -114,7 +115,7 @@ bool HasReplayMetadata(const OsPath& directoryName); /** * Returns the metadata of a replay. */ -JS::Value GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName); +JS::Value GetReplayMetadata(const ScriptInterface& scriptInterface, const OsPath& directoryName); /** * Adds a replay to the replayCache. diff --git a/source/ps/scripting/JSInterface_ConfigDB.cpp b/source/ps/scripting/JSInterface_ConfigDB.cpp index c39de7fc85..8832917e15 100644 --- a/source/ps/scripting/JSInterface_ConfigDB.cpp +++ b/source/ps/scripting/JSInterface_ConfigDB.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 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 @@ -21,11 +21,14 @@ #include "ps/ConfigDB.h" #include "ps/CLogger.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include #include +namespace JSI_ConfigDB +{ // These entries will not be readable nor writable for JS, so that e.g. malicious mods can't leak personal or sensitive data static const std::unordered_set g_ProtectedConfigNames = { "modio.public_key", // See ModIO.cpp @@ -35,7 +38,7 @@ static const std::unordered_set g_ProtectedConfigNames = { "userreport.id" // Acts as authentication token for GDPR personal data requests. }; -bool JSI_ConfigDB::IsProtectedConfigName(const std::string& name) +bool IsProtectedConfigName(const std::string& name) { if (g_ProtectedConfigNames.find(name) != g_ProtectedConfigNames.end()) { @@ -45,7 +48,7 @@ bool JSI_ConfigDB::IsProtectedConfigName(const std::string& name) return false; } -bool JSI_ConfigDB::GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs) +bool GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs) { if (cfgNsString == L"default") cfgNs = CFG_DEFAULT; @@ -66,7 +69,7 @@ bool JSI_ConfigDB::GetConfigNamespace(const std::wstring& cfgNsString, EConfigNa return true; } -bool JSI_ConfigDB::HasChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString) +bool HasChanges(const std::wstring& cfgNsString) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -75,7 +78,7 @@ bool JSI_ConfigDB::HasChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) return g_ConfigDB.HasChanges(cfgNs); } -bool JSI_ConfigDB::SetChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, bool value) +bool SetChanges(const std::wstring& cfgNsString, bool value) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -85,7 +88,7 @@ bool JSI_ConfigDB::SetChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) return true; } -std::string JSI_ConfigDB::GetValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name) +std::string GetValue(const std::wstring& cfgNsString, const std::string& name) { if (IsProtectedConfigName(name)) return ""; @@ -99,7 +102,7 @@ std::string JSI_ConfigDB::GetValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPri return value; } -bool JSI_ConfigDB::CreateValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name, const std::string& value) +bool CreateValue(const std::wstring& cfgNsString, const std::string& name, const std::string& value) { if (IsProtectedConfigName(name)) return false; @@ -112,7 +115,7 @@ bool JSI_ConfigDB::CreateValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate return true; } -bool JSI_ConfigDB::CreateValues(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name, const std::vector& values) +bool CreateValues(const std::wstring& cfgNsString, const std::string& name, const std::vector& values) { if (IsProtectedConfigName(name)) return false; @@ -126,7 +129,7 @@ bool JSI_ConfigDB::CreateValues(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat } -bool JSI_ConfigDB::RemoveValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name) +bool RemoveValue(const std::wstring& cfgNsString, const std::string& name) { if (IsProtectedConfigName(name)) return false; @@ -139,7 +142,7 @@ bool JSI_ConfigDB::RemoveValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate return true; } -bool JSI_ConfigDB::WriteFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const Path& path) +bool WriteFile(const std::wstring& cfgNsString, const Path& path) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -148,7 +151,7 @@ bool JSI_ConfigDB::WriteFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), return g_ConfigDB.WriteFile(cfgNs, path); } -bool JSI_ConfigDB::WriteValueToFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) +bool WriteValueToFile(const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) { if (IsProtectedConfigName(name)) return false; @@ -160,13 +163,13 @@ bool JSI_ConfigDB::WriteValueToFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPr return g_ConfigDB.WriteValueToFile(cfgNs, name, value, path); } -void JSI_ConfigDB::CreateAndWriteValueToFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) +void CreateAndWriteValueToFile(const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) { - CreateValue(pCmptPrivate, cfgNsString, name, value); - WriteValueToFile(pCmptPrivate, cfgNsString, name, value, path); + CreateValue(cfgNsString, name, value); + WriteValueToFile(cfgNsString, name, value, path); } -bool JSI_ConfigDB::Reload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString) +bool Reload(const std::wstring& cfgNsString) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -175,7 +178,7 @@ bool JSI_ConfigDB::Reload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), co return g_ConfigDB.Reload(cfgNs); } -bool JSI_ConfigDB::SetFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const Path& path) +bool SetFile(const std::wstring& cfgNsString, const Path& path) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -185,17 +188,18 @@ bool JSI_ConfigDB::SetFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), c return true; } -void JSI_ConfigDB::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("ConfigDB_HasChanges"); - scriptInterface.RegisterFunction("ConfigDB_SetChanges"); - scriptInterface.RegisterFunction("ConfigDB_GetValue"); - scriptInterface.RegisterFunction("ConfigDB_CreateValue"); - scriptInterface.RegisterFunction, &JSI_ConfigDB::CreateValues>("ConfigDB_CreateValues"); - scriptInterface.RegisterFunction("ConfigDB_RemoveValue"); - scriptInterface.RegisterFunction("ConfigDB_WriteFile"); - scriptInterface.RegisterFunction("ConfigDB_WriteValueToFile"); - scriptInterface.RegisterFunction("ConfigDB_CreateAndWriteValueToFile"); - scriptInterface.RegisterFunction("ConfigDB_SetFile"); - scriptInterface.RegisterFunction("ConfigDB_Reload"); + ScriptFunction::Register<&HasChanges>(rq, "ConfigDB_HasChanges"); + ScriptFunction::Register<&SetChanges>(rq, "ConfigDB_SetChanges"); + ScriptFunction::Register<&GetValue>(rq, "ConfigDB_GetValue"); + ScriptFunction::Register<&CreateValue>(rq, "ConfigDB_CreateValue"); + ScriptFunction::Register<&CreateValues>(rq, "ConfigDB_CreateValues"); + ScriptFunction::Register<&RemoveValue>(rq, "ConfigDB_RemoveValue"); + ScriptFunction::Register<&WriteFile>(rq, "ConfigDB_WriteFile"); + ScriptFunction::Register<&WriteValueToFile>(rq, "ConfigDB_WriteValueToFile"); + ScriptFunction::Register<&CreateAndWriteValueToFile>(rq, "ConfigDB_CreateAndWriteValueToFile"); + ScriptFunction::Register<&SetFile>(rq, "ConfigDB_SetFile"); + ScriptFunction::Register<&Reload>(rq, "ConfigDB_Reload"); +} } diff --git a/source/ps/scripting/JSInterface_ConfigDB.h b/source/ps/scripting/JSInterface_ConfigDB.h index 2440d7fea9..bc12b1aa6a 100644 --- a/source/ps/scripting/JSInterface_ConfigDB.h +++ b/source/ps/scripting/JSInterface_ConfigDB.h @@ -18,27 +18,11 @@ #ifndef INCLUDED_JSI_CONFIGDB #define INCLUDED_JSI_CONFIGDB -#include "ps/ConfigDB.h" -#include "scriptinterface/ScriptInterface.h" - -#include +class ScriptRequest; namespace JSI_ConfigDB { - bool IsProtectedConfigName(const std::string& name); - bool GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs); - bool HasChanges(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString); - bool SetChanges(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, bool value); - std::string GetValue(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name); - bool CreateValue(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value); - bool CreateValues(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::vector& values); - bool RemoveValue(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name); - bool WriteFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const Path& path); - bool WriteValueToFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path); - void CreateAndWriteValueToFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path); - bool Reload(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString); - bool SetFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const Path& path); - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_CONFIGDB diff --git a/source/ps/scripting/JSInterface_Console.cpp b/source/ps/scripting/JSInterface_Console.cpp index cbe3e8c39c..def3251d43 100644 --- a/source/ps/scripting/JSInterface_Console.cpp +++ b/source/ps/scripting/JSInterface_Console.cpp @@ -23,7 +23,7 @@ #include "ps/CLogger.h" #include "scriptinterface/FunctionWrapper.h" -namespace +namespace JSI_Console { CConsole* ConsoleGetter(const ScriptRequest&, JS::CallArgs&) { @@ -34,10 +34,10 @@ CConsole* ConsoleGetter(const ScriptRequest&, JS::CallArgs&) } return g_Console; } -} -void JSI_Console::RegisterScriptFunctions(const ScriptRequest& rq) +void RegisterScriptFunctions(const ScriptRequest& rq) { ScriptFunction::Register<&CConsole::IsActive, ConsoleGetter>(rq, "Console_GetVisibleEnabled"); ScriptFunction::Register<&CConsole::SetVisible, ConsoleGetter>(rq, "Console_SetVisibleEnabled"); } +} diff --git a/source/ps/scripting/JSInterface_Debug.cpp b/source/ps/scripting/JSInterface_Debug.cpp index bf292ed70b..86b8b20b34 100644 --- a/source/ps/scripting/JSInterface_Debug.cpp +++ b/source/ps/scripting/JSInterface_Debug.cpp @@ -22,15 +22,18 @@ #include "i18n/L10n.h" #include "lib/svn_revision.h" #include "lib/debug.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include #include +namespace JSI_Debug +{ /** * Microseconds since the epoch. */ -double JSI_Debug::GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +double GetMicroseconds() { return JS_Now(); } @@ -38,18 +41,18 @@ double JSI_Debug::GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPriv // Deliberately cause the game to crash. // Currently implemented via access violation (read of address 0). // Useful for testing the crashlog/stack trace code. -int JSI_Debug::Crash(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +int Crash() { debug_printf("Crashing at user's request.\n"); return *(volatile int*)0; } -void JSI_Debug::DebugWarn(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void DebugWarn() { debug_warn(L"Warning at user's request."); } -void JSI_Debug::DisplayErrorDialog(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& msg) +void DisplayErrorDialog(const std::wstring& msg) { debug_DisplayError(msg.c_str(), DE_NO_DEBUG_INFO, NULL, NULL, NULL, 0, NULL, NULL); } @@ -58,13 +61,13 @@ void JSI_Debug::DisplayErrorDialog(ScriptInterface::CmptPrivate* UNUSED(pCmptPri // - Displayed on main menu screen; tells non-programmers which auto-build // they are running. Could also be determined via .EXE file properties, // but that's a bit more trouble. -std::wstring JSI_Debug::GetBuildDate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::wstring GetBuildDate() { UDate buildDate = g_L10n.ParseDateTime(__DATE__, "MMM d yyyy", icu::Locale::getUS()); return wstring_from_utf8(g_L10n.LocalizeDateTime(buildDate, L10n::Date, icu::SimpleDateFormat::MEDIUM)); } -double JSI_Debug::GetBuildTimestamp(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +double GetBuildTimestamp() { UDate buildDate = g_L10n.ParseDateTime(__DATE__ " " __TIME__, "MMM d yyyy HH:mm:ss", icu::Locale::getUS()); if (buildDate) @@ -77,7 +80,7 @@ double JSI_Debug::GetBuildTimestamp(ScriptInterface::CmptPrivate* UNUSED(pCmptPr // lib/svn_revision.cpp. it is useful to know when attempting to // reproduce bugs (the main EXE and PDB should be temporarily reverted to // that revision so that they match user-submitted crashdumps). -std::wstring JSI_Debug::GetBuildRevision(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::wstring GetBuildRevision() { std::wstring svnRevision(svn_revision); if (svnRevision == L"custom build") @@ -85,13 +88,14 @@ std::wstring JSI_Debug::GetBuildRevision(ScriptInterface::CmptPrivate* UNUSED(pC return svnRevision; } -void JSI_Debug::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("GetMicroseconds"); - scriptInterface.RegisterFunction("Crash"); - scriptInterface.RegisterFunction("DebugWarn"); - scriptInterface.RegisterFunction("DisplayErrorDialog"); - scriptInterface.RegisterFunction("GetBuildDate"); - scriptInterface.RegisterFunction("GetBuildTimestamp"); - scriptInterface.RegisterFunction("GetBuildRevision"); + ScriptFunction::Register<&GetMicroseconds>(rq, "GetMicroseconds"); + ScriptFunction::Register<&Crash>(rq, "Crash"); + ScriptFunction::Register<&DebugWarn>(rq, "DebugWarn"); + ScriptFunction::Register<&DisplayErrorDialog>(rq, "DisplayErrorDialog"); + ScriptFunction::Register<&GetBuildDate>(rq, "GetBuildDate"); + ScriptFunction::Register<&GetBuildTimestamp>(rq, "GetBuildTimestamp"); + ScriptFunction::Register<&GetBuildRevision>(rq, "GetBuildRevision"); +} } diff --git a/source/ps/scripting/JSInterface_Debug.h b/source/ps/scripting/JSInterface_Debug.h index 50b9034a1b..b7753a8c06 100644 --- a/source/ps/scripting/JSInterface_Debug.h +++ b/source/ps/scripting/JSInterface_Debug.h @@ -18,21 +18,11 @@ #ifndef INCLUDED_JSI_DEBUG #define INCLUDED_JSI_DEBUG -#include "scriptinterface/ScriptInterface.h" - -#include +class ScriptRequest; namespace JSI_Debug { - int Crash(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - void DebugWarn(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - void DisplayErrorDialog(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& msg); - std::wstring GetBuildDate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - double GetBuildTimestamp(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - std::wstring GetBuildRevision(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - double GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); - - void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_DEBUG diff --git a/source/ps/scripting/JSInterface_Game.cpp b/source/ps/scripting/JSInterface_Game.cpp index 5fe84ba546..fdce7dbe22 100644 --- a/source/ps/scripting/JSInterface_Game.cpp +++ b/source/ps/scripting/JSInterface_Game.cpp @@ -27,17 +27,20 @@ #include "ps/GameSetup/GameSetup.h" #include "ps/Replay.h" #include "ps/World.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/system/TurnManager.h" #include "simulation2/Simulation2.h" #include "soundmanager/SoundManager.h" -bool JSI_Game::IsGameStarted(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +namespace JSI_Game +{ +bool IsGameStarted() { return g_Game; } -void JSI_Game::StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs, int playerID) +void StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs, int playerID) { ENSURE(!g_NetServer); ENSURE(!g_NetClient); @@ -56,12 +59,12 @@ void JSI_Game::StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleV g_Game->StartGame(&gameAttribs, ""); } -void JSI_Game::Script_EndGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void Script_EndGame() { EndGame(); } -int JSI_Game::GetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +int GetPlayerID() { if (!g_Game) return -1; @@ -69,7 +72,7 @@ int JSI_Game::GetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) return g_Game->GetPlayerID(); } -void JSI_Game::SetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int id) +void SetPlayerID(int id) { if (!g_Game) return; @@ -77,7 +80,7 @@ void JSI_Game::SetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), i g_Game->SetPlayerID(id); } -void JSI_Game::SetViewedPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int id) +void SetViewedPlayer(int id) { if (!g_Game) return; @@ -85,21 +88,20 @@ void JSI_Game::SetViewedPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate g_Game->SetViewedPlayerID(id); } -float JSI_Game::GetSimRate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +float GetSimRate() { return g_Game->GetSimRate(); } -void JSI_Game::SetSimRate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float rate) +void SetSimRate(float rate) { g_Game->SetSimRate(rate); } -bool JSI_Game::IsPaused(ScriptInterface::CmptPrivate* pCmptPrivate) +bool IsPaused(const ScriptRequest& rq) { if (!g_Game) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Game is not started"); return false; } @@ -107,11 +109,10 @@ bool JSI_Game::IsPaused(ScriptInterface::CmptPrivate* pCmptPrivate) return g_Game->m_Paused; } -void JSI_Game::SetPaused(ScriptInterface::CmptPrivate* pCmptPrivate, bool pause, bool sendMessage) +void SetPaused(const ScriptRequest& rq, bool pause, bool sendMessage) { if (!g_Game) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptException::Raise(rq, "Game is not started"); return; } @@ -130,7 +131,7 @@ void JSI_Game::SetPaused(ScriptInterface::CmptPrivate* pCmptPrivate, bool pause, g_NetClient->SendPausedMessage(pause); } -bool JSI_Game::IsVisualReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +bool IsVisualReplay() { if (!g_Game) return false; @@ -138,7 +139,7 @@ bool JSI_Game::IsVisualReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) return g_Game->IsVisualReplay(); } -std::wstring JSI_Game::GetCurrentReplayDirectory(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::wstring GetCurrentReplayDirectory() { if (!g_Game) return std::wstring(); @@ -149,17 +150,17 @@ std::wstring JSI_Game::GetCurrentReplayDirectory(ScriptInterface::CmptPrivate* U return g_Game->GetReplayLogger().GetDirectory().Filename().string(); } -void JSI_Game::EnableTimeWarpRecording(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), unsigned int numTurns) +void EnableTimeWarpRecording(unsigned int numTurns) { g_Game->GetTurnManager()->EnableTimeWarpRecording(numTurns); } -void JSI_Game::RewindTimeWarp(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void RewindTimeWarp() { g_Game->GetTurnManager()->RewindTimeWarp(); } -void JSI_Game::DumpTerrainMipmap(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void DumpTerrainMipmap() { VfsPath filename(L"screenshots/terrainmipmap.png"); g_Game->GetWorld()->GetTerrain()->GetHeightMipmap().DumpToDisk(filename); @@ -168,21 +169,22 @@ void JSI_Game::DumpTerrainMipmap(ScriptInterface::CmptPrivate* UNUSED(pCmptPriva LOGMESSAGERENDER("Terrain mipmap written to '%s'", realPath.string8()); } -void JSI_Game::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("IsGameStarted"); - scriptInterface.RegisterFunction("StartGame"); - scriptInterface.RegisterFunction("EndGame"); - scriptInterface.RegisterFunction("GetPlayerID"); - scriptInterface.RegisterFunction("SetPlayerID"); - scriptInterface.RegisterFunction("SetViewedPlayer"); - scriptInterface.RegisterFunction("GetSimRate"); - scriptInterface.RegisterFunction("SetSimRate"); - scriptInterface.RegisterFunction("IsPaused"); - scriptInterface.RegisterFunction("SetPaused"); - scriptInterface.RegisterFunction("IsVisualReplay"); - scriptInterface.RegisterFunction("GetCurrentReplayDirectory"); - scriptInterface.RegisterFunction("EnableTimeWarpRecording"); - scriptInterface.RegisterFunction("RewindTimeWarp"); - scriptInterface.RegisterFunction("DumpTerrainMipmap"); + ScriptFunction::Register<&IsGameStarted>(rq, "IsGameStarted"); + ScriptFunction::Register<&StartGame>(rq, "StartGame"); + ScriptFunction::Register<&Script_EndGame>(rq, "EndGame"); + ScriptFunction::Register<&GetPlayerID>(rq, "GetPlayerID"); + ScriptFunction::Register<&SetPlayerID>(rq, "SetPlayerID"); + ScriptFunction::Register<&SetViewedPlayer>(rq, "SetViewedPlayer"); + ScriptFunction::Register<&GetSimRate>(rq, "GetSimRate"); + ScriptFunction::Register<&SetSimRate>(rq, "SetSimRate"); + ScriptFunction::Register<&IsPaused>(rq, "IsPaused"); + ScriptFunction::Register<&SetPaused>(rq, "SetPaused"); + ScriptFunction::Register<&IsVisualReplay>(rq, "IsVisualReplay"); + ScriptFunction::Register<&GetCurrentReplayDirectory>(rq, "GetCurrentReplayDirectory"); + ScriptFunction::Register<&EnableTimeWarpRecording>(rq, "EnableTimeWarpRecording"); + ScriptFunction::Register<&RewindTimeWarp>(rq, "RewindTimeWarp"); + ScriptFunction::Register<&DumpTerrainMipmap>(rq, "DumpTerrainMipmap"); +} } diff --git a/source/ps/scripting/JSInterface_Game.h b/source/ps/scripting/JSInterface_Game.h index 69494eed24..cf83eaa9d5 100644 --- a/source/ps/scripting/JSInterface_Game.h +++ b/source/ps/scripting/JSInterface_Game.h @@ -18,27 +18,11 @@ #ifndef INCLUDED_JSI_GAME #define INCLUDED_JSI_GAME -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_Game { - bool IsGameStarted(ScriptInterface::CmptPrivate* pCmptPrivate); - void StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs, int playerID); - void Script_EndGame(ScriptInterface::CmptPrivate* pCmptPrivate); - int GetPlayerID(ScriptInterface::CmptPrivate* pCmptPrivate); - void SetPlayerID(ScriptInterface::CmptPrivate* pCmptPrivate, int id); - void SetViewedPlayer(ScriptInterface::CmptPrivate* pCmptPrivate, int id); - float GetSimRate(ScriptInterface::CmptPrivate* pCmptPrivate); - void SetSimRate(ScriptInterface::CmptPrivate* pCmptPrivate, float rate); - bool IsPaused(ScriptInterface::CmptPrivate* pCmptPrivate); - void SetPaused(ScriptInterface::CmptPrivate* pCmptPrivate, bool pause, bool sendMessage); - bool IsVisualReplay(ScriptInterface::CmptPrivate* pCmptPrivate); - std::wstring GetCurrentReplayDirectory(ScriptInterface::CmptPrivate* pCmptPrivate); - void RewindTimeWarp(ScriptInterface::CmptPrivate* pCmptPrivate); - void EnableTimeWarpRecording(ScriptInterface::CmptPrivate* pCmptPrivate, unsigned int numTurns); - void DumpTerrainMipmap(ScriptInterface::CmptPrivate* pCmptPrivate); - - void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_GAME diff --git a/source/ps/scripting/JSInterface_Main.cpp b/source/ps/scripting/JSInterface_Main.cpp index 3715cefec5..0a7a662162 100644 --- a/source/ps/scripting/JSInterface_Main.cpp +++ b/source/ps/scripting/JSInterface_Main.cpp @@ -30,50 +30,53 @@ #include "ps/Globals.h" #include "ps/Hotkey.h" #include "ps/Util.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "tools/atlas/GameInterface/GameLoop.h" extern void QuitEngine(); extern void StartAtlas(); -void JSI_Main::QuitEngine(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +namespace JSI_Main +{ +void QuitEngine() { ::QuitEngine(); } -void JSI_Main::StartAtlas(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void StartAtlas() { ::StartAtlas(); } -bool JSI_Main::AtlasIsAvailable(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +bool AtlasIsAvailable() { return ATLAS_IsAvailable(); } -bool JSI_Main::IsAtlasRunning(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +bool IsAtlasRunning() { return g_AtlasGameLoop && g_AtlasGameLoop->running; } -void JSI_Main::OpenURL(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& url) +void OpenURL(const std::string& url) { sys_open_url(url); } -std::wstring JSI_Main::GetSystemUsername(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::wstring GetSystemUsername() { return sys_get_user_name(); } -std::wstring JSI_Main::GetMatchID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::wstring GetMatchID() { return ps_generate_guid().FromUTF8(); } -JS::Value JSI_Main::LoadMapSettings(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& pathname) +JS::Value LoadMapSettings(const ScriptInterface& scriptInterface, const VfsPath& pathname) { - ScriptRequest rq(pCmptPrivate->pScriptInterface); + ScriptRequest rq(scriptInterface); CMapSummaryReader reader; @@ -81,18 +84,18 @@ JS::Value JSI_Main::LoadMapSettings(ScriptInterface::CmptPrivate* pCmptPrivate, return JS::UndefinedValue(); JS::RootedValue settings(rq.cx); - reader.GetMapSettings(*(pCmptPrivate->pScriptInterface), &settings); + reader.GetMapSettings(scriptInterface, &settings); return settings; } -bool JSI_Main::HotkeyIsPressed_(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& hotkeyName) +bool HotkeyIsPressed_(const std::string& hotkeyName) { return HotkeyIsPressed(hotkeyName); } // This value is recalculated once a frame. We take special care to // filter it, so it is both accurate and free of jitter. -int JSI_Main::GetFps(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +int GetFps() { if (!g_frequencyFilter) return 0; @@ -100,7 +103,7 @@ int JSI_Main::GetFps(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) return g_frequencyFilter->StableFrequency(); } -int JSI_Main::GetTextWidth(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& fontName, const std::wstring& text) +int GetTextWidth(const std::string& fontName, const std::wstring& text) { int width = 0; int height = 0; @@ -110,7 +113,7 @@ int JSI_Main::GetTextWidth(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), c return width; } -std::string JSI_Main::CalculateMD5(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& input) +std::string CalculateMD5(const std::string& input) { u8 digest[MD5::DIGESTSIZE]; @@ -121,18 +124,19 @@ std::string JSI_Main::CalculateMD5(ScriptInterface::CmptPrivate* UNUSED(pCmptPri return Hexify(digest, MD5::DIGESTSIZE); } -void JSI_Main::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("Exit"); - scriptInterface.RegisterFunction("RestartInAtlas"); - scriptInterface.RegisterFunction("AtlasIsAvailable"); - scriptInterface.RegisterFunction("IsAtlasRunning"); - scriptInterface.RegisterFunction("OpenURL"); - scriptInterface.RegisterFunction("GetSystemUsername"); - scriptInterface.RegisterFunction("GetMatchID"); - scriptInterface.RegisterFunction("LoadMapSettings"); - scriptInterface.RegisterFunction("HotkeyIsPressed"); - scriptInterface.RegisterFunction("GetFPS"); - scriptInterface.RegisterFunction("GetTextWidth"); - scriptInterface.RegisterFunction("CalculateMD5"); + ScriptFunction::Register<&QuitEngine>(rq, "Exit"); + ScriptFunction::Register<&StartAtlas>(rq, "RestartInAtlas"); + ScriptFunction::Register<&AtlasIsAvailable>(rq, "AtlasIsAvailable"); + ScriptFunction::Register<&IsAtlasRunning>(rq, "IsAtlasRunning"); + ScriptFunction::Register<&OpenURL>(rq, "OpenURL"); + ScriptFunction::Register<&GetSystemUsername>(rq, "GetSystemUsername"); + ScriptFunction::Register<&GetMatchID>(rq, "GetMatchID"); + ScriptFunction::Register<&LoadMapSettings>(rq, "LoadMapSettings"); + ScriptFunction::Register<&HotkeyIsPressed_>(rq, "HotkeyIsPressed"); + ScriptFunction::Register<&GetFps>(rq, "GetFPS"); + ScriptFunction::Register<&GetTextWidth>(rq, "GetTextWidth"); + ScriptFunction::Register<&CalculateMD5>(rq, "CalculateMD5"); +} } diff --git a/source/ps/scripting/JSInterface_Main.h b/source/ps/scripting/JSInterface_Main.h index 091f3aa8e2..4d4786e390 100644 --- a/source/ps/scripting/JSInterface_Main.h +++ b/source/ps/scripting/JSInterface_Main.h @@ -18,24 +18,11 @@ #ifndef INCLUDED_JSI_MAIN #define INCLUDED_JSI_MAIN -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_Main { - void QuitEngine(ScriptInterface::CmptPrivate* pCmptPrivate); - void StartAtlas(ScriptInterface::CmptPrivate* pCmptPrivate); - bool AtlasIsAvailable(ScriptInterface::CmptPrivate* pCmptPrivate); - bool IsAtlasRunning(ScriptInterface::CmptPrivate* pCmptPrivate); - void OpenURL(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& url); - std::wstring GetSystemUsername(ScriptInterface::CmptPrivate* pCmptPrivate); - std::wstring GetMatchID(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value LoadMapSettings(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& pathname); - bool HotkeyIsPressed_(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyName); - int GetFps(ScriptInterface::CmptPrivate* pCmptPrivate); - int GetTextWidth(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& fontName, const std::wstring& text); - std::string CalculateMD5(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& input); - - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_MAIN diff --git a/source/ps/scripting/JSInterface_ModIo.cpp b/source/ps/scripting/JSInterface_ModIo.cpp index 7387f8b01b..567ca2ffea 100644 --- a/source/ps/scripting/JSInterface_ModIo.cpp +++ b/source/ps/scripting/JSInterface_ModIo.cpp @@ -21,8 +21,21 @@ #include "ps/CLogger.h" #include "ps/ModIo.h" +#include "scriptinterface/FunctionWrapper.h" -void JSI_ModIo::StartGetGameId(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +namespace JSI_ModIo +{ +ModIo* ModIoGetter(const ScriptRequest&, JS::CallArgs&) +{ + if (!g_ModIo) + { + LOGERROR("Trying to access ModIO when it's not initialized!"); + return nullptr; + } + return g_ModIo; +} + +void StartGetGameId() { if (!g_ModIo) g_ModIo = new ModIo(); @@ -32,52 +45,8 @@ void JSI_ModIo::StartGetGameId(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate g_ModIo->StartGetGameId(); } -void JSI_ModIo::StartListMods(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - if (!g_ModIo) - { - LOGERROR("ModIoStartListMods called before ModIoStartGetGameId"); - return; - } - - g_ModIo->StartListMods(); -} - -void JSI_ModIo::StartDownloadMod(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), uint32_t idx) -{ - if (!g_ModIo) - { - LOGERROR("ModIoStartDownloadMod called before ModIoStartGetGameId"); - return; - } - - g_ModIo->StartDownloadMod(idx); -} - -bool JSI_ModIo::AdvanceRequest(ScriptInterface::CmptPrivate* pCmptPrivate) -{ - if (!g_ModIo) - { - LOGERROR("ModIoAdvanceRequest called before ModIoGetMods"); - return false; - } - - ScriptInterface* scriptInterface = pCmptPrivate->pScriptInterface; - return g_ModIo->AdvanceRequest(*scriptInterface); -} - -void JSI_ModIo::CancelRequest(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) -{ - if (!g_ModIo) - { - LOGERROR("ModIoCancelRequest called before ModIoGetMods"); - return; - } - - g_ModIo->CancelRequest(); -} - -JS::Value JSI_ModIo::GetMods(ScriptInterface::CmptPrivate* pCmptPrivate) +// TODO: could provide a FromJSVal for ModIoModData +JS::Value GetMods(const ScriptInterface& scriptInterface) { if (!g_ModIo) { @@ -85,7 +54,6 @@ JS::Value JSI_ModIo::GetMods(ScriptInterface::CmptPrivate* pCmptPrivate) return JS::NullValue(); } - ScriptInterface* scriptInterface = pCmptPrivate->pScriptInterface; ScriptRequest rq(scriptInterface); const std::vector& availableMods = g_ModIo->GetMods(); @@ -100,10 +68,10 @@ JS::Value JSI_ModIo::GetMods(ScriptInterface::CmptPrivate* pCmptPrivate) ScriptInterface::CreateObject(rq, &m); for (const std::pair& prop : mod.properties) - scriptInterface->SetProperty(m, prop.first.c_str(), prop.second, true); + scriptInterface.SetProperty(m, prop.first.c_str(), prop.second, true); - scriptInterface->SetProperty(m, "dependencies", mod.dependencies, true); - scriptInterface->SetPropertyInt(mods, i++, m); + scriptInterface.SetProperty(m, "dependencies", mod.dependencies, true); + scriptInterface.SetPropertyInt(mods, i++, m); } return mods; @@ -123,7 +91,8 @@ const std::map statusStrings = { { DownloadProgressStatus::FAILED_FILECHECK, "failed_filecheck" } }; -JS::Value JSI_ModIo::GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate) +// TODO: could provide a FromJSVal for DownloadProgressData +JS::Value GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate) { if (!g_ModIo) { @@ -145,13 +114,14 @@ JS::Value JSI_ModIo::GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPriv return progressData; } -void JSI_ModIo::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("ModIoStartGetGameId"); - scriptInterface.RegisterFunction("ModIoStartListMods"); - scriptInterface.RegisterFunction("ModIoStartDownloadMod"); - scriptInterface.RegisterFunction("ModIoAdvanceRequest"); - scriptInterface.RegisterFunction("ModIoCancelRequest"); - scriptInterface.RegisterFunction("ModIoGetMods"); - scriptInterface.RegisterFunction("ModIoGetDownloadProgress"); + ScriptFunction::Register<&StartGetGameId>(rq, "ModIoStartGetGameId"); + ScriptFunction::Register<&ModIo::StartListMods, &ModIoGetter>(rq, "ModIoStartListMods"); + ScriptFunction::Register<&ModIo::StartDownloadMod, &ModIoGetter>(rq, "ModIoStartDownloadMod"); + ScriptFunction::Register<&ModIo::AdvanceRequest, &ModIoGetter>(rq, "ModIoAdvanceRequest"); + ScriptFunction::Register<&ModIo::CancelRequest, &ModIoGetter>(rq, "ModIoCancelRequest"); + ScriptFunction::Register<&GetMods>(rq, "ModIoGetMods"); + ScriptFunction::Register<&GetDownloadProgress>(rq, "ModIoGetDownloadProgress"); +} } diff --git a/source/ps/scripting/JSInterface_ModIo.h b/source/ps/scripting/JSInterface_ModIo.h index 3bada14e71..87c4426708 100644 --- a/source/ps/scripting/JSInterface_ModIo.h +++ b/source/ps/scripting/JSInterface_ModIo.h @@ -18,19 +18,11 @@ #ifndef INCLUDED_JSI_MODIO #define INCLUDED_JSI_MODIO -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_ModIo { - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); - - void StartGetGameId(ScriptInterface::CmptPrivate* pCmptPrivate); - void StartListMods(ScriptInterface::CmptPrivate* pCmptPrivate); - void StartDownloadMod(ScriptInterface::CmptPrivate* pCmptPrivate, uint32_t idx); - bool AdvanceRequest(ScriptInterface::CmptPrivate* pCmptPrivate); - void CancelRequest(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value GetMods(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_MODIO diff --git a/source/ps/scripting/JSInterface_SavedGame.cpp b/source/ps/scripting/JSInterface_SavedGame.cpp index 7173c61f03..a78aadf82e 100644 --- a/source/ps/scripting/JSInterface_SavedGame.cpp +++ b/source/ps/scripting/JSInterface_SavedGame.cpp @@ -24,35 +24,38 @@ #include "ps/CLogger.h" #include "ps/Game.h" #include "ps/SavedGame.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" #include "simulation2/system/TurnManager.h" -JS::Value JSI_SavedGame::GetSavedGames(ScriptInterface::CmptPrivate* pCmptPrivate) +namespace JSI_SavedGame { - return SavedGames::GetSavedGames(*(pCmptPrivate->pScriptInterface)); +JS::Value GetSavedGames(const ScriptInterface& scriptInterface) +{ + return SavedGames::GetSavedGames(scriptInterface); } -bool JSI_SavedGame::DeleteSavedGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name) +bool DeleteSavedGame(const std::wstring& name) { return SavedGames::DeleteSavedGame(name); } -void JSI_SavedGame::SaveGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata) +void SaveGame(const ScriptInterface& scriptInterface, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata) { - ScriptInterface::StructuredClone GUIMetadataClone = pCmptPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); + ScriptInterface::StructuredClone GUIMetadataClone = scriptInterface.WriteStructuredClone(GUIMetadata); if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) LOGERROR("Failed to save game"); } -void JSI_SavedGame::SaveGamePrefix(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata) +void SaveGamePrefix(const ScriptInterface& scriptInterface, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata) { - ScriptInterface::StructuredClone GUIMetadataClone = pCmptPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); + ScriptInterface::StructuredClone GUIMetadataClone = scriptInterface.WriteStructuredClone(GUIMetadata); if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) LOGERROR("Failed to save game"); } -void JSI_SavedGame::QuickSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), JS::HandleValue GUIMetadata) +void QuickSave(JS::HandleValue GUIMetadata) { if (g_NetServer || g_NetClient) LOGERROR("Can't store quicksave during multiplayer!"); @@ -62,7 +65,7 @@ void JSI_SavedGame::QuickSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) LOGERROR("Can't store quicksave if game is not running!"); } -void JSI_SavedGame::QuickLoad(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void QuickLoad() { if (g_NetServer || g_NetClient) LOGERROR("Can't load quicksave during multiplayer!"); @@ -72,13 +75,13 @@ void JSI_SavedGame::QuickLoad(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) LOGERROR("Can't load quicksave if game is not running!"); } -JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name) +JS::Value StartSavedGame(const ScriptInterface& scriptInterface, const std::wstring& name) { // We need to be careful with different compartments and contexts. // The GUI calls this function from the GUI context and expects the return value in the same context. // The game we start from here creates another context and expects data in this context. - ScriptRequest rqGui(pCmptPrivate->pScriptInterface); + ScriptRequest rqGui(scriptInterface); ENSURE(!g_NetServer); ENSURE(!g_NetClient); @@ -88,7 +91,7 @@ JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPriva // Load the saved game data from disk JS::RootedValue guiContextMetadata(rqGui.cx); std::string savedState; - Status err = SavedGames::Load(name, *(pCmptPrivate->pScriptInterface), &guiContextMetadata, savedState); + Status err = SavedGames::Load(name, scriptInterface, &guiContextMetadata, savedState); if (err < 0) return JS::UndefinedValue(); @@ -99,7 +102,7 @@ JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPriva ScriptRequest rqGame(sim->GetScriptInterface()); JS::RootedValue gameContextMetadata(rqGame.cx, - sim->GetScriptInterface().CloneValueFromOtherCompartment(*(pCmptPrivate->pScriptInterface), guiContextMetadata)); + sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, guiContextMetadata)); JS::RootedValue gameInitAttributes(rqGame.cx); sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes); @@ -113,21 +116,22 @@ JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPriva return guiContextMetadata; } -void ActivateRejoinTest(ScriptInterface::CmptPrivate*) +void ActivateRejoinTest() { if (!g_Game || !g_Game->GetSimulation2() || !g_Game->GetTurnManager()) return; g_Game->GetSimulation2()->ActivateRejoinTest(g_Game->GetTurnManager()->GetCurrentTurn() + 1); } -void JSI_SavedGame::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("GetSavedGames"); - scriptInterface.RegisterFunction("DeleteSavedGame"); - scriptInterface.RegisterFunction("SaveGame"); - scriptInterface.RegisterFunction("SaveGamePrefix"); - scriptInterface.RegisterFunction("QuickSave"); - scriptInterface.RegisterFunction("QuickLoad"); - scriptInterface.RegisterFunction("ActivateRejoinTest"); - scriptInterface.RegisterFunction("StartSavedGame"); + ScriptFunction::Register<&GetSavedGames>(rq, "GetSavedGames"); + ScriptFunction::Register<&DeleteSavedGame>(rq, "DeleteSavedGame"); + ScriptFunction::Register<&SaveGame>(rq, "SaveGame"); + ScriptFunction::Register<&SaveGamePrefix>(rq, "SaveGamePrefix"); + ScriptFunction::Register<&QuickSave>(rq, "QuickSave"); + ScriptFunction::Register<&QuickLoad>(rq, "QuickLoad"); + ScriptFunction::Register<&ActivateRejoinTest>(rq, "ActivateRejoinTest"); + ScriptFunction::Register<&StartSavedGame>(rq, "StartSavedGame"); +} } diff --git a/source/ps/scripting/JSInterface_SavedGame.h b/source/ps/scripting/JSInterface_SavedGame.h index 4260ca46e6..96b58c4061 100644 --- a/source/ps/scripting/JSInterface_SavedGame.h +++ b/source/ps/scripting/JSInterface_SavedGame.h @@ -18,19 +18,11 @@ #ifndef INCLUDED_JSI_SAVEDGAME #define INCLUDED_JSI_SAVEDGAME -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_SavedGame { - JS::Value GetSavedGames(ScriptInterface::CmptPrivate* pCmptPrivate); - bool DeleteSavedGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name); - void SaveGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata); - void SaveGamePrefix(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata); - void QuickSave(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue GUIMetadata); - void QuickLoad(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value StartSavedGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name); - - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_SAVEDGAME diff --git a/source/ps/scripting/JSInterface_UserReport.cpp b/source/ps/scripting/JSInterface_UserReport.cpp index 45dd680ce8..a384f25dec 100644 --- a/source/ps/scripting/JSInterface_UserReport.cpp +++ b/source/ps/scripting/JSInterface_UserReport.cpp @@ -22,42 +22,46 @@ #include "ps/Filesystem.h" #include "ps/Pyrogenesis.h" #include "ps/UserReport.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include -bool JSI_UserReport::IsUserReportEnabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +namespace JSI_UserReport +{ +bool IsUserReportEnabled() { return g_UserReporter.IsReportingEnabled(); } -void JSI_UserReport::SetUserReportEnabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool enabled) +void SetUserReportEnabled(bool enabled) { g_UserReporter.SetReportingEnabled(enabled); } -std::string JSI_UserReport::GetUserReportStatus(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::string GetUserReportStatus() { return g_UserReporter.GetStatus(); } -std::string JSI_UserReport::GetUserReportLogPath(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::string GetUserReportLogPath() { return psLogDir().string8(); } -std::string JSI_UserReport::GetUserReportConfigPath(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::string GetUserReportConfigPath() { OsPath configPath; WARN_IF_ERR(g_VFS->GetDirectoryRealPath("config/", configPath)); return configPath.string8(); } -void JSI_UserReport::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("IsUserReportEnabled"); - scriptInterface.RegisterFunction("SetUserReportEnabled"); - scriptInterface.RegisterFunction("GetUserReportStatus"); - scriptInterface.RegisterFunction("GetUserReportLogPath"); - scriptInterface.RegisterFunction("GetUserReportConfigPath"); + ScriptFunction::Register<&IsUserReportEnabled>(rq, "IsUserReportEnabled"); + ScriptFunction::Register<&SetUserReportEnabled>(rq, "SetUserReportEnabled"); + ScriptFunction::Register<&GetUserReportStatus>(rq, "GetUserReportStatus"); + ScriptFunction::Register<&GetUserReportLogPath>(rq, "GetUserReportLogPath"); + ScriptFunction::Register<&GetUserReportConfigPath>(rq, "GetUserReportConfigPath"); +} } diff --git a/source/ps/scripting/JSInterface_UserReport.h b/source/ps/scripting/JSInterface_UserReport.h index 4e6f104bcf..808259a002 100644 --- a/source/ps/scripting/JSInterface_UserReport.h +++ b/source/ps/scripting/JSInterface_UserReport.h @@ -18,19 +18,11 @@ #ifndef INCLUDED_JSI_USERREPORT #define INCLUDED_JSI_USERREPORT -#include "scriptinterface/ScriptInterface.h" - -#include +class ScriptRequest; namespace JSI_UserReport { - bool IsUserReportEnabled(ScriptInterface::CmptPrivate* pCmptPrivate); - void SetUserReportEnabled(ScriptInterface::CmptPrivate* pCmptPrivate, bool enabled); - std::string GetUserReportStatus(ScriptInterface::CmptPrivate* pCmptPrivate); - std::string GetUserReportLogPath(ScriptInterface::CmptPrivate* pCmptPrivate); - std::string GetUserReportConfigPath(ScriptInterface::CmptPrivate* pCmptPrivate); - - void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_USERREPORT diff --git a/source/ps/scripting/JSInterface_VFS.cpp b/source/ps/scripting/JSInterface_VFS.cpp index 689793bd14..c7ef580640 100644 --- a/source/ps/scripting/JSInterface_VFS.cpp +++ b/source/ps/scripting/JSInterface_VFS.cpp @@ -23,11 +23,14 @@ #include "ps/CLogger.h" #include "ps/CStr.h" #include "ps/Filesystem.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptExtraHeaders.h" #include "scriptinterface/ScriptInterface.h" #include +namespace JSI_VFS +{ // Only allow engine compartments to read files they may be concerned about. #define PathRestriction_GUI {L""} #define PathRestriction_Simulation {L"simulation/"} @@ -46,19 +49,40 @@ /* else: success */ +// Tests whether the current script context is allowed to read from the given directory +bool PathRestrictionMet(const ScriptRequest& rq, const std::vector& validPaths, const CStrW& filePath) +{ + for (const CStrW& validPath : validPaths) + if (filePath.find(validPath) == 0) + return true; + + CStrW allowedPaths; + for (std::size_t i = 0; i < validPaths.size(); ++i) + { + if (i != 0) + allowedPaths += L", "; + + allowedPaths += L"\"" + validPaths[i] + L"\""; + } + + ScriptException::Raise(rq, "This part of the engine may only read from %s!", utf8_from_wstring(allowedPaths).c_str()); + + return false; +} + + // state held across multiple BuildDirEntListCB calls; init by BuildDirEntList. struct BuildDirEntListState { - ScriptInterface* pScriptInterface; + const ScriptRequest& rq; JS::PersistentRootedObject filename_array; int cur_idx; - BuildDirEntListState(ScriptInterface* scriptInterface) - : pScriptInterface(scriptInterface), - filename_array(scriptInterface->GetGeneralJSContext()), + BuildDirEntListState(const ScriptRequest& rq) + : rq(rq), + filename_array(rq.cx), cur_idx(0) { - ScriptRequest rq(pScriptInterface); filename_array = JS::NewArrayObject(rq.cx, JS::HandleValueArray::empty()); } }; @@ -67,12 +91,11 @@ struct BuildDirEntListState static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData) { BuildDirEntListState* s = (BuildDirEntListState*)cbData; - ScriptRequest rq(s->pScriptInterface); - JS::RootedObject filenameArrayObj(rq.cx, s->filename_array); - JS::RootedValue val(rq.cx); - ScriptInterface::ToJSVal(rq, &val, CStrW(pathname.string()) ); - JS_SetElement(rq.cx, filenameArrayObj, s->cur_idx++, val); + JS::RootedObject filenameArrayObj(s->rq.cx, s->filename_array); + JS::RootedValue val(s->rq.cx); + ScriptInterface::ToJSVal(s->rq, &val, CStrW(pathname.string()) ); + JS_SetElement(s->rq.cx, filenameArrayObj, s->cur_idx++, val); return INFO::OK; } @@ -81,9 +104,9 @@ static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED // specified directory. // filter_string: default "" matches everything; otherwise, see vfs_next_dirent. // recurse: should subdirectories be included in the search? default false. -JS::Value JSI_VFS::BuildDirEntList(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const std::wstring& path, const std::wstring& filterStr, bool recurse) +JS::Value BuildDirEntList(const ScriptRequest& rq, const std::vector& validPaths, const std::wstring& path, const std::wstring& filterStr, bool recurse) { - if (!PathRestrictionMet(pCmptPrivate, validPaths, path)) + if (!PathRestrictionMet(rq, validPaths, path)) return JS::NullValue(); // convert to const wchar_t*; if there's no filter, pass 0 for speed @@ -95,20 +118,20 @@ JS::Value JSI_VFS::BuildDirEntList(ScriptInterface::CmptPrivate* pCmptPrivate, c int flags = recurse ? vfs::DIR_RECURSIVE : 0; // build array in the callback function - BuildDirEntListState state(pCmptPrivate->pScriptInterface); + BuildDirEntListState state(rq); vfs::ForEachFile(g_VFS, path, BuildDirEntListCB, (uintptr_t)&state, filter, flags); return JS::ObjectValue(*state.filename_array); } // Return true iff the file exits -bool JSI_VFS::FileExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const CStrW& filename) +bool FileExists(const ScriptRequest& rq, const std::vector& validPaths, const CStrW& filename) { - return PathRestrictionMet(pCmptPrivate, validPaths, filename) && g_VFS->GetFileInfo(filename, 0) == INFO::OK; + return PathRestrictionMet(rq, validPaths, filename) && g_VFS->GetFileInfo(filename, 0) == INFO::OK; } // Return time [seconds since 1970] of the last modification to the specified file. -double JSI_VFS::GetFileMTime(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) +double GetFileMTime(const std::wstring& filename) { CFileInfo fileInfo; Status err = g_VFS->GetFileInfo(filename, &fileInfo); @@ -118,7 +141,7 @@ double JSI_VFS::GetFileMTime(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), } // Return current size of file. -unsigned int JSI_VFS::GetFileSize(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) +unsigned int GetFileSize(const std::wstring& filename) { CFileInfo fileInfo; Status err = g_VFS->GetFileInfo(filename, &fileInfo); @@ -128,7 +151,7 @@ unsigned int JSI_VFS::GetFileSize(ScriptInterface::CmptPrivate* UNUSED(pCmptPriv } // Return file contents in a string. Assume file is UTF-8 encoded text. -JS::Value JSI_VFS::ReadFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename) +JS::Value ReadFile(const ScriptRequest& rq, const std::wstring& filename) { CVFSFile file; if (file.Load(g_VFS, filename) != PSRETURN_OK) @@ -140,14 +163,13 @@ JS::Value JSI_VFS::ReadFile(ScriptInterface::CmptPrivate* pCmptPrivate, const st contents.Replace("\r\n", "\n"); // Decode as UTF-8 - ScriptRequest rq(pCmptPrivate->pScriptInterface); JS::RootedValue ret(rq.cx); ScriptInterface::ToJSVal(rq, &ret, contents.FromUTF8()); return ret; } // Return file contents as an array of lines. Assume file is UTF-8 encoded text. -JS::Value JSI_VFS::ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename) +JS::Value ReadFileLines(const ScriptInterface& scriptInterface, const std::wstring& filename) { CVFSFile file; if (file.Load(g_VFS, filename) != PSRETURN_OK) @@ -161,7 +183,6 @@ JS::Value JSI_VFS::ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, con // split into array of strings (one per line) std::stringstream ss(contents); - const ScriptInterface& scriptInterface = *pCmptPrivate->pScriptInterface; ScriptRequest rq(scriptInterface); JS::RootedValue line_array(rq.cx); @@ -181,21 +202,21 @@ JS::Value JSI_VFS::ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, con return line_array; } -JS::Value JSI_VFS::ReadJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const CStrW& filePath) +// Return file contents parsed as a JS Object +JS::Value ReadJSONFile(const ScriptInterface& scriptInterface, const std::vector& validPaths, const CStrW& filePath) { - if (!PathRestrictionMet(pCmptPrivate, validPaths, filePath)) + ScriptRequest rq(scriptInterface); + if (!PathRestrictionMet(rq, validPaths, filePath)) return JS::NullValue(); - const ScriptInterface& scriptInterface = *pCmptPrivate->pScriptInterface; - ScriptRequest rq(scriptInterface); JS::RootedValue out(rq.cx); scriptInterface.ReadJSONFile(filePath, &out); return out; } -void JSI_VFS::WriteJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath, JS::HandleValue val1) +// Save given JS Object to a JSON file +void WriteJSONFile(const ScriptInterface& scriptInterface, const std::wstring& filePath, JS::HandleValue val1) { - const ScriptInterface& scriptInterface = *pCmptPrivate->pScriptInterface; ScriptRequest rq(scriptInterface); // TODO: This is a workaround because we need to pass a MutableHandle to StringifyJSON. @@ -209,7 +230,7 @@ void JSI_VFS::WriteJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const st g_VFS->CreateFile(path, buf.Data(), buf.Size()); } -bool JSI_VFS::DeleteCampaignSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& filePath) +bool DeleteCampaignSave(const CStrW& filePath) { OsPath realPath; if (filePath.Left(16) != L"saves/campaigns/" || filePath.Right(12) != L".0adcampaign") @@ -221,39 +242,18 @@ bool JSI_VFS::DeleteCampaignSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPriva wunlink(realPath) == 0; } -bool JSI_VFS::PathRestrictionMet(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const CStrW& filePath) -{ - for (const CStrW& validPath : validPaths) - if (filePath.find(validPath) == 0) - return true; - - CStrW allowedPaths; - for (std::size_t i = 0; i < validPaths.size(); ++i) - { - if (i != 0) - allowedPaths += L", "; - - allowedPaths += L"\"" + validPaths[i] + L"\""; - } - - ScriptRequest rq(pCmptPrivate->pScriptInterface); - ScriptException::Raise(rq, "This part of the engine may only read from %s!", utf8_from_wstring(allowedPaths).c_str()); - - return false; -} - #define VFS_ScriptFunctions(context)\ -JS::Value Script_ReadJSONFile_##context(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath)\ +JS::Value Script_ReadJSONFile_##context(const ScriptInterface& scriptInterface, const std::wstring& filePath)\ {\ - return JSI_VFS::ReadJSONFile(pCmptPrivate, PathRestriction_##context, filePath);\ + return ReadJSONFile(scriptInterface, PathRestriction_##context, filePath);\ }\ -JS::Value Script_ListDirectoryFiles_##context(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& path, const std::wstring& filterStr, bool recurse)\ +JS::Value Script_ListDirectoryFiles_##context(const ScriptInterface& scriptInterface, const std::wstring& path, const std::wstring& filterStr, bool recurse)\ {\ - return JSI_VFS::BuildDirEntList(pCmptPrivate, PathRestriction_##context, path, filterStr, recurse);\ + return BuildDirEntList(scriptInterface, PathRestriction_##context, path, filterStr, recurse);\ }\ -bool Script_FileExists_##context(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath)\ +bool Script_FileExists_##context(const ScriptInterface& scriptInterface, const std::wstring& filePath)\ {\ - return JSI_VFS::FileExists(pCmptPrivate, PathRestriction_##context, filePath);\ + return FileExists(scriptInterface, PathRestriction_##context, filePath);\ }\ VFS_ScriptFunctions(GUI); @@ -261,29 +261,30 @@ VFS_ScriptFunctions(Simulation); VFS_ScriptFunctions(Maps); #undef VFS_ScriptFunctions -void JSI_VFS::RegisterScriptFunctions_GUI(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions_GUI(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("ListDirectoryFiles"); - scriptInterface.RegisterFunction("FileExists"); - scriptInterface.RegisterFunction("GetFileMTime"); - scriptInterface.RegisterFunction("GetFileSize"); - scriptInterface.RegisterFunction("ReadFile"); - scriptInterface.RegisterFunction("ReadFileLines"); - scriptInterface.RegisterFunction("ReadJSONFile"); - scriptInterface.RegisterFunction("WriteJSONFile"); - scriptInterface.RegisterFunction("DeleteCampaignSave"); + ScriptFunction::Register<&Script_ListDirectoryFiles_GUI>(rq, "ListDirectoryFiles"); + ScriptFunction::Register<&Script_FileExists_GUI>(rq, "FileExists"); + ScriptFunction::Register<&GetFileMTime>(rq, "GetFileMTime"); + ScriptFunction::Register<&GetFileSize>(rq, "GetFileSize"); + ScriptFunction::Register<&ReadFile>(rq, "ReadFile"); + ScriptFunction::Register<&ReadFileLines>(rq, "ReadFileLines"); + ScriptFunction::Register<&Script_ReadJSONFile_GUI>(rq, "ReadJSONFile"); + ScriptFunction::Register<&WriteJSONFile>(rq, "WriteJSONFile"); + ScriptFunction::Register<&DeleteCampaignSave>(rq, "DeleteCampaignSave"); } -void JSI_VFS::RegisterScriptFunctions_Simulation(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions_Simulation(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("ListDirectoryFiles"); - scriptInterface.RegisterFunction("FileExists"); - scriptInterface.RegisterFunction("ReadJSONFile"); + ScriptFunction::Register<&Script_ListDirectoryFiles_Simulation>(rq, "ListDirectoryFiles"); + ScriptFunction::Register<&Script_FileExists_Simulation>(rq, "FileExists"); + ScriptFunction::Register<&Script_ReadJSONFile_Simulation>(rq, "ReadJSONFile"); } -void JSI_VFS::RegisterScriptFunctions_Maps(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions_Maps(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("ListDirectoryFiles"); - scriptInterface.RegisterFunction("FileExists"); - scriptInterface.RegisterFunction("ReadJSONFile"); + ScriptFunction::Register<&Script_ListDirectoryFiles_Maps>(rq, "ListDirectoryFiles"); + ScriptFunction::Register<&Script_FileExists_Maps>(rq, "FileExists"); + ScriptFunction::Register<&Script_ReadJSONFile_Maps>(rq, "ReadJSONFile"); +} } diff --git a/source/ps/scripting/JSInterface_VFS.h b/source/ps/scripting/JSInterface_VFS.h index 5bbf903960..4e1d700296 100644 --- a/source/ps/scripting/JSInterface_VFS.h +++ b/source/ps/scripting/JSInterface_VFS.h @@ -18,45 +18,13 @@ #ifndef INCLUDED_JSI_VFS #define INCLUDED_JSI_VFS -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_VFS { - // Return an array of pathname strings, one for each matching entry in the - // specified directory. - JS::Value BuildDirEntList(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const std::wstring& path, const std::wstring& filterStr, bool recurse); - - // Return true iff the file exists - bool FileExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const CStrW& filename); - - // Return time [seconds since 1970] of the last modification to the specified file. - double GetFileMTime(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename); - - // Return current size of file. - unsigned int GetFileSize(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename); - - // Return file contents in a string. - JS::Value ReadFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename); - - // Return file contents as an array of lines. - JS::Value ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename); - - // Return file contents parsed as a JS Object - JS::Value ReadJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const CStrW& filePath); - - // Save given JS Object to a JSON file - void WriteJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath, JS::HandleValue val1); - - // Delete the given campaign save. - // This is limited to campaign save to avoid mods deleting the wrong file. - bool DeleteCampaignSave(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& filePath); - - // Tests whether the current script context is allowed to read from the given directory - bool PathRestrictionMet(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector& validPaths, const CStrW& filePath); - - void RegisterScriptFunctions_GUI(const ScriptInterface& scriptInterface); - void RegisterScriptFunctions_Simulation(const ScriptInterface& scriptInterface); - void RegisterScriptFunctions_Maps(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions_GUI(const ScriptRequest& rq); + void RegisterScriptFunctions_Simulation(const ScriptRequest& rq); + void RegisterScriptFunctions_Maps(const ScriptRequest& rq); } #endif // INCLUDED_JSI_VFS diff --git a/source/ps/scripting/JSInterface_VisualReplay.cpp b/source/ps/scripting/JSInterface_VisualReplay.cpp index 2689d1fcc0..c08753bdf9 100644 --- a/source/ps/scripting/JSInterface_VisualReplay.cpp +++ b/source/ps/scripting/JSInterface_VisualReplay.cpp @@ -21,56 +21,25 @@ #include "ps/CStr.h" #include "ps/VisualReplay.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" -bool JSI_VisualReplay::StartVisualReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& directory) +namespace JSI_VisualReplay { - return VisualReplay::StartVisualReplay(directory); +CStrW GetReplayDirectoryName(const CStrW& directoryName) +{ + return OsPath(VisualReplay::GetDirectoryPath() / directoryName).string(); } -bool JSI_VisualReplay::DeleteReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& replayFile) +void RegisterScriptFunctions(const ScriptRequest& rq) { - return VisualReplay::DeleteReplay(replayFile); + ScriptFunction::Register<&VisualReplay::GetReplays>(rq, "GetReplays"); + ScriptFunction::Register<&VisualReplay::DeleteReplay>(rq, "DeleteReplay"); + ScriptFunction::Register<&VisualReplay::StartVisualReplay>(rq, "StartVisualReplay"); + ScriptFunction::Register<&VisualReplay::GetReplayAttributes>(rq, "GetReplayAttributes"); + ScriptFunction::Register<&VisualReplay::GetReplayMetadata>(rq, "GetReplayMetadata"); + ScriptFunction::Register<&VisualReplay::HasReplayMetadata>(rq, "HasReplayMetadata"); + ScriptFunction::Register<&VisualReplay::AddReplayToCache>(rq, "AddReplayToCache"); + ScriptFunction::Register<&GetReplayDirectoryName>(rq, "GetReplayDirectoryName"); } - -JS::Value JSI_VisualReplay::GetReplays(ScriptInterface::CmptPrivate* pCmptPrivate, bool compareFiles) -{ - return VisualReplay::GetReplays(*(pCmptPrivate->pScriptInterface), compareFiles); -} - -JS::Value JSI_VisualReplay::GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName) -{ - return VisualReplay::GetReplayAttributes(pCmptPrivate, directoryName); -} - -bool JSI_VisualReplay::HasReplayMetadata(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& directoryName) -{ - return VisualReplay::HasReplayMetadata(directoryName); -} - -JS::Value JSI_VisualReplay::GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName) -{ - return VisualReplay::GetReplayMetadata(pCmptPrivate, directoryName); -} - -void JSI_VisualReplay::AddReplayToCache(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName) -{ - VisualReplay::AddReplayToCache(*(pCmptPrivate->pScriptInterface), directoryName); -} - -CStrW JSI_VisualReplay::GetReplayDirectoryName(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& directoryName) -{ - return wstring_from_utf8(OsPath(VisualReplay::GetDirectoryPath() / directoryName).string8()); -} - -void JSI_VisualReplay::RegisterScriptFunctions(const ScriptInterface& scriptInterface) -{ - scriptInterface.RegisterFunction("GetReplays"); - scriptInterface.RegisterFunction("DeleteReplay"); - scriptInterface.RegisterFunction("StartVisualReplay"); - scriptInterface.RegisterFunction("GetReplayAttributes"); - scriptInterface.RegisterFunction("GetReplayMetadata"); - scriptInterface.RegisterFunction("HasReplayMetadata"); - scriptInterface.RegisterFunction("AddReplayToCache"); - scriptInterface.RegisterFunction("GetReplayDirectoryName"); } diff --git a/source/ps/scripting/JSInterface_VisualReplay.h b/source/ps/scripting/JSInterface_VisualReplay.h index fa126379b6..bb13477ef0 100644 --- a/source/ps/scripting/JSInterface_VisualReplay.h +++ b/source/ps/scripting/JSInterface_VisualReplay.h @@ -18,19 +18,11 @@ #ifndef INCLUDED_JSI_VISUALREPLAY #define INCLUDED_JSI_VISUALREPLAY -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_VisualReplay { - bool StartVisualReplay(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directory); - bool DeleteReplay(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& replayFile); - JS::Value GetReplays(ScriptInterface::CmptPrivate* pCmptPrivate, bool compareFiles); - JS::Value GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName); - bool HasReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName); - JS::Value GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName); - void AddReplayToCache(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName); - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); - CStrW GetReplayDirectoryName(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_VISUALREPLAY diff --git a/source/renderer/scripting/JSInterface_Renderer.cpp b/source/renderer/scripting/JSInterface_Renderer.cpp index 0bd5f30811..5d83138a15 100644 --- a/source/renderer/scripting/JSInterface_Renderer.cpp +++ b/source/renderer/scripting/JSInterface_Renderer.cpp @@ -22,15 +22,17 @@ #include "graphics/TextureManager.h" #include "renderer/RenderingOptions.h" #include "renderer/Renderer.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" +namespace JSI_Renderer +{ #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \ -bool Get##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) \ +bool Get##NAME##Enabled() \ { \ -return g_RenderingOptions.Get##NAME(); \ + return g_RenderingOptions.Get##NAME(); \ } \ \ -void Set##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool enabled) \ +void Set##NAME##Enabled(bool enabled) \ { \ g_RenderingOptions.Set##NAME(enabled); \ } @@ -40,26 +42,27 @@ IMPLEMENT_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum); #undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING -std::string JSI_Renderer::GetRenderPath(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::string GetRenderPath() { return RenderPathEnum::ToString(g_RenderingOptions.GetRenderPath()); } -bool JSI_Renderer::TextureExists(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) +bool TextureExists(const std::wstring& filename) { return g_Renderer.GetTextureManager().TextureExists(filename); } #define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \ -scriptInterface.RegisterFunction("Renderer_Get" #NAME "Enabled"); \ -scriptInterface.RegisterFunction("Renderer_Set" #NAME "Enabled"); +ScriptFunction::Register<&Get##NAME##Enabled>(rq, "Renderer_Get" #NAME "Enabled"); \ +ScriptFunction::Register<&Set##NAME##Enabled>(rq, "Renderer_Set" #NAME "Enabled"); -void JSI_Renderer::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("Renderer_GetRenderPath"); - scriptInterface.RegisterFunction("TextureExists"); + ScriptFunction::Register<&GetRenderPath>(rq, "Renderer_GetRenderPath"); + ScriptFunction::Register<&TextureExists>(rq, "TextureExists"); REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayFrustum); REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum); } #undef REGISTER_BOOLEAN_SCRIPT_SETTING +} diff --git a/source/renderer/scripting/JSInterface_Renderer.h b/source/renderer/scripting/JSInterface_Renderer.h index faf295f322..325bcf736e 100644 --- a/source/renderer/scripting/JSInterface_Renderer.h +++ b/source/renderer/scripting/JSInterface_Renderer.h @@ -18,16 +18,11 @@ #ifndef INCLUDED_JSINTERFACE_RENDERER #define INCLUDED_JSINTERFACE_RENDERER -#include "scriptinterface/ScriptInterface.h" +class ScriptRequest; namespace JSI_Renderer { - std::string GetRenderPath(ScriptInterface::CmptPrivate* pCmptPrivate); - bool TextureExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename); - - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } -#undef DECLARE_BOOLEAN_SCRIPT_SETTING - #endif // INCLUDED_JSINTERFACE_RENDERER diff --git a/source/scriptinterface/NativeWrapperDecls.h b/source/scriptinterface/NativeWrapperDecls.h index eab5144301..c27f9ece2b 100644 --- a/source/scriptinterface/NativeWrapperDecls.h +++ b/source/scriptinterface/NativeWrapperDecls.h @@ -56,16 +56,6 @@ template struct MaybeRef; #define T0_TAIL_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL_MAYBE_REF, T) // ", const T0&, T1" #define A0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, a) // ", a0, a1" -// Define RegisterFunction -#define OVERLOADS(z, i, data) \ - template \ - void RegisterFunction(const char* name) const \ - { \ - Register(name, call, nargs()); \ - } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS - // JSFastNative-compatible function that wraps the function identified in the template argument list // (Definition comes later, since it depends on some things we haven't defined yet) #define OVERLOADS(z, i, data) \ diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index f9c244a3c2..6e6248d018 100644 --- a/source/scriptinterface/ScriptInterface.cpp +++ b/source/scriptinterface/ScriptInterface.cpp @@ -17,6 +17,7 @@ #include "precompiled.h" +#include "FunctionWrapper.h" #include "ScriptContext.h" #include "ScriptExtraHeaders.h" #include "ScriptInterface.h" @@ -55,7 +56,6 @@ struct ScriptInterface_impl { ScriptInterface_impl(const char* nativeScopeName, const shared_ptr& context); ~ScriptInterface_impl(); - void Register(const char* name, JSNative fptr, uint nargs) const; // Take care to keep this declaration before heap rooted members. Destructors of heap rooted // members have to be called before the context destructor. @@ -176,107 +176,77 @@ bool error(JSContext* cx, uint argc, JS::Value* vp) return true; } -bool deepcopy(JSContext* cx, uint argc, JS::Value* vp) +JS::Value deepcopy(const ScriptRequest& rq, JS::HandleValue val) { - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - if (args.length() < 1) + if (val.isNullOrUndefined()) { - args.rval().setUndefined(); - return true; + ScriptException::Raise(rq, "deepcopy requires one argument."); + return JS::UndefinedValue(); } - ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ - JS::RootedValue ret(cx); - if (!JS_StructuredClone(rq.cx, args[0], &ret, NULL, NULL)) - return false; - - args.rval().set(ret); - return true; + JS::RootedValue ret(rq.cx); + if (!JS_StructuredClone(rq.cx, val, &ret, NULL, NULL)) + { + ScriptException::Raise(rq, "deepcopy StructureClone copy failed."); + return JS::UndefinedValue(); + } + return ret; } -bool deepfreeze(JSContext* cx, uint argc, JS::Value* vp) +JS::Value deepfreeze(const ScriptInterface& scriptInterface, JS::HandleValue val) { - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ - - if (args.length() != 1 || !args.get(0).isObject()) + ScriptRequest rq(scriptInterface); + if (!val.isObject()) { ScriptException::Raise(rq, "deepfreeze requires exactly one object as an argument."); - return false; + return JS::UndefinedValue(); } - ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface->FreezeObject(args.get(0), true); - args.rval().set(args.get(0)); - return true; + scriptInterface.FreezeObject(val, true); + return val; } -bool ProfileStart(JSContext* cx, uint argc, JS::Value* vp) +void ProfileStart(const std::string& regionName) { const char* name = "(ProfileStart)"; - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ - if (args.length() >= 1) - { - std::string str; - if (!ScriptInterface::FromJSVal(rq, args[0], str)) - return false; + typedef boost::flyweight< + std::string, + boost::flyweights::no_tracking, + boost::flyweights::no_locking + > StringFlyweight; - typedef boost::flyweight< - std::string, - boost::flyweights::no_tracking, - boost::flyweights::no_locking - > StringFlyweight; - - name = StringFlyweight(str).get().c_str(); - } + if (!regionName.empty()) + name = StringFlyweight(regionName).get().c_str(); if (CProfileManager::IsInitialised() && Threading::IsMainThread()) g_Profiler.StartScript(name); g_Profiler2.RecordRegionEnter(name); - - args.rval().setUndefined(); - return true; } -bool ProfileStop(JSContext* UNUSED(cx), uint argc, JS::Value* vp) +void ProfileStop() { - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); if (CProfileManager::IsInitialised() && Threading::IsMainThread()) g_Profiler.Stop(); g_Profiler2.RecordRegionLeave(); - - args.rval().setUndefined(); - return true; } -bool ProfileAttribute(JSContext* cx, uint argc, JS::Value* vp) +void ProfileAttribute(const std::string& attr) { const char* name = "(ProfileAttribute)"; - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ - if (args.length() >= 1) - { - std::string str; - if (!ScriptInterface::FromJSVal(rq, args[0], str)) - return false; + typedef boost::flyweight< + std::string, + boost::flyweights::no_tracking, + boost::flyweights::no_locking + > StringFlyweight; - typedef boost::flyweight< - std::string, - boost::flyweights::no_tracking, - boost::flyweights::no_locking - > StringFlyweight; - - name = StringFlyweight(str).get().c_str(); - } + if (!attr.empty()) + name = StringFlyweight(attr).get().c_str(); g_Profiler2.RecordAttribute("%s", name); - - args.rval().setUndefined(); - return true; } // Math override functions: @@ -336,18 +306,19 @@ ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const sh JS_DefineProperty(m_cx, m_glob, "global", m_glob, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); - m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); - + // These first 4 actually use CallArgs & thus don't use ScriptFunction JS_DefineFunction(m_cx, m_glob, "print", ::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "log", ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "warn", ::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); - JS_DefineFunction(m_cx, m_glob, "clone", ::deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); - JS_DefineFunction(m_cx, m_glob, "deepfreeze", ::deepfreeze, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); + ScriptFunction::Register(m_cx, m_glob, "clone"); + ScriptFunction::Register(m_cx, m_glob, "deepfreeze"); - Register("ProfileStart", ::ProfileStart, 1); - Register("ProfileStop", ::ProfileStop, 0); - Register("ProfileAttribute", ::ProfileAttribute, 1); + m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); + + ScriptFunction::Register<&ProfileStart>(m_cx, m_nativeScope, "ProfileStart"); + ScriptFunction::Register<&ProfileStop>(m_cx, m_nativeScope, "ProfileStop"); + ScriptFunction::Register<&ProfileAttribute>(m_cx, m_nativeScope, "ProfileAttribute"); m_context->RegisterRealm(JS::GetObjectRealmOrNull(m_glob)); } @@ -357,13 +328,6 @@ ScriptInterface_impl::~ScriptInterface_impl() m_context->UnRegisterRealm(JS::GetObjectRealmOrNull(m_glob)); } -void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs) const -{ - JSAutoRealm autoRealm(m_cx, m_glob); - JS::RootedObject nativeScope(m_cx, m_nativeScope); - JS::RootedFunction func(m_cx, JS_DefineFunction(m_cx, nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)); -} - ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr& context) : m(std::make_unique(nativeScopeName, context)) { @@ -441,11 +405,6 @@ bool ScriptInterface::ReplaceNondeterministicRNG(boost::rand48& rng) return false; } -void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs) const -{ - m->Register(name, fptr, (uint)nargs); -} - JSContext* ScriptInterface::GetGeneralJSContext() const { return m->m_context->GetGeneralJSContext(); diff --git a/source/scriptinterface/ScriptInterface.h b/source/scriptinterface/ScriptInterface.h index 98ddd0c17d..e04d53df19 100644 --- a/source/scriptinterface/ScriptInterface.h +++ b/source/scriptinterface/ScriptInterface.h @@ -34,7 +34,6 @@ ERROR_TYPE(Scripting_LoadFile, OpenFailed); ERROR_TYPE(Scripting_LoadFile, EvalErrors); ERROR_TYPE(Scripting, CallFunctionFailed); -ERROR_TYPE(Scripting, RegisterFunctionFailed); ERROR_TYPE(Scripting, DefineConstantFailed); ERROR_TYPE(Scripting, CreateObjectFailed); ERROR_TYPE(Scripting, TypeDoesNotExist); @@ -105,7 +104,7 @@ public: /** * Constructor. - * @param nativeScopeName Name of global object that functions (via RegisterFunction) will + * @param nativeScopeName Name of global object that functions (via ScriptFunction::Register) will * be placed into, as a scoping mechanism; typically "Engine" * @param debugName Name of this interface for CScriptStats purposes. * @param context ScriptContext to use when initializing this interface. @@ -455,7 +454,6 @@ private: JSClass* m_Class; JSNative m_Constructor; }; - void Register(const char* name, JSNative fptr, size_t nargs) const; // Take care to keep this declaration before heap rooted members. Destructors of heap rooted // members have to be called before the custom destructor of ScriptInterface_impl. @@ -470,9 +468,6 @@ public: // This declares: // // template - // void RegisterFunction(const char* functionName) const; - // - // template // static JSNative call; // // template diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp index a47ec98ebb..101a9865a8 100644 --- a/source/simulation2/components/CCmpAIManager.cpp +++ b/source/simulation2/components/CCmpAIManager.cpp @@ -32,6 +32,7 @@ #include "ps/scripting/JSInterface_VFS.h" #include "ps/TemplateLoader.h" #include "ps/Util.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptContext.h" #include "simulation2/components/ICmpAIInterface.h" #include "simulation2/components/ICmpCommandQueue.h" @@ -228,16 +229,22 @@ public: JS_AddExtraGCRootsTracer(m_ScriptInterface->GetGeneralJSContext(), Trace, this); - m_ScriptInterface->RegisterFunction("PostCommand"); - m_ScriptInterface->RegisterFunction("IncludeModule"); - m_ScriptInterface->RegisterFunction("Exit"); + ScriptRequest rq(m_ScriptInterface); +#define REGISTER_FUNC_NAME(func, name) \ + ScriptFunction::Register<&CAIWorker::func, ScriptFunction::ObjectFromCBData>(rq, name); - m_ScriptInterface->RegisterFunction("ComputePath"); + REGISTER_FUNC_NAME(PostCommand, "PostCommand"); + REGISTER_FUNC_NAME(LoadScripts, "IncludeModule"); + ScriptFunction::Register(rq, "Exit"); - m_ScriptInterface->RegisterFunction, u32, u32, u32, CAIWorker::DumpImage>("DumpImage"); - m_ScriptInterface->RegisterFunction("GetTemplate"); + REGISTER_FUNC_NAME(ComputePathScript, "ComputePath"); - JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get())); + REGISTER_FUNC_NAME(DumpImage, "DumpImage"); + REGISTER_FUNC_NAME(GetTemplate, "GetTemplate"); + +#undef REGISTER_FUNC_NAME + + JSI_VFS::RegisterScriptFunctions_Simulation(rq); // Globalscripts may use VFS script functions m_ScriptInterface->LoadGlobalScripts(); @@ -279,20 +286,6 @@ public: return true; } - static void IncludeModule(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name) - { - ENSURE(pCmptPrivate->pCBData); - CAIWorker* self = static_cast (pCmptPrivate->pCBData); - self->LoadScripts(name); - } - - static void PostCommand(ScriptInterface::CmptPrivate* pCmptPrivate, int playerid, JS::HandleValue cmd) - { - ENSURE(pCmptPrivate->pCBData); - CAIWorker* self = static_cast (pCmptPrivate->pCBData); - self->PostCommand(playerid, cmd); - } - void PostCommand(int playerid, JS::HandleValue cmd) { for (size_t i=0; ipCBData); - CAIWorker* self = static_cast (pCmptPrivate->pCBData); - ScriptRequest rq(self->m_ScriptInterface); + ScriptRequest rq(m_ScriptInterface); CFixedVector2D pos, goalPos; std::vector waypoints; JS::RootedValue retVal(rq.cx); - self->m_ScriptInterface->FromJSVal(rq, position, pos); - self->m_ScriptInterface->FromJSVal(rq, goal, goalPos); + m_ScriptInterface->FromJSVal(rq, position, pos); + m_ScriptInterface->FromJSVal(rq, goal, goalPos); - self->ComputePath(pos, goalPos, passClass, waypoints); - self->m_ScriptInterface->ToJSVal >(rq, &retVal, waypoints); + ComputePath(pos, goalPos, passClass, waypoints); + m_ScriptInterface->ToJSVal >(rq, &retVal, waypoints); return retVal; } @@ -337,14 +327,6 @@ public: waypoints.emplace_back(wp.x, wp.z); } - static CParamNode GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name) - { - ENSURE(pCmptPrivate->pCBData); - CAIWorker* self = static_cast (pCmptPrivate->pCBData); - - return self->GetTemplate(name); - } - CParamNode GetTemplate(const std::string& name) { if (!m_TemplateLoader.TemplateExists(name)) @@ -352,15 +334,10 @@ public: return m_TemplateLoader.GetTemplateFileData(name).GetChild("Entity"); } - static void ExitProgram(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) - { - QuitEngine(); - } - /** * Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights). */ - static void DumpImage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name, const std::vector& data, u32 w, u32 h, u32 max) + void DumpImage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name, const std::vector& data, u32 w, u32 h, u32 max) { // TODO: this is totally not threadsafe. VfsPath filename = L"screenshots/aidump/" + name; diff --git a/source/simulation2/components/tests/test_scripts.h b/source/simulation2/components/tests/test_scripts.h index 3affbc9ee9..5053842475 100644 --- a/source/simulation2/components/tests/test_scripts.h +++ b/source/simulation2/components/tests/test_scripts.h @@ -92,7 +92,8 @@ public: CComponentManager componentManager(context, g_ScriptContext, true); ScriptTestSetup(componentManager.GetScriptInterface()); - componentManager.GetScriptInterface().RegisterFunction ("SerializationRoundTrip"); + ScriptRequest rq(componentManager.GetScriptInterface()); + ScriptFunction::Register(rq, "SerializationRoundTrip"); load_script(componentManager.GetScriptInterface(), path); } diff --git a/source/simulation2/scripting/JSInterface_Simulation.cpp b/source/simulation2/scripting/JSInterface_Simulation.cpp index b8452e16f6..9828671537 100644 --- a/source/simulation2/scripting/JSInterface_Simulation.cpp +++ b/source/simulation2/scripting/JSInterface_Simulation.cpp @@ -24,6 +24,7 @@ #include "ps/Game.h" #include "ps/GameSetup/Config.h" #include "ps/Pyrogenesis.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/components/ICmpAIManager.h" #include "simulation2/components/ICmpCommandQueue.h" @@ -39,7 +40,9 @@ #include #include -JS::Value JSI_Simulation::GuiInterfaceCall(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue data) +namespace JSI_Simulation +{ +JS::Value GuiInterfaceCall(const ScriptInterface& scriptInterface, const std::wstring& name, JS::HandleValue data) { if (!g_Game) return JS::UndefinedValue(); @@ -52,14 +55,14 @@ JS::Value JSI_Simulation::GuiInterfaceCall(ScriptInterface::CmptPrivate* pCmptPr return JS::UndefinedValue(); ScriptRequest rqSim(sim->GetScriptInterface()); - JS::RootedValue arg(rqSim.cx, sim->GetScriptInterface().CloneValueFromOtherCompartment(*(pCmptPrivate->pScriptInterface), data)); + JS::RootedValue arg(rqSim.cx, sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, data)); JS::RootedValue ret(rqSim.cx); cmpGuiInterface->ScriptCall(g_Game->GetViewedPlayerID(), name, arg, &ret); - return pCmptPrivate->pScriptInterface->CloneValueFromOtherCompartment(sim->GetScriptInterface(), ret); + return scriptInterface.CloneValueFromOtherCompartment(sim->GetScriptInterface(), ret); } -void JSI_Simulation::PostNetworkCommand(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue cmd) +void PostNetworkCommand(const ScriptInterface& scriptInterface, JS::HandleValue cmd) { if (!g_Game) return; @@ -73,39 +76,39 @@ void JSI_Simulation::PostNetworkCommand(ScriptInterface::CmptPrivate* pCmptPriva ScriptRequest rqSim(sim->GetScriptInterface()); JS::RootedValue cmd2(rqSim.cx, - sim->GetScriptInterface().CloneValueFromOtherCompartment(*(pCmptPrivate->pScriptInterface), cmd)); + sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, cmd)); cmpCommandQueue->PostNetworkCommand(cmd2); } -void JSI_Simulation::DumpSimState(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +void DumpSimState() { OsPath path = psLogDir()/"sim_dump.txt"; std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); g_Game->GetSimulation2()->DumpDebugState(file); } -entity_id_t JSI_Simulation::PickEntityAtPoint(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int x, int y) +entity_id_t PickEntityAtPoint(int x, int y) { return EntitySelection::PickEntityAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetViewedPlayerID(), false); } -std::vector JSI_Simulation::PickPlayerEntitiesInRect(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int x0, int y0, int x1, int y1, int player) +std::vector PickPlayerEntitiesInRect(int x0, int y0, int x1, int y1, int player) { return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false); } -std::vector JSI_Simulation::PickPlayerEntitiesOnScreen(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int player) +std::vector PickPlayerEntitiesOnScreen(int player) { return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, player, false); } -std::vector JSI_Simulation::PickNonGaiaEntitiesOnScreen(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::vector PickNonGaiaEntitiesOnScreen() { return EntitySelection::PickNonGaiaEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, false); } -std::vector JSI_Simulation::GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) +std::vector GetEntitiesWithStaticObstructionOnScreen() { struct StaticObstructionFilter { @@ -118,7 +121,7 @@ std::vector JSI_Simulation::GetEntitiesWithStaticObstructionOnScree return EntitySelection::GetEntitiesWithComponentInRect(*g_Game->GetSimulation2(), IID_Obstruction, *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres); } -JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t z) +JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(const ScriptInterface& scriptInterface, entity_pos_t x, entity_pos_t z) { if (!g_Game) return JS::UndefinedValue(); @@ -126,7 +129,7 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter CSimulation2* sim = g_Game->GetSimulation2(); ENSURE(sim); - ScriptRequest rq(pCmptPrivate->pScriptInterface); + ScriptRequest rq(scriptInterface); JS::RootedValue edgeList(rq.cx); ScriptInterface::CreateArray(rq, &edgeList); int edgeListIndex = 0; @@ -135,7 +138,7 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter CFG_GET_VAL("gui.session.snaptoedgesdistancethreshold", distanceThreshold); CFixedVector2D entityPos(x, z); - std::vector entities = GetEntitiesWithStaticObstructionOnScreen(pCmptPrivate); + std::vector entities = GetEntitiesWithStaticObstructionOnScreen(); for (entity_id_t entity : entities) { CmpPtr cmpObstruction(sim->GetSimContext(), entity); @@ -182,39 +185,40 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter "normal", normal, "order", "cw"); - pCmptPrivate->pScriptInterface->SetPropertyInt(edgeList, edgeListIndex++, edge); + scriptInterface.SetPropertyInt(edgeList, edgeListIndex++, edge); } } return edgeList; } -std::vector JSI_Simulation::PickSimilarPlayerEntities(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) +std::vector PickSimilarPlayerEntities(const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) { return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetViewedPlayerID(), includeOffScreen, matchRank, false, allowFoundations); } -JS::Value JSI_Simulation::GetAIs(ScriptInterface::CmptPrivate* pCmptPrivate) +JS::Value GetAIs(const ScriptInterface& scriptInterface) { - return ICmpAIManager::GetAIs(*(pCmptPrivate->pScriptInterface)); + return ICmpAIManager::GetAIs(scriptInterface); } -void JSI_Simulation::SetBoundingBoxDebugOverlay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool enabled) +void SetBoundingBoxDebugOverlay(bool enabled) { ICmpSelectable::ms_EnableDebugOverlays = enabled; } -void JSI_Simulation::RegisterScriptFunctions(const ScriptInterface& scriptInterface) +void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("GuiInterfaceCall"); - scriptInterface.RegisterFunction("PostNetworkCommand"); - scriptInterface.RegisterFunction("DumpSimState"); - scriptInterface.RegisterFunction("GetAIs"); - scriptInterface.RegisterFunction("PickEntityAtPoint"); - scriptInterface.RegisterFunction, int, int, int, int, int, &PickPlayerEntitiesInRect>("PickPlayerEntitiesInRect"); - scriptInterface.RegisterFunction, int, &PickPlayerEntitiesOnScreen>("PickPlayerEntitiesOnScreen"); - scriptInterface.RegisterFunction, &PickNonGaiaEntitiesOnScreen>("PickNonGaiaEntitiesOnScreen"); - scriptInterface.RegisterFunction, &GetEntitiesWithStaticObstructionOnScreen>("GetEntitiesWithStaticObstructionOnScreen"); - scriptInterface.RegisterFunction("GetEdgesOfStaticObstructionsOnScreenNearTo"); - scriptInterface.RegisterFunction, std::string, bool, bool, bool, &PickSimilarPlayerEntities>("PickSimilarPlayerEntities"); - scriptInterface.RegisterFunction("SetBoundingBoxDebugOverlay"); + ScriptFunction::Register<&GuiInterfaceCall>(rq, "GuiInterfaceCall"); + ScriptFunction::Register<&PostNetworkCommand>(rq, "PostNetworkCommand"); + ScriptFunction::Register<&DumpSimState>(rq, "DumpSimState"); + ScriptFunction::Register<&GetAIs>(rq, "GetAIs"); + ScriptFunction::Register<&PickEntityAtPoint>(rq, "PickEntityAtPoint"); + ScriptFunction::Register<&PickPlayerEntitiesInRect>(rq, "PickPlayerEntitiesInRect"); + ScriptFunction::Register<&PickPlayerEntitiesOnScreen>(rq, "PickPlayerEntitiesOnScreen"); + ScriptFunction::Register<&PickNonGaiaEntitiesOnScreen>(rq, "PickNonGaiaEntitiesOnScreen"); + ScriptFunction::Register<&GetEntitiesWithStaticObstructionOnScreen>(rq, "GetEntitiesWithStaticObstructionOnScreen"); + ScriptFunction::Register<&GetEdgesOfStaticObstructionsOnScreenNearTo>(rq, "GetEdgesOfStaticObstructionsOnScreenNearTo"); + ScriptFunction::Register<&PickSimilarPlayerEntities>(rq, "PickSimilarPlayerEntities"); + ScriptFunction::Register<&SetBoundingBoxDebugOverlay>(rq, "SetBoundingBoxDebugOverlay"); +} } diff --git a/source/simulation2/scripting/JSInterface_Simulation.h b/source/simulation2/scripting/JSInterface_Simulation.h index 9160876fba..66f31b4e18 100644 --- a/source/simulation2/scripting/JSInterface_Simulation.h +++ b/source/simulation2/scripting/JSInterface_Simulation.h @@ -18,26 +18,11 @@ #ifndef INCLUDED_JSI_SIMULATION #define INCLUDED_JSI_SIMULATION -#include "scriptinterface/ScriptInterface.h" -#include "simulation2/helpers/Position.h" -#include "simulation2/system/Entity.h" +class ScriptRequest; namespace JSI_Simulation { - JS::Value GuiInterfaceCall(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue data); - void PostNetworkCommand(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue cmd); - entity_id_t PickEntityAtPoint(ScriptInterface::CmptPrivate* pCmptPrivate, int x, int y); - void DumpSimState(ScriptInterface::CmptPrivate* pCmptPrivate); - std::vector PickPlayerEntitiesInRect(ScriptInterface::CmptPrivate* pCmptPrivate, int x0, int y0, int x1, int y1, int player); - std::vector PickPlayerEntitiesOnScreen(ScriptInterface::CmptPrivate* pCmptPrivate, int player); - std::vector PickNonGaiaEntitiesOnScreen(ScriptInterface::CmptPrivate* pCmptPrivate); - std::vector GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CmptPrivate* pCmptPrivate); - JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t z); - std::vector PickSimilarPlayerEntities(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations); - JS::Value GetAIs(ScriptInterface::CmptPrivate* pCmptPrivate); - void SetBoundingBoxDebugOverlay(ScriptInterface::CmptPrivate* pCmptPrivate, bool enabled); - - void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_JSI_SIMULATION diff --git a/source/soundmanager/scripting/JSInterface_Sound.cpp b/source/soundmanager/scripting/JSInterface_Sound.cpp index 90db7109f3..fbf53f5576 100644 --- a/source/soundmanager/scripting/JSInterface_Sound.cpp +++ b/source/soundmanager/scripting/JSInterface_Sound.cpp @@ -22,6 +22,7 @@ #include "lib/utf8.h" #include "maths/Vector3D.h" #include "ps/Filesystem.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "soundmanager/SoundManager.h" @@ -31,84 +32,84 @@ namespace JSI_Sound { #if CONFIG2_AUDIO - void StartMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) + void StartMusic() { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMusicEnabled(true); } - void StopMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) + void StopMusic() { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMusicEnabled(false); } - void ClearPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) + void ClearPlaylist() { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->ClearPlayListItems(); } - void AddPlaylistItem(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) + void AddPlaylistItem(const std::wstring& filename) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->AddPlayListItem(VfsPath(filename)); } - void StartPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool looping) + void StartPlaylist(bool looping) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->StartPlayList(looping ); } - void PlayMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename, bool looping) + void PlayMusic(const std::wstring& filename, bool looping) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->PlayAsMusic(filename, looping); } - void PlayUISound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename, bool looping) + void PlayUISound(const std::wstring& filename, bool looping) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->PlayAsUI(filename, looping); } - void PlayAmbientSound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename, bool looping) + void PlayAmbientSound(const std::wstring& filename, bool looping) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->PlayAsAmbient(filename, looping); } - bool MusicPlaying(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) + bool MusicPlaying() { return true; } - void SetMasterGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) + void SetMasterGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMasterGain(gain); } - void SetMusicGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) + void SetMusicGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMusicGain(gain); } - void SetAmbientGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) + void SetAmbientGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetAmbientGain(gain); } - void SetActionGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) + void SetActionGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetActionGain(gain); } - void SetUIGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) + void SetUIGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetUIGain(gain); @@ -116,38 +117,38 @@ namespace JSI_Sound #else - bool MusicPlaying(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){ return false; } - void PlayAmbientSound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ){} - void PlayUISound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} - void PlayMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} - void StartPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool UNUSED(looping) ){} - void AddPlaylistItem(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename) ){} - void ClearPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){} - void StopMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){} - void StartMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){} - void SetMasterGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} - void SetMusicGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} - void SetAmbientGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} - void SetActionGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} - void SetUIGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} + bool MusicPlaying( ){ return false; } + void PlayAmbientSound(const std::wstring& UNUSED(filename), bool UNUSED(looping) ){} + void PlayUISound(const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} + void PlayMusic(const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} + void StartPlaylist(bool UNUSED(looping) ){} + void AddPlaylistItem(const std::wstring& UNUSED(filename) ){} + void ClearPlaylist( ){} + void StopMusic( ){} + void StartMusic( ){} + void SetMasterGain(float UNUSED(gain)){} + void SetMusicGain(float UNUSED(gain)){} + void SetAmbientGain(float UNUSED(gain)){} + void SetActionGain(float UNUSED(gain)){} + void SetUIGain(float UNUSED(gain)){} #endif - void RegisterScriptFunctions(const ScriptInterface& scriptInterface) + void RegisterScriptFunctions(const ScriptRequest& rq) { - scriptInterface.RegisterFunction("StartMusic"); - scriptInterface.RegisterFunction("StopMusic"); - scriptInterface.RegisterFunction("ClearPlaylist"); - scriptInterface.RegisterFunction("AddPlaylistItem"); - scriptInterface.RegisterFunction("StartPlaylist"); - scriptInterface.RegisterFunction("PlayMusic"); - scriptInterface.RegisterFunction("PlayUISound"); - scriptInterface.RegisterFunction("PlayAmbientSound"); - scriptInterface.RegisterFunction("MusicPlaying"); - scriptInterface.RegisterFunction("SetMasterGain"); - scriptInterface.RegisterFunction("SetMusicGain"); - scriptInterface.RegisterFunction("SetAmbientGain"); - scriptInterface.RegisterFunction("SetActionGain"); - scriptInterface.RegisterFunction("SetUIGain"); + ScriptFunction::Register<&StartMusic>(rq, "StartMusic"); + ScriptFunction::Register<&StopMusic>(rq, "StopMusic"); + ScriptFunction::Register<&ClearPlaylist>(rq, "ClearPlaylist"); + ScriptFunction::Register<&AddPlaylistItem>(rq, "AddPlaylistItem"); + ScriptFunction::Register<&StartPlaylist>(rq, "StartPlaylist"); + ScriptFunction::Register<&PlayMusic>(rq, "PlayMusic"); + ScriptFunction::Register<&PlayUISound>(rq, "PlayUISound"); + ScriptFunction::Register<&PlayAmbientSound>(rq, "PlayAmbientSound"); + ScriptFunction::Register<&MusicPlaying>(rq, "MusicPlaying"); + ScriptFunction::Register<&SetMasterGain>(rq, "SetMasterGain"); + ScriptFunction::Register<&SetMusicGain>(rq, "SetMusicGain"); + ScriptFunction::Register<&SetAmbientGain>(rq, "SetAmbientGain"); + ScriptFunction::Register<&SetActionGain>(rq, "SetActionGain"); + ScriptFunction::Register<&SetUIGain>(rq, "SetUIGain"); } } diff --git a/source/soundmanager/scripting/JSInterface_Sound.h b/source/soundmanager/scripting/JSInterface_Sound.h index 2c6586fc92..1cd691543a 100644 --- a/source/soundmanager/scripting/JSInterface_Sound.h +++ b/source/soundmanager/scripting/JSInterface_Sound.h @@ -19,11 +19,11 @@ #ifndef INCLUDED_SOUNDSCRIPTINTERFACE #define INCLUDED_SOUNDSCRIPTINTERFACE -class ScriptInterface; +class ScriptRequest; namespace JSI_Sound { - void RegisterScriptFunctions(const ScriptInterface& scriptInterface); + void RegisterScriptFunctions(const ScriptRequest& rq); } #endif // INCLUDED_SOUNDSCRIPTINTERFACE