Index: source/graphics/MapGenerator.h =================================================================== --- source/graphics/MapGenerator.h +++ source/graphics/MapGenerator.h @@ -118,6 +118,7 @@ */ void InitScriptInterface(const u32 seed); + static CMapGeneratorWorker* GetWorkerFromCxPrivateData(JSContext* cx, JS::CallArgs&); private: /** @@ -133,55 +134,52 @@ */ bool LoadScripts(const VfsPath& libraryName); - /** - * Recursively load all script files in the given folder. - */ - static bool LoadLibrary(ScriptInterface::CxPrivate* pCxPrivate, const VfsPath& name); - /** * Finalize map generation and pass results from the script to the engine. */ - static void ExportMap(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue data); + void ExportMap(JS::HandleValue data); /** * Load an image file and return it as a height array. */ - static JS::Value LoadHeightmap(ScriptInterface::CxPrivate* pCxPrivate, const VfsPath& src); + std::vector LoadHeightmapImage(const VfsPath& src); /** * Load an Atlas terrain file (PMP) returning textures and heightmap. */ - static JS::Value LoadMapTerrain(ScriptInterface::CxPrivate* pCxPrivate, 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::CxPrivate* pCxPrivate, int progress); + void SetProgress(int progress); /** * Microseconds since the epoch. */ - static double GetMicroseconds(ScriptInterface::CxPrivate* pCxPrivate); + double GetMicroseconds(); /** * Return the template data of the given template name. */ - static CParamNode GetTemplate(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName); + CParamNode GetTemplate(const std::string& templateName); /** * Check whether the given template exists. */ - static bool TemplateExists(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName); + bool TemplateExists(const std::string& templateName); /** * Returns all template names of simulation entity templates. */ - static std::vector FindTemplates(ScriptInterface::CxPrivate* pCxPrivate, 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::CxPrivate* pCxPrivate, const std::string& path, bool includeSubdirectories); + std::vector FindActorTemplates(const std::string& path, bool includeSubdirectories); + +private: /** * Perform map generation in an independent thread. Index: source/graphics/MapGenerator.cpp =================================================================== --- source/graphics/MapGenerator.cpp +++ source/graphics/MapGenerator.cpp @@ -31,6 +31,7 @@ #include "ps/FileIo.h" #include "ps/Profile.h" #include "ps/scripting/JSInterface_VFS.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptRuntime.h" #include "scriptinterface/ScriptConversions.h" #include "scriptinterface/ScriptInterface.h" @@ -162,6 +163,15 @@ return true; } +#define Register(func, name) \ + ScriptWrapper::WrapAndRegister(*m_ScriptInterface, name); + +CMapGeneratorWorker* CMapGeneratorWorker::GetWorkerFromCxPrivateData(JSContext* cx, JS::CallArgs&) +{ + return static_cast(ScriptInterface::GetScriptInterfaceAndCBData(cx)->pCBData); +} + void CMapGeneratorWorker::InitScriptInterface(const u32 seed) { m_ScriptInterface->SetCallbackData(static_cast(this)); @@ -176,9 +186,9 @@ m_ScriptInterface->LoadGlobalScripts(); // File loading - m_ScriptInterface->RegisterFunction("LoadLibrary"); - m_ScriptInterface->RegisterFunction("LoadHeightmapImage"); - m_ScriptInterface->RegisterFunction("LoadMapTerrain"); + Register(LoadScripts, "LoadLibrary"); + Register(LoadHeightmapImage, "LoadHeightmapImage"); + Register(LoadMapTerrain, "LoadMapTerrain"); // Engine constants @@ -193,16 +203,17 @@ void CMapGeneratorWorker::RegisterScriptFunctions_MapGenerator() { // 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(GetTemplate, "GetTemplate"); + Register(TemplateExists, "TemplateExists"); + Register(FindTemplates, "FindTemplates"); + Register(FindActorTemplates, "FindActorTemplates"); // Progression and profiling - m_ScriptInterface->RegisterFunction("SetProgress"); - m_ScriptInterface->RegisterFunction("GetMicroseconds"); - m_ScriptInterface->RegisterFunction("ExportMap"); + Register(SetProgress, "SetProgress"); + Register(GetMicroseconds, "GetMicroseconds"); + Register(ExportMap, "ExportMap"); } +#undef Register int CMapGeneratorWorker::GetProgress() { @@ -210,7 +221,7 @@ return m_Progress; } -double CMapGeneratorWorker::GetMicroseconds(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +double CMapGeneratorWorker::GetMicroseconds() { return JS_Now(); } @@ -221,61 +232,47 @@ return m_MapData; } -bool CMapGeneratorWorker::LoadLibrary(ScriptInterface::CxPrivate* pCxPrivate, const VfsPath& name) +void CMapGeneratorWorker::ExportMap(JS::HandleValue data) { - CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); - return self->LoadScripts(name); -} - -void CMapGeneratorWorker::ExportMap(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue data) -{ - CMapGeneratorWorker* self = static_cast(pCxPrivate->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::CxPrivate* pCxPrivate, int progress) +void CMapGeneratorWorker::SetProgress(int progress) { - CMapGeneratorWorker* self = static_cast(pCxPrivate->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::CxPrivate* pCxPrivate, const std::string& templateName) +CParamNode CMapGeneratorWorker::GetTemplate(const std::string& templateName) { - CMapGeneratorWorker* self = static_cast(pCxPrivate->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::CxPrivate* pCxPrivate, const std::string& templateName) +bool CMapGeneratorWorker::TemplateExists(const std::string& templateName) { - CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); - return self->m_TemplateLoader.TemplateExists(templateName); + return m_TemplateLoader.TemplateExists(templateName); } -std::vector CMapGeneratorWorker::FindTemplates(ScriptInterface::CxPrivate* pCxPrivate, const std::string& path, bool includeSubdirectories) +std::vector CMapGeneratorWorker::FindTemplates(const std::string& path, bool includeSubdirectories) { - CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); - return self->m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES); + return m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES); } -std::vector CMapGeneratorWorker::FindActorTemplates(ScriptInterface::CxPrivate* pCxPrivate, const std::string& path, bool includeSubdirectories) +std::vector CMapGeneratorWorker::FindActorTemplates(const std::string& path, bool includeSubdirectories) { - CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); - return self->m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES); + return m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES); } bool CMapGeneratorWorker::LoadScripts(const VfsPath& libraryName) @@ -316,33 +313,23 @@ return true; } -JS::Value CMapGeneratorWorker::LoadHeightmap(ScriptInterface::CxPrivate* pCxPrivate, const VfsPath& filename) +std::vector CMapGeneratorWorker::LoadHeightmapImage(const VfsPath& filename) { std::vector heightmap; if (LoadHeightmapImageVfs(filename, heightmap) != INFO::OK) { LOGERROR("Could not load heightmap file '%s'", filename.string8()); - return JS::UndefinedValue(); + m_ScriptInterface->ReportError(("Could not load heightmap file" + filename.string8()).c_str()); } - - CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); - JSContext* cx = self->m_ScriptInterface->GetContext(); - JSAutoRequest rq(cx); - JS::RootedValue returnValue(cx); - ToJSVal_vector(cx, &returnValue, heightmap); - return returnValue; + return heightmap; } // See CMapReader::UnpackTerrain, CMapReader::ParseTerrain for the reordering -JS::Value CMapGeneratorWorker::LoadMapTerrain(ScriptInterface::CxPrivate* pCxPrivate, const VfsPath& filename) +JS::Value CMapGeneratorWorker::LoadMapTerrain(const VfsPath& filename) { - CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); - JSContext* cx = self->m_ScriptInterface->GetContext(); - JSAutoRequest rq(cx); - if (!VfsFileExists(filename)) { - self->m_ScriptInterface->ReportError( + m_ScriptInterface->ReportError( ("Terrain file \"" + filename.string8() + "\" does not exist!").c_str()); return JS::UndefinedValue(); @@ -353,7 +340,7 @@ if (unpacker.GetVersion() < CMapIO::FILE_READ_VERSION) { - self->m_ScriptInterface->ReportError( + m_ScriptInterface->ReportError( ("Could not load terrain file \"" + filename.string8() + "\" too old version!").c_str()); return JS::UndefinedValue(); @@ -400,10 +387,10 @@ } } - JS::RootedValue returnValue(cx); + JS::RootedValue returnValue(m_ScriptInterface->GetContext()); ScriptInterface::CreateObject( - cx, + m_ScriptInterface->GetContext(), &returnValue, "height", heightmap, "textureNames", textureNames, Index: source/graphics/scripting/JSInterface_GameView.h =================================================================== --- source/graphics/scripting/JSInterface_GameView.h +++ source/graphics/scripting/JSInterface_GameView.h @@ -24,8 +24,8 @@ #include "simulation2/system/Entity.h" #define DECLARE_BOOLEAN_SCRIPT_SETTING(NAME) \ - bool Get##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate); \ - void Set##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate, bool Enabled); + bool Get##NAME##Enabled(); \ + void Set##NAME##Enabled(bool Enabled); namespace JSI_GameView { @@ -37,13 +37,13 @@ DECLARE_BOOLEAN_SCRIPT_SETTING(ConstrainCamera); JS::Value GetCameraPivot(ScriptInterface::CxPrivate* pCxPrivate); - void CameraMoveTo(ScriptInterface::CxPrivate* pCxPrivate, entity_pos_t x, entity_pos_t z); - void SetCameraTarget(ScriptInterface::CxPrivate* pCxPrivate, float x, float y, float z); - void SetCameraData(ScriptInterface::CxPrivate* pCxPrivate, 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::CxPrivate* pCxPrivate, entity_id_t entityid); - void CameraFollowFPS(ScriptInterface::CxPrivate* pCxPrivate, entity_id_t entityid); - entity_id_t GetFollowedEntity(ScriptInterface::CxPrivate* pCxPrivate); - CFixedVector3D GetTerrainAtScreenPoint(ScriptInterface::CxPrivate* pCxPrivate, int x, int y); + void CameraMoveTo(entity_pos_t x, entity_pos_t z); + void SetCameraTarget(float x, float y, float z); + 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); + void CameraFollow(entity_id_t entityid); + void CameraFollowFPS(entity_id_t entityid); + entity_id_t GetFollowedEntity(); + CFixedVector3D GetTerrainAtScreenPoint(int x, int y); } #undef DECLARE_BOOLEAN_SCRIPT_SETTING Index: source/graphics/scripting/JSInterface_GameView.cpp =================================================================== --- source/graphics/scripting/JSInterface_GameView.cpp +++ source/graphics/scripting/JSInterface_GameView.cpp @@ -25,10 +25,11 @@ #include "ps/Game.h" #include "ps/World.h" #include "ps/CLogger.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \ -bool JSI_GameView::Get##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) \ +bool JSI_GameView::Get##NAME##Enabled() \ { \ if (!g_Game || !g_Game->GetView()) \ { \ @@ -38,7 +39,7 @@ return g_Game->GetView()->Get##NAME##Enabled(); \ } \ \ -void JSI_GameView::Set##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool Enabled) \ +void JSI_GameView::Set##NAME##Enabled(bool Enabled) \ { \ if (!g_Game || !g_Game->GetView()) \ { \ @@ -56,8 +57,8 @@ #define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \ -scriptInterface.RegisterFunction("GameView_Get" #NAME "Enabled"); \ -scriptInterface.RegisterFunction("GameView_Set" #NAME "Enabled"); +ScriptWrapper::WrapAndRegister(scriptInterface, "GameView_Get" #NAME "Enabled"); \ +ScriptWrapper::WrapAndRegister(scriptInterface, "GameView_Set" #NAME "Enabled") void JSI_GameView::RegisterScriptFunctions_Settings(const ScriptInterface& scriptInterface) { @@ -84,7 +85,7 @@ /** * Move camera to a 2D location. */ -void JSI_GameView::CameraMoveTo(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_pos_t x, entity_pos_t z) +void JSI_GameView::CameraMoveTo(entity_pos_t x, entity_pos_t z) { if (!g_Game || !g_Game->GetWorld() || !g_Game->GetView() || !g_Game->GetWorld()->GetTerrain()) return; @@ -102,7 +103,7 @@ /** * Set the camera to look at the given location. */ -void JSI_GameView::SetCameraTarget(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float x, float y, float z) +void JSI_GameView::SetCameraTarget(float x, float y, float z) { g_Game->GetView()->ResetCameraTarget(CVector3D(x, y, z)); } @@ -110,7 +111,7 @@ /** * Set the data (position, orientation and zoom) of the camera. */ -void JSI_GameView::SetCameraData(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), 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 JSI_GameView::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->GetWorld() || !g_Game->GetView() || !g_Game->GetWorld()->GetTerrain()) return; @@ -127,7 +128,7 @@ * Start / stop camera following mode. * @param entityid unit id to follow. If zero, stop following mode */ -void JSI_GameView::CameraFollow(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_id_t entityid) +void JSI_GameView::CameraFollow(entity_id_t entityid) { if (!g_Game || !g_Game->GetView()) return; @@ -139,7 +140,7 @@ * Start / stop first-person camera following mode. * @param entityid unit id to follow. If zero, stop following mode. */ -void JSI_GameView::CameraFollowFPS(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_id_t entityid) +void JSI_GameView::CameraFollowFPS(entity_id_t entityid) { if (!g_Game || !g_Game->GetView()) return; @@ -147,7 +148,7 @@ g_Game->GetView()->FollowEntity(entityid, true); } -entity_id_t JSI_GameView::GetFollowedEntity(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +entity_id_t JSI_GameView::GetFollowedEntity() { if (!g_Game || !g_Game->GetView()) return INVALID_ENTITY; @@ -155,7 +156,7 @@ return g_Game->GetView()->GetFollowedEntity(); } -CFixedVector3D JSI_GameView::GetTerrainAtScreenPoint(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x, int y) +CFixedVector3D JSI_GameView::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)); @@ -165,12 +166,14 @@ { RegisterScriptFunctions_Settings(scriptInterface); - scriptInterface.RegisterFunction("GetCameraPivot"); - scriptInterface.RegisterFunction("CameraMoveTo"); - scriptInterface.RegisterFunction("SetCameraTarget"); - scriptInterface.RegisterFunction("SetCameraData"); - scriptInterface.RegisterFunction("CameraFollow"); - scriptInterface.RegisterFunction("CameraFollowFPS"); - scriptInterface.RegisterFunction("GetFollowedEntity"); - scriptInterface.RegisterFunction("GetTerrainAtScreenPoint"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(GetCameraPivot); + Register(CameraMoveTo); + Register(SetCameraTarget); + Register(SetCameraData); + Register(CameraFollow); + Register(CameraFollowFPS); + Register(GetFollowedEntity); + Register(GetTerrainAtScreenPoint); +#undef Register } Index: source/gui/Scripting/JSInterface_GUIManager.h =================================================================== --- source/gui/Scripting/JSInterface_GUIManager.h +++ source/gui/Scripting/JSInterface_GUIManager.h @@ -29,10 +29,10 @@ JS::Value GetGUIObjectByName(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name); void SetGlobalHotkey(ScriptInterface::CxPrivate* pCxPrivate, const std::string& hotkeyTag, const std::string& eventName, JS::HandleValue function); void UnsetGlobalHotkey(ScriptInterface::CxPrivate* pCxPrivate, const std::string& hotkeyTag, const std::string& eventName); - std::wstring SetCursor(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name); - void ResetCursor(ScriptInterface::CxPrivate* pCxPrivate); - bool TemplateExists(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName); - CParamNode GetTemplate(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName); + std::wstring SetCursor(const std::wstring& name); + void ResetCursor(); + bool TemplateExists(const std::string& templateName); + CParamNode GetTemplate(const std::string& templateName); void RegisterScriptFunctions(const ScriptInterface& scriptInterface); } Index: source/gui/Scripting/JSInterface_GUIManager.cpp =================================================================== --- source/gui/Scripting/JSInterface_GUIManager.cpp +++ source/gui/Scripting/JSInterface_GUIManager.cpp @@ -23,6 +23,7 @@ #include "gui/GUIManager.h" #include "gui/ObjectBases/IGUIObject.h" #include "ps/GameSetup/Config.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" // Note that the initData argument may only contain clonable data. @@ -34,6 +35,7 @@ void JSI_GUIManager::SwitchGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData) { + printf("switching to %ls\n", name.c_str()); g_GUI->SwitchPage(name, pCxPrivate->pScriptInterface, initData); } @@ -73,38 +75,40 @@ guiPage->UnsetGlobalHotkey(hotkeyTag, eventName); } -std::wstring JSI_GUIManager::SetCursor(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& name) +std::wstring JSI_GUIManager::SetCursor(const std::wstring& name) { std::wstring old = g_CursorName; g_CursorName = name; return old; } -void JSI_GUIManager::ResetCursor(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_GUIManager::ResetCursor() { g_CursorName = g_DefaultCursor; } -bool JSI_GUIManager::TemplateExists(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& templateName) +bool JSI_GUIManager::TemplateExists(const std::string& templateName) { return g_GUI->TemplateExists(templateName); } -CParamNode JSI_GUIManager::GetTemplate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& templateName) +CParamNode JSI_GUIManager::GetTemplate(const std::string& templateName) { return g_GUI->GetTemplate(templateName); } void JSI_GUIManager::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - 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"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(PushGuiPage); + Register(SwitchGuiPage); + Register(SetGlobalHotkey); + Register(UnsetGlobalHotkey); + Register(PopGuiPage); + Register(GetGUIObjectByName); + Register(SetCursor); + Register(ResetCursor); + Register(TemplateExists); + Register(GetTemplate); +#undef Register } Index: source/gui/Scripting/JSInterface_IGUIObject.cpp =================================================================== --- source/gui/Scripting/JSInterface_IGUIObject.cpp +++ source/gui/Scripting/JSInterface_IGUIObject.cpp @@ -23,6 +23,7 @@ #include "gui/CGUISetting.h" #include "gui/ObjectBases/IGUIObject.h" #include "ps/CLogger.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptExtraHeaders.h" #include "scriptinterface/ScriptInterface.h" Index: source/i18n/scripting/JSInterface_L10n.h =================================================================== --- source/i18n/scripting/JSInterface_L10n.h +++ source/i18n/scripting/JSInterface_L10n.h @@ -55,7 +55,7 @@ * @return Translation of @p sourceString to the current locale, or * @p sourceString if there is no translation available. */ - std::wstring Translate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& sourceString); + std::wstring Translate(const std::wstring& sourceString); /** * Returns the translation of the specified string to the @@ -72,7 +72,7 @@ * specified @p context, or @p sourceString if there is no * translation available. */ - std::wstring TranslateWithContext(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& context, const std::wstring& sourceString); + std::wstring TranslateWithContext(const std::string& context, const std::wstring& sourceString); /** * Returns the translation of the specified string to the @@ -93,7 +93,7 @@ * @p number is 1) or @p pluralSourceString (if @p number is not 1) * if there is no translation available. */ - std::wstring TranslatePlural(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number); + std::wstring TranslatePlural(const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number); /** * Returns the translation of the specified string to the @@ -117,7 +117,7 @@ * @p pluralSourceString (if @p number is not 1) if there is no * translation available. */ - std::wstring TranslatePluralWithContext(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& context, const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number); + std::wstring TranslatePluralWithContext(const std::string& context, const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number); /** * Translates a text line by line to the @@ -134,7 +134,7 @@ * 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::CxPrivate* UNUSED(pCxPrivate), const std::wstring& sourceString); + std::wstring TranslateLines(const std::wstring& sourceString); /** * Translate each of the strings of a JavaScript array to the @@ -150,7 +150,7 @@ * Some of the items in the returned array may be in English because * there was not translation available for them. */ - std::vector TranslateArray(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::vector& sourceArray); + std::vector TranslateArray(const std::vector& sourceArray); /** * Returns the specified date converted to the local timezone using the specified date format. @@ -172,7 +172,7 @@ * @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::CxPrivate* UNUSED(pCxPrivate), UDate milliseconds, const std::wstring& formatString); + std::wstring FormatMillisecondsIntoDateStringLocal(UDate milliseconds, const std::wstring& formatString); /** * Returns the specified date in GMT using the specified date format. @@ -194,7 +194,7 @@ * @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::CxPrivate* UNUSED(pCxPrivate), UDate milliseconds, const std::wstring& formatString); + std::wstring FormatMillisecondsIntoDateStringGMT(UDate milliseconds, const std::wstring& formatString); /** * Returns the specified floating-point number as a string, with the number @@ -207,7 +207,7 @@ * @param number Number to format. * @return Decimal number formatted using the current locale. */ - std::wstring FormatDecimalNumberIntoString(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), double number); + std::wstring FormatDecimalNumberIntoString(double number); /** * Returns an array of supported locale codes sorted alphabetically. @@ -229,7 +229,7 @@ * * @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale */ - std::vector GetSupportedLocaleBaseNames(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); + std::vector GetSupportedLocaleBaseNames(); /** * Returns an array of supported locale names sorted alphabetically by @@ -250,7 +250,7 @@ * * @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale */ - std::vector GetSupportedLocaleDisplayNames(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); + std::vector GetSupportedLocaleDisplayNames(); /** * Returns the code of the current locale. @@ -265,7 +265,7 @@ * @sa GetAllLocales() * @sa ReevaluateCurrentLocaleAndReload() */ - std::string GetCurrentLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); + std::string GetCurrentLocale(); /** * Returns an array of locale codes supported by ICU. @@ -282,7 +282,7 @@ * * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a073d70df8c9c8d119c0d42d70de24137 */ - std::vector GetAllLocales(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); + std::vector GetAllLocales(); /** * Returns the code of the recommended locale for the current user that the @@ -308,7 +308,7 @@ * * @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale */ - std::string GetDictionaryLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& configLocale); + std::string GetDictionaryLocale(const std::string& configLocale); /** * Returns an array of paths to files in the virtual filesystem that provide @@ -321,7 +321,7 @@ * @return Array of paths to files in the virtual filesystem that provide * translations for @p locale. */ - std::vector GetDictionariesForLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + std::vector GetDictionariesForLocale(const std::string& locale); /** * Returns the ISO-639 language code of the specified locale code. @@ -336,7 +336,7 @@ * * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#af36d821adced72a870d921ebadd0ca93 */ - std::string GetLocaleLanguage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + std::string GetLocaleLanguage(const std::string& locale); /** * Returns the programmatic code of the entire locale without keywords. @@ -349,7 +349,7 @@ * * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a4c1acbbdf95dc15599db5f322fa4c4d0 */ - std::string GetLocaleBaseName(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + std::string GetLocaleBaseName(const std::string& locale); /** * Returns the ISO-3166 country code of the specified locale code. @@ -364,7 +364,7 @@ * * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#ae3f1fc415c00d4f0ab33288ceadccbf9 */ - std::string GetLocaleCountry(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + std::string GetLocaleCountry(const std::string& locale); /** * Returns the ISO-15924 abbreviation script code of the specified locale code. @@ -377,10 +377,10 @@ * * @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a5e0145a339d30794178a1412dcc55abe */ - std::string GetLocaleScript(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + std::string GetLocaleScript(const std::string& locale); - std::wstring GetFallbackToAvailableDictLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + std::wstring GetFallbackToAvailableDictLocale(const std::string& locale); /** * Returns @c true if the current locale is the special “Long Strings” @@ -392,7 +392,7 @@ * @return Whether the current locale is the special “Long Strings” * (@c true) or not (@c false). */ - bool UseLongStrings(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); + bool UseLongStrings(); /** * Returns @c true if the locale is supported by both ICU and the game. It @@ -411,7 +411,7 @@ * @return Whether @p locale is supported by both ICU and the game (@c true) * or not (@c false). */ - bool ValidateLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + bool ValidateLocale(const std::string& locale); /** * Saves the specified locale in the game configuration file. @@ -430,7 +430,7 @@ * @return Whether the specified locale is valid (@c true) or not * (@c false). */ - bool SaveLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale); + bool SaveLocale(const std::string& locale); /** * Determines the best, supported locale for the current user, makes it the @@ -449,7 +449,7 @@ * * @sa GetCurrentLocale() */ - void ReevaluateCurrentLocaleAndReload(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); + void ReevaluateCurrentLocaleAndReload(); } #endif // INCLUDED_JSINTERFACE_L10N Index: source/i18n/scripting/JSInterface_L10n.cpp =================================================================== --- source/i18n/scripting/JSInterface_L10n.cpp +++ source/i18n/scripting/JSInterface_L10n.cpp @@ -22,39 +22,40 @@ #include "i18n/L10n.h" #include "lib/utf8.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" // Returns a translation of the specified English string into the current language. -std::wstring JSI_L10n::Translate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& sourceString) +std::wstring JSI_L10n::Translate(const std::wstring& sourceString) { return wstring_from_utf8(g_L10n.Translate(utf8_from_wstring(sourceString))); } // Returns a translation of the specified English string, for the specified context. -std::wstring JSI_L10n::TranslateWithContext(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& context, const std::wstring& sourceString) +std::wstring JSI_L10n::TranslateWithContext(const std::string& context, const std::wstring& sourceString) { 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::CxPrivate* UNUSED(pCxPrivate), const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number) +std::wstring JSI_L10n::TranslatePlural(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::CxPrivate* UNUSED(pCxPrivate), const std::string& context, const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number) +std::wstring JSI_L10n::TranslatePluralWithContext(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::CxPrivate* UNUSED(pCxPrivate), const std::wstring& sourceString) +std::wstring JSI_L10n::TranslateLines(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::CxPrivate* UNUSED(pCxPrivate), const std::vector& sourceArray) +std::vector JSI_L10n::TranslateArray(const std::vector& sourceArray) { std::vector translatedArray; for (const std::wstring& elem : sourceArray) @@ -63,95 +64,95 @@ return translatedArray; } -std::wstring JSI_L10n::GetFallbackToAvailableDictLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +std::wstring JSI_L10n::GetFallbackToAvailableDictLocale(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::CxPrivate* UNUSED(pCxPrivate), UDate milliseconds, const std::wstring& formatString) +std::wstring JSI_L10n::FormatMillisecondsIntoDateStringLocal(UDate milliseconds, const std::wstring& formatString) { return wstring_from_utf8(g_L10n.FormatMillisecondsIntoDateString(milliseconds, utf8_from_wstring(formatString), true)); } // Return a localized version of a duration or a time in GMT given in milliseconds. -std::wstring JSI_L10n::FormatMillisecondsIntoDateStringGMT(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), UDate milliseconds, const std::wstring& formatString) +std::wstring JSI_L10n::FormatMillisecondsIntoDateStringGMT(UDate milliseconds, const std::wstring& formatString) { return wstring_from_utf8(g_L10n.FormatMillisecondsIntoDateString(milliseconds, utf8_from_wstring(formatString), false)); } // Return a localized version of the given decimal number. -std::wstring JSI_L10n::FormatDecimalNumberIntoString(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), double number) +std::wstring JSI_L10n::FormatDecimalNumberIntoString(double number) { return wstring_from_utf8(g_L10n.FormatDecimalNumberIntoString(number)); } -std::vector JSI_L10n::GetSupportedLocaleBaseNames(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::vector JSI_L10n::GetSupportedLocaleBaseNames() { return g_L10n.GetSupportedLocaleBaseNames(); } -std::vector JSI_L10n::GetSupportedLocaleDisplayNames(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::vector JSI_L10n::GetSupportedLocaleDisplayNames() { return g_L10n.GetSupportedLocaleDisplayNames(); } -std::string JSI_L10n::GetCurrentLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::string JSI_L10n::GetCurrentLocale() { return g_L10n.GetCurrentLocaleString(); } -bool JSI_L10n::UseLongStrings(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_L10n::UseLongStrings() { return g_L10n.UseLongStrings(); } -std::vector JSI_L10n::GetAllLocales(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::vector JSI_L10n::GetAllLocales() { return g_L10n.GetAllLocales(); } -std::string JSI_L10n::GetDictionaryLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& configLocale) +std::string JSI_L10n::GetDictionaryLocale(const std::string& configLocale) { return g_L10n.GetDictionaryLocale(configLocale); } -std::vector JSI_L10n::GetDictionariesForLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +std::vector JSI_L10n::GetDictionariesForLocale(const std::string& locale) { return g_L10n.GetDictionariesForLocale(locale); } -std::string JSI_L10n::GetLocaleLanguage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +std::string JSI_L10n::GetLocaleLanguage(const std::string& locale) { return g_L10n.GetLocaleLanguage(locale); } -std::string JSI_L10n::GetLocaleBaseName(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +std::string JSI_L10n::GetLocaleBaseName(const std::string& locale) { return g_L10n.GetLocaleBaseName(locale); } -std::string JSI_L10n::GetLocaleCountry(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +std::string JSI_L10n::GetLocaleCountry(const std::string& locale) { return g_L10n.GetLocaleCountry(locale); } -std::string JSI_L10n::GetLocaleScript(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +std::string JSI_L10n::GetLocaleScript(const std::string& locale) { return g_L10n.GetLocaleScript(locale); } -bool JSI_L10n::ValidateLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +bool JSI_L10n::ValidateLocale(const std::string& locale) { return g_L10n.ValidateLocale(locale); } -bool JSI_L10n::SaveLocale(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& locale) +bool JSI_L10n::SaveLocale(const std::string& locale) { return g_L10n.SaveLocale(locale); } -void JSI_L10n::ReevaluateCurrentLocaleAndReload(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_L10n::ReevaluateCurrentLocaleAndReload() { g_L10n.ReevaluateCurrentLocaleAndReload(); } @@ -159,31 +160,32 @@ 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"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(Translate); + Register(TranslateWithContext); + Register(TranslatePlural); + Register(TranslatePluralWithContext); + Register(TranslateLines); + Register(TranslateArray); + Register(FormatMillisecondsIntoDateStringLocal); + Register(FormatMillisecondsIntoDateStringGMT); + Register(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"); + Register(GetSupportedLocaleBaseNames); + Register(GetSupportedLocaleDisplayNames); + Register(GetCurrentLocale); + Register(GetAllLocales); + Register(GetDictionaryLocale); + Register(GetDictionariesForLocale); - scriptInterface.RegisterFunction("UseLongStrings"); - scriptInterface.RegisterFunction("GetLocaleLanguage"); - scriptInterface.RegisterFunction("GetLocaleBaseName"); - scriptInterface.RegisterFunction("GetLocaleCountry"); - scriptInterface.RegisterFunction("GetLocaleScript"); - scriptInterface.RegisterFunction("GetFallbackToAvailableDictLocale"); + Register(GetLocaleLanguage); + Register(GetLocaleBaseName); + Register(GetLocaleCountry); + Register(GetLocaleScript); + Register(GetFallbackToAvailableDictLocale); - scriptInterface.RegisterFunction("ValidateLocale"); - scriptInterface.RegisterFunction("SaveLocale"); - scriptInterface.RegisterFunction("ReevaluateCurrentLocaleAndReload"); + Register(ValidateLocale); + Register(SaveLocale); + Register(ReevaluateCurrentLocaleAndReload); +#undef Register } Index: source/lobby/scripting/JSInterface_Lobby.h =================================================================== --- source/lobby/scripting/JSInterface_Lobby.h +++ source/lobby/scripting/JSInterface_Lobby.h @@ -27,9 +27,8 @@ { void RegisterScriptFunctions(const ScriptInterface& scriptInterface); - bool HasXmppClient(ScriptInterface::CxPrivate* pCxPrivate); - bool IsRankedGame(ScriptInterface::CxPrivate* pCxPrivate); - void SetRankedGame(ScriptInterface::CxPrivate* pCxPrivate, bool isRanked); + bool HasXmppClient(); + void SetRankedGame(bool isRanked); #if CONFIG2_LOBBY void StartXmppClient(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize); @@ -64,9 +63,6 @@ // 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::CxPrivate* pCxPrivate, const std::wstring& pass, const std::wstring& user); #endif // CONFIG2_LOBBY } Index: source/lobby/scripting/JSInterface_Lobby.cpp =================================================================== --- source/lobby/scripting/JSInterface_Lobby.cpp +++ source/lobby/scripting/JSInterface_Lobby.cpp @@ -26,6 +26,7 @@ #include "ps/CLogger.h" #include "ps/CStr.h" #include "ps/Util.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptVal.h" @@ -35,49 +36,51 @@ void JSI_Lobby::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) // Lobby functions - scriptInterface.RegisterFunction("HasXmppClient"); - scriptInterface.RegisterFunction("SetRankedGame"); + Register(HasXmppClient); + Register(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"); + Register(StartXmppClient); + Register(StartRegisterXmppClient); + Register(StopXmppClient); + Register(ConnectXmppClient); + Register(DisconnectXmppClient); + Register(IsXmppClientConnected); + Register(SendGetBoardList); + Register(SendGetProfile); + Register(SendRegisterGame); + Register(SendGameReport); + Register(SendUnregisterGame); + Register(SendChangeStateGame); + Register(GetPlayerList); + Register(GetGameList); + Register(GetBoardList); + Register(GetProfile); + Register(LobbyGuiPollNewMessages); + Register(LobbyGuiPollHistoricMessages); + Register(LobbyGuiPollHasPlayerListUpdate); + Register(LobbySendMessage); + Register(LobbySetPlayerPresence); + Register(LobbySetNick); + Register(LobbyGetNick); + Register(LobbyKick); + Register(LobbyBan); + Register(LobbyGetPlayerPresence); + Register(LobbyGetPlayerRole); + Register(LobbyGetPlayerRating); + Register(EncryptPassword); + Register(LobbyGetRoomSubject); #endif // CONFIG2_LOBBY +#undef Register } -bool JSI_Lobby::HasXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Lobby::HasXmppClient() { return g_XmppClient; } -void JSI_Lobby::SetRankedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool isRanked) +void JSI_Lobby::SetRankedGame(bool isRanked) { g_rankedGame = isRanked; } @@ -528,11 +531,6 @@ return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase(); } -std::wstring JSI_Lobby::EncryptPassword(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), 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::CxPrivate* pCxPrivate) { if (!g_XmppClient) Index: source/network/scripting/JSInterface_Network.h =================================================================== --- source/network/scripting/JSInterface_Network.h +++ source/network/scripting/JSInterface_Network.h @@ -24,23 +24,23 @@ namespace JSI_Network { - u16 GetDefaultPort(ScriptInterface::CxPrivate* pCxPrivate); - bool HasNetServer(ScriptInterface::CxPrivate* pCxPrivate); - bool HasNetClient(ScriptInterface::CxPrivate* pCxPrivate); - void StartNetworkGame(ScriptInterface::CxPrivate* pCxPrivate); + u16 GetDefaultPort(); + bool HasNetServer(); + bool HasNetClient(); + void StartNetworkGame(); void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1); void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName); void StartNetworkJoin(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID); JS::Value FindStunEndpoint(ScriptInterface::CxPrivate* pCxPrivate, int port); - void DisconnectNetworkGame(ScriptInterface::CxPrivate* pCxPrivate); + void DisconnectNetworkGame(); JS::Value PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate); - CStr GetPlayerGUID(ScriptInterface::CxPrivate* pCxPrivate); - void KickPlayer(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, bool ban); - void AssignNetworkPlayer(ScriptInterface::CxPrivate* pCxPrivate, int playerID, const CStr& guid); - void ClearAllPlayerReady (ScriptInterface::CxPrivate* pCxPrivate); - void SendNetworkChat(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& message); - void SendNetworkReady(ScriptInterface::CxPrivate* pCxPrivate, int message); - void SetTurnLength(ScriptInterface::CxPrivate* pCxPrivate, int length); + CStr GetPlayerGUID(); + void KickPlayer(const CStrW& playerName, bool ban); + void AssignNetworkPlayer(int playerID, const CStr& guid); + void ClearAllPlayerReady (); + void SendNetworkChat(const CStrW& message); + void SendNetworkReady(int message); + void SetTurnLength(int length); void RegisterScriptFunctions(const ScriptInterface& scriptInterface); } Index: source/network/scripting/JSInterface_Network.cpp =================================================================== --- source/network/scripting/JSInterface_Network.cpp +++ source/network/scripting/JSInterface_Network.cpp @@ -30,18 +30,19 @@ #include "ps/CLogger.h" #include "ps/Game.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" -u16 JSI_Network::GetDefaultPort(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +u16 JSI_Network::GetDefaultPort() { return PS_DEFAULT_PORT; } -bool JSI_Network::HasNetServer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Network::HasNetServer() { return g_NetServer; } -bool JSI_Network::HasNetClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Network::HasNetClient() { return g_NetClient; } @@ -132,7 +133,7 @@ } } -void JSI_Network::DisconnectNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Network::DisconnectNetworkGame() { // TODO: we ought to do async reliable disconnections @@ -141,7 +142,7 @@ SAFE_DELETE(g_Game); } -CStr JSI_Network::GetPlayerGUID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +CStr JSI_Network::GetPlayerGUID() { if (!g_NetClient) return "local"; @@ -174,48 +175,48 @@ g_NetClient->SendGameSetupMessage(&attribs, *(pCxPrivate->pScriptInterface)); } -void JSI_Network::AssignNetworkPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int playerID, const CStr& guid) +void JSI_Network::AssignNetworkPlayer(int playerID, const CStr& guid) { ENSURE(g_NetClient); g_NetClient->SendAssignPlayerMessage(playerID, guid); } -void JSI_Network::KickPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& playerName, bool ban) +void JSI_Network::KickPlayer(const CStrW& playerName, bool ban) { ENSURE(g_NetClient); g_NetClient->SendKickPlayerMessage(playerName, ban); } -void JSI_Network::SendNetworkChat(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& message) +void JSI_Network::SendNetworkChat(const CStrW& message) { ENSURE(g_NetClient); g_NetClient->SendChatMessage(message); } -void JSI_Network::SendNetworkReady(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int message) +void JSI_Network::SendNetworkReady(int message) { ENSURE(g_NetClient); g_NetClient->SendReadyMessage(message); } -void JSI_Network::ClearAllPlayerReady (ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Network::ClearAllPlayerReady () { ENSURE(g_NetClient); g_NetClient->SendClearAllReadyMessage(); } -void JSI_Network::StartNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Network::StartNetworkGame() { ENSURE(g_NetClient); g_NetClient->SendStartGameMessage(); } -void JSI_Network::SetTurnLength(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int length) +void JSI_Network::SetTurnLength(int length) { if (g_NetServer) g_NetServer->SetTurnLength(length); @@ -225,21 +226,23 @@ void JSI_Network::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("GetDefaultPort"); - scriptInterface.RegisterFunction("HasNetServer"); - scriptInterface.RegisterFunction("HasNetClient"); - scriptInterface.RegisterFunction("FindStunEndpoint"); - scriptInterface.RegisterFunction("StartNetworkHost"); - scriptInterface.RegisterFunction("StartNetworkJoin"); - 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"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(GetDefaultPort); + Register(HasNetServer); + Register(HasNetClient); + Register(FindStunEndpoint); + Register(StartNetworkHost); + Register(StartNetworkJoin); + Register(DisconnectNetworkGame); + Register(GetPlayerGUID); + Register(PollNetworkClient); + Register(SetNetworkGameAttributes); + Register(AssignNetworkPlayer); + Register(KickPlayer); + Register(SendNetworkChat); + Register(SendNetworkReady); + Register(ClearAllPlayerReady); + Register(StartNetworkGame); + Register(SetTurnLength); +#undef Register } Index: source/ps/GameSetup/HWDetect.cpp =================================================================== --- source/ps/GameSetup/HWDetect.cpp +++ source/ps/GameSetup/HWDetect.cpp @@ -44,6 +44,7 @@ #include "ps/scripting/JSInterface_Debug.h" #include "ps/UserReport.h" #include "ps/VideoMode.h" +#include "scriptinterface/FunctionWrapper.h" // TODO: Support OpenGL platforms which don’t use GLX as well. #if defined(SDL_VIDEO_DRIVER_X11) && !CONFIG2_GLES @@ -141,7 +142,7 @@ return !(ns == CFG_LAST || ns == CFG_DEFAULT); } -void SetDisableAudio(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled) +void SetDisableAudio(bool disabled) { g_DisableAudio = disabled; } @@ -157,7 +158,7 @@ JSI_Debug::RegisterScriptFunctions(scriptInterface); // Engine.DisplayErrorDialog JSI_ConfigDB::RegisterScriptFunctions(scriptInterface); - scriptInterface.RegisterFunction("SetDisableAudio"); + ScriptWrapper::WrapAndRegister(scriptInterface, "SetDisableAudio"); // Load the detection script: Index: source/ps/scripting/JSInterface_ConfigDB.h =================================================================== --- source/ps/scripting/JSInterface_ConfigDB.h +++ source/ps/scripting/JSInterface_ConfigDB.h @@ -27,16 +27,16 @@ { bool IsProtectedConfigName(const std::string& name); bool GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs); - bool HasChanges(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString); - bool SetChanges(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, bool value); - std::string GetValue(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name); - bool CreateValue(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value); - bool RemoveValue(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name); - bool WriteFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const Path& path); - bool WriteValueToFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path); - void CreateAndWriteValueToFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path); - bool Reload(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString); - bool SetFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const Path& path); + bool HasChanges(const std::wstring& cfgNsString); + bool SetChanges(const std::wstring& cfgNsString, bool value); + std::string GetValue(const std::wstring& cfgNsString, const std::string& name); + bool CreateValue(const std::wstring& cfgNsString, const std::string& name, const std::string& value); + bool RemoveValue(const std::wstring& cfgNsString, const std::string& name); + bool WriteFile(const std::wstring& cfgNsString, const Path& path); + bool WriteValueToFile(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); + bool Reload(const std::wstring& cfgNsString); + bool SetFile(const std::wstring& cfgNsString, const Path& path); void RegisterScriptFunctions(const ScriptInterface& scriptInterface); } Index: source/ps/scripting/JSInterface_ConfigDB.cpp =================================================================== --- source/ps/scripting/JSInterface_ConfigDB.cpp +++ source/ps/scripting/JSInterface_ConfigDB.cpp @@ -22,6 +22,7 @@ #include "ps/ConfigDB.h" #include "ps/CLogger.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #include #include @@ -66,7 +67,7 @@ return true; } -bool JSI_ConfigDB::HasChanges(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString) +bool JSI_ConfigDB::HasChanges(const std::wstring& cfgNsString) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -75,7 +76,7 @@ return g_ConfigDB.HasChanges(cfgNs); } -bool JSI_ConfigDB::SetChanges(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, bool value) +bool JSI_ConfigDB::SetChanges(const std::wstring& cfgNsString, bool value) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -85,7 +86,7 @@ return true; } -std::string JSI_ConfigDB::GetValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const std::string& name) +std::string JSI_ConfigDB::GetValue(const std::wstring& cfgNsString, const std::string& name) { if (IsProtectedConfigName(name)) return ""; @@ -99,7 +100,7 @@ return value; } -bool JSI_ConfigDB::CreateValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const std::string& name, const std::string& value) +bool JSI_ConfigDB::CreateValue(const std::wstring& cfgNsString, const std::string& name, const std::string& value) { if (IsProtectedConfigName(name)) return false; @@ -112,7 +113,7 @@ return true; } -bool JSI_ConfigDB::RemoveValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const std::string& name) +bool JSI_ConfigDB::RemoveValue(const std::wstring& cfgNsString, const std::string& name) { if (IsProtectedConfigName(name)) return false; @@ -125,7 +126,7 @@ return true; } -bool JSI_ConfigDB::WriteFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const Path& path) +bool JSI_ConfigDB::WriteFile(const std::wstring& cfgNsString, const Path& path) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -134,7 +135,7 @@ return g_ConfigDB.WriteFile(cfgNs, path); } -bool JSI_ConfigDB::WriteValueToFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) +bool JSI_ConfigDB::WriteValueToFile(const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) { if (IsProtectedConfigName(name)) return false; @@ -146,13 +147,13 @@ return g_ConfigDB.WriteValueToFile(cfgNs, name, value, path); } -void JSI_ConfigDB::CreateAndWriteValueToFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) +void JSI_ConfigDB::CreateAndWriteValueToFile(const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) { - CreateValue(pCxPrivate, cfgNsString, name, value); - WriteValueToFile(pCxPrivate, cfgNsString, name, value, path); + CreateValue(cfgNsString, name, value); + WriteValueToFile(cfgNsString, name, value, path); } -bool JSI_ConfigDB::Reload(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString) +bool JSI_ConfigDB::Reload(const std::wstring& cfgNsString) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -161,7 +162,7 @@ return g_ConfigDB.Reload(cfgNs); } -bool JSI_ConfigDB::SetFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const Path& path) +bool JSI_ConfigDB::SetFile(const std::wstring& cfgNsString, const Path& path) { EConfigNamespace cfgNs; if (!GetConfigNamespace(cfgNsString, cfgNs)) @@ -173,14 +174,16 @@ void JSI_ConfigDB::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("ConfigDB_HasChanges"); - scriptInterface.RegisterFunction("ConfigDB_SetChanges"); - scriptInterface.RegisterFunction("ConfigDB_GetValue"); - scriptInterface.RegisterFunction("ConfigDB_CreateValue"); - scriptInterface.RegisterFunction("ConfigDB_RemoveValue"); - scriptInterface.RegisterFunction("ConfigDB_WriteFile"); - scriptInterface.RegisterFunction("ConfigDB_WriteValueToFile"); - scriptInterface.RegisterFunction("ConfigDB_CreateAndWriteValueToFile"); - scriptInterface.RegisterFunction("ConfigDB_SetFile"); - scriptInterface.RegisterFunction("ConfigDB_Reload"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, "ConfigDB_" #name) + Register(HasChanges); + Register(SetChanges); + Register(GetValue); + Register(CreateValue); + Register(RemoveValue); + Register(WriteFile); + Register(WriteValueToFile); + Register(CreateAndWriteValueToFile); + Register(SetFile); + Register(Reload); +#undef Register } Index: source/ps/scripting/JSInterface_Console.h =================================================================== --- source/ps/scripting/JSInterface_Console.h +++ source/ps/scripting/JSInterface_Console.h @@ -23,8 +23,8 @@ namespace JSI_Console { bool CheckGlobalInitialized(); - bool GetVisibleEnabled(ScriptInterface::CxPrivate* pCxPrivate); - void SetVisibleEnabled(ScriptInterface::CxPrivate* pCxPrivate, bool Enabled); + bool GetVisibleEnabled(); + void SetVisibleEnabled(bool Enabled); void RegisterScriptFunctions(const ScriptInterface& scriptInterface); } Index: source/ps/scripting/JSInterface_Console.cpp =================================================================== --- source/ps/scripting/JSInterface_Console.cpp +++ source/ps/scripting/JSInterface_Console.cpp @@ -22,6 +22,7 @@ #include "ps/CConsole.h" #include "ps/CLogger.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" bool JSI_Console::CheckGlobalInitialized() { @@ -33,14 +34,14 @@ return true; } -bool JSI_Console::GetVisibleEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Console::GetVisibleEnabled() { if (!CheckGlobalInitialized()) return false; return g_Console->IsActive(); } -void JSI_Console::SetVisibleEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool Enabled) +void JSI_Console::SetVisibleEnabled(bool Enabled) { if (!CheckGlobalInitialized()) return; @@ -49,6 +50,6 @@ void JSI_Console::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("Console_GetVisibleEnabled"); - scriptInterface.RegisterFunction("Console_SetVisibleEnabled"); + ScriptWrapper::WrapAndRegister(scriptInterface, "Console_GetVisibleEnabled"); + ScriptWrapper::WrapAndRegister(scriptInterface, "Console_SetVisibleEnabled"); } Index: source/ps/scripting/JSInterface_Debug.h =================================================================== --- source/ps/scripting/JSInterface_Debug.h +++ source/ps/scripting/JSInterface_Debug.h @@ -24,13 +24,13 @@ namespace JSI_Debug { - int Crash(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); - void DebugWarn(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); - void DisplayErrorDialog(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& msg); - std::wstring GetBuildDate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); - double GetBuildTimestamp(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); - std::wstring GetBuildRevision(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); - double GetMicroseconds(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)); + int Crash(); + void DebugWarn(); + void DisplayErrorDialog(const std::wstring& msg); + std::wstring GetBuildDate(); + double GetBuildTimestamp(); + std::wstring GetBuildRevision(); + double GetMicroseconds(); void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); } Index: source/ps/scripting/JSInterface_Debug.cpp =================================================================== --- source/ps/scripting/JSInterface_Debug.cpp +++ source/ps/scripting/JSInterface_Debug.cpp @@ -23,13 +23,14 @@ #include "lib/svn_revision.h" #include "lib/debug.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #include /** * Microseconds since the epoch. */ -double JSI_Debug::GetMicroseconds(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +double JSI_Debug::GetMicroseconds() { return JS_Now(); } @@ -37,18 +38,18 @@ // 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::CxPrivate* UNUSED(pCxPrivate)) +int JSI_Debug::Crash() { debug_printf("Crashing at user's request.\n"); return *(volatile int*)0; } -void JSI_Debug::DebugWarn(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Debug::DebugWarn() { debug_warn(L"Warning at user's request."); } -void JSI_Debug::DisplayErrorDialog(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& msg) +void JSI_Debug::DisplayErrorDialog(const std::wstring& msg) { debug_DisplayError(msg.c_str(), DE_NO_DEBUG_INFO, NULL, NULL, NULL, 0, NULL, NULL); } @@ -57,13 +58,13 @@ // - 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::CxPrivate* UNUSED(pCxPrivate)) +std::wstring JSI_Debug::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::CxPrivate* UNUSED(pCxPrivate)) +double JSI_Debug::GetBuildTimestamp() { UDate buildDate = g_L10n.ParseDateTime(__DATE__ " " __TIME__, "MMM d yyyy HH:mm:ss", icu::Locale::getUS()); if (buildDate) @@ -76,7 +77,7 @@ // 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::CxPrivate* UNUSED(pCxPrivate)) +std::wstring JSI_Debug::GetBuildRevision() { std::wstring svnRevision(svn_revision); if (svnRevision == L"custom build") @@ -86,11 +87,13 @@ void JSI_Debug::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("GetMicroseconds"); - scriptInterface.RegisterFunction("Crash"); - scriptInterface.RegisterFunction("DebugWarn"); - scriptInterface.RegisterFunction("DisplayErrorDialog"); - scriptInterface.RegisterFunction("GetBuildDate"); - scriptInterface.RegisterFunction("GetBuildTimestamp"); - scriptInterface.RegisterFunction("GetBuildRevision"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(GetMicroseconds); + Register(Crash); + Register(DebugWarn); + Register(DisplayErrorDialog); + Register(GetBuildDate); + Register(GetBuildTimestamp); + Register(GetBuildRevision); +#undef Register } Index: source/ps/scripting/JSInterface_Game.h =================================================================== --- source/ps/scripting/JSInterface_Game.h +++ source/ps/scripting/JSInterface_Game.h @@ -22,21 +22,21 @@ namespace JSI_Game { - bool IsGameStarted(ScriptInterface::CxPrivate* pCxPrivate); + bool IsGameStarted(); void StartGame(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs, int playerID); - void Script_EndGame(ScriptInterface::CxPrivate* pCxPrivate); - int GetPlayerID(ScriptInterface::CxPrivate* pCxPrivate); - void SetPlayerID(ScriptInterface::CxPrivate* pCxPrivate, int id); - void SetViewedPlayer(ScriptInterface::CxPrivate* pCxPrivate, int id); - float GetSimRate(ScriptInterface::CxPrivate* pCxPrivate); - void SetSimRate(ScriptInterface::CxPrivate* pCxPrivate, float rate); + void Script_EndGame(); + int GetPlayerID(); + void SetPlayerID(int id); + void SetViewedPlayer(int id); + float GetSimRate(); + void SetSimRate(float rate); bool IsPaused(ScriptInterface::CxPrivate* pCxPrivate); void SetPaused(ScriptInterface::CxPrivate* pCxPrivate, bool pause, bool sendMessage); - bool IsVisualReplay(ScriptInterface::CxPrivate* pCxPrivate); - std::wstring GetCurrentReplayDirectory(ScriptInterface::CxPrivate* pCxPrivate); - void RewindTimeWarp(ScriptInterface::CxPrivate* pCxPrivate); - void EnableTimeWarpRecording(ScriptInterface::CxPrivate* pCxPrivate, unsigned int numTurns); - void DumpTerrainMipmap(ScriptInterface::CxPrivate* pCxPrivate); + bool IsVisualReplay(); + std::wstring GetCurrentReplayDirectory(); + void RewindTimeWarp(); + void EnableTimeWarpRecording(unsigned int numTurns); + void DumpTerrainMipmap(); void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); } Index: source/ps/scripting/JSInterface_Game.cpp =================================================================== --- source/ps/scripting/JSInterface_Game.cpp +++ source/ps/scripting/JSInterface_Game.cpp @@ -27,13 +27,14 @@ #include "ps/Replay.h" #include "ps/World.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #include "simulation2/system/TurnManager.h" #include "simulation2/Simulation2.h" #include "soundmanager/SoundManager.h" extern void EndGame(); -bool JSI_Game::IsGameStarted(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Game::IsGameStarted() { return g_Game; } @@ -58,12 +59,12 @@ g_Game->StartGame(&gameAttribs, ""); } -void JSI_Game::Script_EndGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Game::Script_EndGame() { EndGame(); } -int JSI_Game::GetPlayerID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +int JSI_Game::GetPlayerID() { if (!g_Game) return -1; @@ -71,7 +72,7 @@ return g_Game->GetPlayerID(); } -void JSI_Game::SetPlayerID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int id) +void JSI_Game::SetPlayerID(int id) { if (!g_Game) return; @@ -79,7 +80,7 @@ g_Game->SetPlayerID(id); } -void JSI_Game::SetViewedPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int id) +void JSI_Game::SetViewedPlayer(int id) { if (!g_Game) return; @@ -87,12 +88,12 @@ g_Game->SetViewedPlayerID(id); } -float JSI_Game::GetSimRate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +float JSI_Game::GetSimRate() { return g_Game->GetSimRate(); } -void JSI_Game::SetSimRate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float rate) +void JSI_Game::SetSimRate(float rate) { g_Game->SetSimRate(rate); } @@ -131,7 +132,7 @@ g_NetClient->SendPausedMessage(pause); } -bool JSI_Game::IsVisualReplay(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Game::IsVisualReplay() { if (!g_Game) return false; @@ -139,7 +140,7 @@ return g_Game->IsVisualReplay(); } -std::wstring JSI_Game::GetCurrentReplayDirectory(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::wstring JSI_Game::GetCurrentReplayDirectory() { if (!g_Game) return std::wstring(); @@ -150,17 +151,17 @@ return g_Game->GetReplayLogger().GetDirectory().Filename().string(); } -void JSI_Game::EnableTimeWarpRecording(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), unsigned int numTurns) +void JSI_Game::EnableTimeWarpRecording(unsigned int numTurns) { g_Game->GetTurnManager()->EnableTimeWarpRecording(numTurns); } -void JSI_Game::RewindTimeWarp(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Game::RewindTimeWarp() { g_Game->GetTurnManager()->RewindTimeWarp(); } -void JSI_Game::DumpTerrainMipmap(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Game::DumpTerrainMipmap() { VfsPath filename(L"screenshots/terrainmipmap.png"); g_Game->GetWorld()->GetTerrain()->GetHeightMipmap().DumpToDisk(filename); @@ -171,19 +172,21 @@ void JSI_Game::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - 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"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(IsGameStarted); + Register(StartGame); + Register(EndGame); + Register(GetPlayerID); + Register(SetPlayerID); + Register(SetViewedPlayer); + Register(GetSimRate); + Register(SetSimRate); + Register(IsPaused); + Register(SetPaused); + Register(IsVisualReplay); + Register(GetCurrentReplayDirectory); + Register(EnableTimeWarpRecording); + Register(RewindTimeWarp); + Register(DumpTerrainMipmap); +#undef Register } Index: source/ps/scripting/JSInterface_Main.h =================================================================== --- source/ps/scripting/JSInterface_Main.h +++ source/ps/scripting/JSInterface_Main.h @@ -22,18 +22,18 @@ namespace JSI_Main { - void QuitEngine(ScriptInterface::CxPrivate* pCxPrivate); - void StartAtlas(ScriptInterface::CxPrivate* pCxPrivate); - bool AtlasIsAvailable(ScriptInterface::CxPrivate* pCxPrivate); - bool IsAtlasRunning(ScriptInterface::CxPrivate* pCxPrivate); - void OpenURL(ScriptInterface::CxPrivate* pCxPrivate, const std::string& url); - std::wstring GetSystemUsername(ScriptInterface::CxPrivate* pCxPrivate); - std::wstring GetMatchID(ScriptInterface::CxPrivate* pCxPrivate); + void QuitEngine(); + void StartAtlas(); + bool AtlasIsAvailable(); + bool IsAtlasRunning(); + void OpenURL(const std::string& url); + std::wstring GetSystemUsername(); + std::wstring GetMatchID(); JS::Value LoadMapSettings(ScriptInterface::CxPrivate* pCxPrivate, const VfsPath& pathname); - bool HotkeyIsPressed_(ScriptInterface::CxPrivate* pCxPrivate, const std::string& hotkeyName); - int GetFps(ScriptInterface::CxPrivate* pCxPrivate); - int GetTextWidth(ScriptInterface::CxPrivate* pCxPrivate, const std::string& fontName, const std::wstring& text); - std::string CalculateMD5(ScriptInterface::CxPrivate* pCxPrivate, const std::string& input); + bool HotkeyIsPressed_(const std::string& hotkeyName); + int GetFps(); + int GetTextWidth(const std::string& fontName, const std::wstring& text); + std::string CalculateMD5(const std::string& input); void RegisterScriptFunctions(const ScriptInterface& scriptInterface); } Index: source/ps/scripting/JSInterface_Main.cpp =================================================================== --- source/ps/scripting/JSInterface_Main.cpp +++ source/ps/scripting/JSInterface_Main.cpp @@ -31,42 +31,43 @@ #include "ps/Hotkey.h" #include "ps/Util.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #include "tools/atlas/GameInterface/GameLoop.h" extern void QuitEngine(); extern void StartAtlas(); -void JSI_Main::QuitEngine(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Main::QuitEngine() { ::QuitEngine(); } -void JSI_Main::StartAtlas(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Main::StartAtlas() { ::StartAtlas(); } -bool JSI_Main::AtlasIsAvailable(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Main::AtlasIsAvailable() { return ATLAS_IsAvailable(); } -bool JSI_Main::IsAtlasRunning(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_Main::IsAtlasRunning() { return g_AtlasGameLoop && g_AtlasGameLoop->running; } -void JSI_Main::OpenURL(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& url) +void JSI_Main::OpenURL(const std::string& url) { sys_open_url(url); } -std::wstring JSI_Main::GetSystemUsername(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::wstring JSI_Main::GetSystemUsername() { return sys_get_user_name(); } -std::wstring JSI_Main::GetMatchID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::wstring JSI_Main::GetMatchID() { return ps_generate_guid().FromUTF8(); } @@ -86,14 +87,14 @@ return settings; } -bool JSI_Main::HotkeyIsPressed_(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& hotkeyName) +bool JSI_Main::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::CxPrivate* UNUSED(pCxPrivate)) +int JSI_Main::GetFps() { if (!g_frequencyFilter) return 0; @@ -101,7 +102,7 @@ return g_frequencyFilter->StableFrequency(); } -int JSI_Main::GetTextWidth(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& fontName, const std::wstring& text) +int JSI_Main::GetTextWidth(const std::string& fontName, const std::wstring& text) { int width = 0; int height = 0; @@ -111,7 +112,7 @@ return width; } -std::string JSI_Main::CalculateMD5(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& input) +std::string JSI_Main::CalculateMD5(const std::string& input) { u8 digest[MD5::DIGESTSIZE]; @@ -124,16 +125,18 @@ void JSI_Main::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - 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"); + ScriptWrapper::WrapAndRegister(scriptInterface, "Exit"); + ScriptWrapper::WrapAndRegister(scriptInterface, "RestartInAtlas"); + ScriptWrapper::WrapAndRegister(scriptInterface, "GetFPS"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(AtlasIsAvailable); + Register(IsAtlasRunning); + Register(OpenURL); + Register(GetSystemUsername); + Register(GetMatchID); + Register(LoadMapSettings); + Register(HotkeyIsPressed); + Register(GetTextWidth); + Register(CalculateMD5); +#undef Register } Index: source/ps/scripting/JSInterface_Mod.h =================================================================== --- source/ps/scripting/JSInterface_Mod.h +++ source/ps/scripting/JSInterface_Mod.h @@ -27,8 +27,8 @@ JS::Value GetEngineInfo(ScriptInterface::CxPrivate* pCxPrivate); JS::Value GetAvailableMods(ScriptInterface::CxPrivate* pCxPrivate); - void RestartEngine(ScriptInterface::CxPrivate* pCxPrivate); - void SetMods(ScriptInterface::CxPrivate* pCxPrivate, const std::vector& mods); + void RestartEngine(); + void SetMods(const std::vector& mods); } #endif // INCLUDED_JSI_MOD Index: source/ps/scripting/JSInterface_Mod.cpp =================================================================== --- source/ps/scripting/JSInterface_Mod.cpp +++ source/ps/scripting/JSInterface_Mod.cpp @@ -21,6 +21,7 @@ #include "ps/Mod.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" extern void RestartEngine(); @@ -44,20 +45,20 @@ return Mod::GetAvailableMods(*(pCxPrivate->pScriptInterface)); } -void JSI_Mod::RestartEngine(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Mod::RestartEngine() { ::RestartEngine(); } -void JSI_Mod::SetMods(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::vector& mods) +void JSI_Mod::SetMods(const std::vector& mods) { g_modsLoaded = mods; } void JSI_Mod::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("GetEngineInfo"); - scriptInterface.RegisterFunction("GetAvailableMods"); - scriptInterface.RegisterFunction("RestartEngine"); - scriptInterface.RegisterFunction, &JSI_Mod::SetMods>("SetMods"); + ScriptWrapper::WrapAndRegister(scriptInterface, "GetEngineInfo"); + ScriptWrapper::WrapAndRegister(scriptInterface, "GetAvailableMods"); + ScriptWrapper::WrapAndRegister(scriptInterface, "RestartEngine"); + ScriptWrapper::WrapAndRegister(scriptInterface, "SetMods"); } Index: source/ps/scripting/JSInterface_ModIo.h =================================================================== --- source/ps/scripting/JSInterface_ModIo.h +++ source/ps/scripting/JSInterface_ModIo.h @@ -24,11 +24,11 @@ { void RegisterScriptFunctions(const ScriptInterface& scriptInterface); - void StartGetGameId(ScriptInterface::CxPrivate* pCxPrivate); - void StartListMods(ScriptInterface::CxPrivate* pCxPrivate); - void StartDownloadMod(ScriptInterface::CxPrivate* pCxPrivate, uint32_t idx); + void StartGetGameId(); + void StartListMods(); + void StartDownloadMod(uint32_t idx); bool AdvanceRequest(ScriptInterface::CxPrivate* pCxPrivate); - void CancelRequest(ScriptInterface::CxPrivate* pCxPrivate); + void CancelRequest(); JS::Value GetMods(ScriptInterface::CxPrivate* pCxPrivate); JS::Value GetDownloadProgress(ScriptInterface::CxPrivate* pCxPrivate); } Index: source/ps/scripting/JSInterface_ModIo.cpp =================================================================== --- source/ps/scripting/JSInterface_ModIo.cpp +++ source/ps/scripting/JSInterface_ModIo.cpp @@ -21,8 +21,9 @@ #include "ps/CLogger.h" #include "ps/ModIo.h" +#include "scriptinterface/FunctionWrapper.h" -void JSI_ModIo::StartGetGameId(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_ModIo::StartGetGameId() { if (!g_ModIo) g_ModIo = new ModIo(); @@ -32,7 +33,7 @@ g_ModIo->StartGetGameId(); } -void JSI_ModIo::StartListMods(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_ModIo::StartListMods() { if (!g_ModIo) { @@ -43,7 +44,7 @@ g_ModIo->StartListMods(); } -void JSI_ModIo::StartDownloadMod(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), uint32_t idx) +void JSI_ModIo::StartDownloadMod(uint32_t idx) { if (!g_ModIo) { @@ -66,7 +67,7 @@ return g_ModIo->AdvanceRequest(*scriptInterface); } -void JSI_ModIo::CancelRequest(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_ModIo::CancelRequest() { if (!g_ModIo) { @@ -149,11 +150,13 @@ void JSI_ModIo::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("ModIoStartGetGameId"); - scriptInterface.RegisterFunction("ModIoStartListMods"); - scriptInterface.RegisterFunction("ModIoStartDownloadMod"); - scriptInterface.RegisterFunction("ModIoAdvanceRequest"); - scriptInterface.RegisterFunction("ModIoCancelRequest"); - scriptInterface.RegisterFunction("ModIoGetMods"); - scriptInterface.RegisterFunction("ModIoGetDownloadProgress"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, "ModIo" #name) + Register(StartGetGameId); + Register(StartListMods); + Register(StartDownloadMod); + Register(AdvanceRequest); + Register(CancelRequest); + Register(GetMods); + Register(GetDownloadProgress); +#undef Register } Index: source/ps/scripting/JSInterface_SavedGame.h =================================================================== --- source/ps/scripting/JSInterface_SavedGame.h +++ source/ps/scripting/JSInterface_SavedGame.h @@ -23,11 +23,11 @@ namespace JSI_SavedGame { JS::Value GetSavedGames(ScriptInterface::CxPrivate* pCxPrivate); - bool DeleteSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name); + bool DeleteSavedGame(const std::wstring& name); void SaveGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata); void SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata); - void QuickSave(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue GUIMetadata); - void QuickLoad(ScriptInterface::CxPrivate* pCxPrivate); + void QuickSave(JS::HandleValue GUIMetadata); + void QuickLoad(); JS::Value StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name); void RegisterScriptFunctions(const ScriptInterface& scriptInterface); Index: source/ps/scripting/JSInterface_SavedGame.cpp =================================================================== --- source/ps/scripting/JSInterface_SavedGame.cpp +++ source/ps/scripting/JSInterface_SavedGame.cpp @@ -25,6 +25,7 @@ #include "ps/Game.h" #include "ps/SavedGame.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #include "simulation2/Simulation2.h" #include "simulation2/system/TurnManager.h" @@ -33,7 +34,7 @@ return SavedGames::GetSavedGames(*(pCxPrivate->pScriptInterface)); } -bool JSI_SavedGame::DeleteSavedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& name) +bool JSI_SavedGame::DeleteSavedGame(const std::wstring& name) { return SavedGames::DeleteSavedGame(name); } @@ -52,7 +53,7 @@ LOGERROR("Failed to save game"); } -void JSI_SavedGame::QuickSave(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), JS::HandleValue GUIMetadata) +void JSI_SavedGame::QuickSave(JS::HandleValue GUIMetadata) { if (g_NetServer || g_NetClient) LOGERROR("Can't store quicksave during multiplayer!"); @@ -62,7 +63,7 @@ LOGERROR("Can't store quicksave if game is not running!"); } -void JSI_SavedGame::QuickLoad(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_SavedGame::QuickLoad() { if (g_NetServer || g_NetClient) LOGERROR("Can't load quicksave during multiplayer!"); @@ -117,11 +118,13 @@ void JSI_SavedGame::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("GetSavedGames"); - scriptInterface.RegisterFunction("DeleteSavedGame"); - scriptInterface.RegisterFunction("SaveGame"); - scriptInterface.RegisterFunction("SaveGamePrefix"); - scriptInterface.RegisterFunction("QuickSave"); - scriptInterface.RegisterFunction("QuickLoad"); - scriptInterface.RegisterFunction("StartSavedGame"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(GetSavedGames); + Register(DeleteSavedGame); + Register(SaveGame); + Register(SaveGamePrefix); + Register(QuickSave); + Register(QuickLoad); + Register(StartSavedGame); +#undef Register } Index: source/ps/scripting/JSInterface_UserReport.h =================================================================== --- source/ps/scripting/JSInterface_UserReport.h +++ source/ps/scripting/JSInterface_UserReport.h @@ -24,11 +24,11 @@ namespace JSI_UserReport { - bool IsUserReportEnabled(ScriptInterface::CxPrivate* pCxPrivate); - void SetUserReportEnabled(ScriptInterface::CxPrivate* pCxPrivate, bool enabled); - std::string GetUserReportStatus(ScriptInterface::CxPrivate* pCxPrivate); - std::string GetUserReportLogPath(ScriptInterface::CxPrivate* pCxPrivate); - std::string GetUserReportConfigPath(ScriptInterface::CxPrivate* pCxPrivate); + bool IsUserReportEnabled(); + void SetUserReportEnabled(bool enabled); + std::string GetUserReportStatus(); + std::string GetUserReportLogPath(); + std::string GetUserReportConfigPath(); void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); } Index: source/ps/scripting/JSInterface_UserReport.cpp =================================================================== --- source/ps/scripting/JSInterface_UserReport.cpp +++ source/ps/scripting/JSInterface_UserReport.cpp @@ -23,30 +23,31 @@ #include "ps/Pyrogenesis.h" #include "ps/UserReport.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #include -bool JSI_UserReport::IsUserReportEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +bool JSI_UserReport::IsUserReportEnabled() { return g_UserReporter.IsReportingEnabled(); } -void JSI_UserReport::SetUserReportEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool enabled) +void JSI_UserReport::SetUserReportEnabled(bool enabled) { g_UserReporter.SetReportingEnabled(enabled); } -std::string JSI_UserReport::GetUserReportStatus(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::string JSI_UserReport::GetUserReportStatus() { return g_UserReporter.GetStatus(); } -std::string JSI_UserReport::GetUserReportLogPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::string JSI_UserReport::GetUserReportLogPath() { return psLogDir().string8(); } -std::string JSI_UserReport::GetUserReportConfigPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::string JSI_UserReport::GetUserReportConfigPath() { OsPath configPath; WARN_IF_ERR(g_VFS->GetDirectoryRealPath("config/", configPath)); @@ -55,9 +56,11 @@ void JSI_UserReport::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("IsUserReportEnabled"); - scriptInterface.RegisterFunction("SetUserReportEnabled"); - scriptInterface.RegisterFunction("GetUserReportStatus"); - scriptInterface.RegisterFunction("GetUserReportLogPath"); - scriptInterface.RegisterFunction("GetUserReportConfigPath"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(IsUserReportEnabled); + Register(SetUserReportEnabled); + Register(GetUserReportStatus); + Register(GetUserReportLogPath); + Register(GetUserReportConfigPath); +#undef Register } Index: source/ps/scripting/JSInterface_VFS.h =================================================================== --- source/ps/scripting/JSInterface_VFS.h +++ source/ps/scripting/JSInterface_VFS.h @@ -30,10 +30,10 @@ bool FileExists(ScriptInterface::CxPrivate* pCxPrivate, const std::vector& validPaths, const CStrW& filename); // Return time [seconds since 1970] of the last modification to the specified file. - double GetFileMTime(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename); + double GetFileMTime(const std::wstring& filename); // Return current size of file. - unsigned int GetFileSize(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename); + unsigned int GetFileSize(const std::wstring& filename); // Return file contents in a string. JS::Value ReadFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename); Index: source/ps/scripting/JSInterface_VFS.cpp =================================================================== --- source/ps/scripting/JSInterface_VFS.cpp +++ source/ps/scripting/JSInterface_VFS.cpp @@ -25,6 +25,7 @@ #include "ps/Filesystem.h" #include "scriptinterface/ScriptVal.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #include @@ -109,7 +110,7 @@ } // Return time [seconds since 1970] of the last modification to the specified file. -double JSI_VFS::GetFileMTime(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& filename) +double JSI_VFS::GetFileMTime(const std::wstring& filename) { CFileInfo fileInfo; Status err = g_VFS->GetFileInfo(filename, &fileInfo); @@ -119,7 +120,7 @@ } // Return current size of file. -unsigned int JSI_VFS::GetFileSize(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& filename) +unsigned int JSI_VFS::GetFileSize(const std::wstring& filename) { CFileInfo fileInfo; Status err = g_VFS->GetFileInfo(filename, &fileInfo); @@ -254,28 +255,32 @@ VFS_ScriptFunctions(Maps); #undef VFS_ScriptFunctions +#define Register(func, name) ScriptWrapper::WrapAndRegister(scriptInterface, name) + void JSI_VFS::RegisterScriptFunctions_GUI(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("ListDirectoryFiles"); - scriptInterface.RegisterFunction("FileExists"); - scriptInterface.RegisterFunction("GetFileMTime"); - scriptInterface.RegisterFunction("GetFileSize"); - scriptInterface.RegisterFunction("ReadFile"); - scriptInterface.RegisterFunction("ReadFileLines"); - scriptInterface.RegisterFunction("ReadJSONFile"); - scriptInterface.RegisterFunction("WriteJSONFile"); + Register(Script_ListDirectoryFiles_GUI, "ListDirectoryFiles"); + Register(Script_FileExists_GUI, "FileExists"); + Register(JSI_VFS::GetFileMTime, "GetFileMTime"); + Register(JSI_VFS::GetFileSize, "GetFileSize"); + Register(JSI_VFS::ReadFile, "ReadFile"); + Register(JSI_VFS::ReadFileLines, "ReadFileLines"); + Register(Script_ReadJSONFile_GUI, "ReadJSONFile"); + Register(WriteJSONFile, "WriteJSONFile"); } void JSI_VFS::RegisterScriptFunctions_Simulation(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("ListDirectoryFiles"); - scriptInterface.RegisterFunction("FileExists"); - scriptInterface.RegisterFunction("ReadJSONFile"); + Register(Script_ListDirectoryFiles_Simulation, "ListDirectoryFiles"); + Register(Script_FileExists_Simulation, "FileExists"); + Register(Script_ReadJSONFile_Simulation, "ReadJSONFile"); } void JSI_VFS::RegisterScriptFunctions_Maps(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("ListDirectoryFiles"); - scriptInterface.RegisterFunction("FileExists"); - scriptInterface.RegisterFunction("ReadJSONFile"); + Register(Script_ListDirectoryFiles_Maps, "ListDirectoryFiles"); + Register(Script_FileExists_Maps, "FileExists"); + Register(Script_ReadJSONFile_Maps, "ReadJSONFile"); } + +#undef Register Index: source/ps/scripting/JSInterface_VisualReplay.h =================================================================== --- source/ps/scripting/JSInterface_VisualReplay.h +++ source/ps/scripting/JSInterface_VisualReplay.h @@ -22,15 +22,15 @@ namespace JSI_VisualReplay { - bool StartVisualReplay(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directory); - bool DeleteReplay(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& replayFile); + bool StartVisualReplay(const CStrW& directory); + bool DeleteReplay(const CStrW& replayFile); JS::Value GetReplays(ScriptInterface::CxPrivate* pCxPrivate, bool compareFiles); JS::Value GetReplayAttributes(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName); - bool HasReplayMetadata(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName); + bool HasReplayMetadata(const CStrW& directoryName); JS::Value GetReplayMetadata(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName); void AddReplayToCache(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName); void RegisterScriptFunctions(const ScriptInterface& scriptInterface); - CStrW GetReplayDirectoryName(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName); + CStrW GetReplayDirectoryName(const CStrW& directoryName); } #endif // INCLUDED_JSI_VISUALREPLAY Index: source/ps/scripting/JSInterface_VisualReplay.cpp =================================================================== --- source/ps/scripting/JSInterface_VisualReplay.cpp +++ source/ps/scripting/JSInterface_VisualReplay.cpp @@ -22,13 +22,14 @@ #include "ps/CStr.h" #include "ps/VisualReplay.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" -bool JSI_VisualReplay::StartVisualReplay(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& directory) +bool JSI_VisualReplay::StartVisualReplay(const CStrW& directory) { return VisualReplay::StartVisualReplay(directory); } -bool JSI_VisualReplay::DeleteReplay(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& replayFile) +bool JSI_VisualReplay::DeleteReplay(const CStrW& replayFile) { return VisualReplay::DeleteReplay(replayFile); } @@ -43,7 +44,7 @@ return VisualReplay::GetReplayAttributes(pCxPrivate, directoryName); } -bool JSI_VisualReplay::HasReplayMetadata(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& directoryName) +bool JSI_VisualReplay::HasReplayMetadata(const CStrW& directoryName) { return VisualReplay::HasReplayMetadata(directoryName); } @@ -58,19 +59,21 @@ VisualReplay::AddReplayToCache(*(pCxPrivate->pScriptInterface), directoryName); } -CStrW JSI_VisualReplay::GetReplayDirectoryName(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& directoryName) +CStrW JSI_VisualReplay::GetReplayDirectoryName(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"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(GetReplays); + Register(DeleteReplay); + Register(StartVisualReplay); + Register(GetReplayAttributes); + Register(GetReplayMetadata); + Register(HasReplayMetadata); + Register(AddReplayToCache); + Register(GetReplayDirectoryName); +#undef Register } Index: source/renderer/scripting/JSInterface_Renderer.h =================================================================== --- source/renderer/scripting/JSInterface_Renderer.h +++ source/renderer/scripting/JSInterface_Renderer.h @@ -21,16 +21,16 @@ #include "scriptinterface/ScriptInterface.h" #define DECLARE_BOOLEAN_SCRIPT_SETTING(NAME) \ - bool Get##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate); \ - void Set##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate, bool Enabled); + bool Get##NAME##Enabled(); \ + void Set##NAME##Enabled(bool Enabled); namespace JSI_Renderer { - std::string GetRenderPath(ScriptInterface::CxPrivate* pCxPrivate); - void SetRenderPath(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name); - void UpdateAntiAliasingTechnique(ScriptInterface::CxPrivate* pCxPrivate); - void RecreateShadowMap(ScriptInterface::CxPrivate* pCxPrivate); - bool TextureExists(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename); + std::string GetRenderPath(); + void SetRenderPath(const std::string& name); + void UpdateAntiAliasingTechnique(); + void RecreateShadowMap(); + bool TextureExists(const std::wstring& filename); DECLARE_BOOLEAN_SCRIPT_SETTING(Shadows); DECLARE_BOOLEAN_SCRIPT_SETTING(ShadowPCF); Index: source/renderer/scripting/JSInterface_Renderer.cpp =================================================================== --- source/renderer/scripting/JSInterface_Renderer.cpp +++ source/renderer/scripting/JSInterface_Renderer.cpp @@ -25,14 +25,15 @@ #include "renderer/Renderer.h" #include "renderer/ShadowMap.h" #include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/FunctionWrapper.h" #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \ -bool JSI_Renderer::Get##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) \ +bool JSI_Renderer::Get##NAME##Enabled() \ { \ return g_RenderingOptions.Get##NAME(); \ } \ \ -void JSI_Renderer::Set##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool enabled) \ +void JSI_Renderer::Set##NAME##Enabled(bool enabled) \ { \ g_RenderingOptions.Set##NAME(enabled); \ } @@ -57,42 +58,44 @@ #undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING -std::string JSI_Renderer::GetRenderPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::string JSI_Renderer::GetRenderPath() { return RenderPathEnum::ToString(g_RenderingOptions.GetRenderPath()); } -void JSI_Renderer::SetRenderPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& name) +void JSI_Renderer::SetRenderPath(const std::string& name) { g_RenderingOptions.SetRenderPath(RenderPathEnum::FromString(name)); } -void JSI_Renderer::UpdateAntiAliasingTechnique(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Renderer::UpdateAntiAliasingTechnique() { g_Renderer.GetPostprocManager().UpdateAntiAliasingTechnique(); } -void JSI_Renderer::RecreateShadowMap(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Renderer::RecreateShadowMap() { g_Renderer.GetShadowMap().RecreateTexture(); } -bool JSI_Renderer::TextureExists(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& filename) +bool JSI_Renderer::TextureExists(const std::wstring& filename) { return g_Renderer.GetTextureManager().TextureExists(filename); } +#define Register(func, name) ScriptWrapper::WrapAndRegister(scriptInterface, name) + #define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \ -scriptInterface.RegisterFunction("Renderer_Get" #NAME "Enabled"); \ -scriptInterface.RegisterFunction("Renderer_Set" #NAME "Enabled"); +Register(JSI_Renderer::Get##NAME##Enabled, "Renderer_Get" #NAME "Enabled"); \ +Register(JSI_Renderer::Set##NAME##Enabled, "Renderer_Set" #NAME "Enabled"); void JSI_Renderer::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - scriptInterface.RegisterFunction("Renderer_GetRenderPath"); - scriptInterface.RegisterFunction("Renderer_SetRenderPath"); - scriptInterface.RegisterFunction("Renderer_RecreateShadowMap"); - scriptInterface.RegisterFunction("Renderer_UpdateAntiAliasingTechnique"); - scriptInterface.RegisterFunction("TextureExists"); + Register(JSI_Renderer::GetRenderPath, "Renderer_GetRenderPath"); + Register(JSI_Renderer::SetRenderPath, "Renderer_SetRenderPath"); + Register(JSI_Renderer::RecreateShadowMap, "Renderer_RecreateShadowMap"); + Register(JSI_Renderer::UpdateAntiAliasingTechnique, "Renderer_UpdateAntiAliasingTechnique"); + Register(JSI_Renderer::TextureExists, "TextureExists"); REGISTER_BOOLEAN_SCRIPT_SETTING(Shadows); REGISTER_BOOLEAN_SCRIPT_SETTING(ShadowPCF); REGISTER_BOOLEAN_SCRIPT_SETTING(Particles); @@ -113,3 +116,4 @@ } #undef REGISTER_BOOLEAN_SCRIPT_SETTING +#undef Register Index: source/scriptinterface/FunctionWrapper.h =================================================================== --- /dev/null +++ source/scriptinterface/FunctionWrapper.h @@ -0,0 +1,302 @@ +/* Copyright (C) 2020 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#ifndef INCLUDED_FUNCTIONWRAPPER +#define INCLUDED_FUNCTIONWRAPPER + +/** + * This file introduces templates to conveniently wrap C++ functions in JSNative functions, + * and to conveniently call JS functions from C++ code. + * This _is_ rather template heavy, so compilation times beware. + * The C++ code can have arbitrary arguments and arbitrary return types, so long + * as they can be converted to/from JS using ScriptInterface::ToJSVal (FromJSVal respectively). + */ + +#include "ScriptInterface.h" + +// Misconfigured template arguments might lead to code calling this +// (which obviously won't work). +// I can't use a static_assert as that would auto-fire, so don't provide +// the implementation and linking will fail. +template<> inline void* ScriptInterface::getPrivate(JSContext* cx, JS::CallArgs&); + +/** + * Some types can't be default-constructed, and thus can't be used in the magic-template below. + * This in particular concerns HandleValue, which is rather annoying. + * To work around that, we replace HandleValue with a "passthrough" type, and the calling code + * will simply pass the CallArgs value directly. + */ +struct passthrough_t{ + passthrough_t() : t(std::unique_ptr(new JS::HandleValue(JS::NullHandleValue))) {}; + std::unique_ptr t; +}; +template +using is_passthrough = typename std::is_same::value; +template<> inline bool ScriptInterface::FromJSVal(JSContext*, JS::HandleValue val, passthrough_t& o) { + o.t = std::unique_ptr(new JS::HandleValue(val)); + return true; +}; + +/** + * Some functions return JS::Value. One could SFINAE this in call(), but this works too. + */ +template<> +inline void ScriptInterface::ToJSVal(JSContext*, JS::MutableHandleValue ret, const JS::Value& val) +{ + ret.set(val); +} + +namespace ScriptWrapperHelper { + /** + * Convenient struct to get info on a [const] function pointer. + */ + template + struct args_info; + + template + using _args_info_t = std::tuple::value, passthrough_t, Types>::type + >::type>::type...>; + + // TODO: would be nice to find a way around the duplication here. + template + struct args_info + { + static const size_t nb_args = sizeof...(Types); + using return_type = R; + using object_type = C; + using convertible_args = _args_info_t; + }; + + template + struct args_info + { + static const size_t nb_args = sizeof...(Types); + using return_type = R; + using object_type = C; + using convertible_args = _args_info_t; + }; + + template + struct args_info + { + static const size_t nb_args = sizeof...(Types); + using return_type = R; + using object_type = void; + using convertible_args = _args_info_t; + }; + + /** + * Based on https://stackoverflow.com/a/32223343 + * make_index_sequence is not defined in C++11... Only C++14. + * TODO C++14: remove this. + */ + template + struct index_sequence + { + using type = index_sequence; + using value_type = size_t; + static constexpr std::size_t size() noexcept { return sizeof...(Ints); } + }; + template + struct _merge_and_renumber; + template + struct _merge_and_renumber, index_sequence> + : index_sequence { }; + template + struct make_index_sequence + : _merge_and_renumber::type, + typename make_index_sequence::type> { }; + template<> struct make_index_sequence<0> : index_sequence<> { }; + template<> struct make_index_sequence<1> : index_sequence<0> { }; + + /** + * This helper is a recursive template call that converts the N-1th argument + * of the function from a JS value to its proper C++ type. + */ + template + struct convertFromJS + { + bool operator()(ScriptInterface& interface, JSContext* cx, JS::CallArgs& val, tuple& outs) + { + if (index_vals >= val.length()) + { + std::get(outs) = typename std::tuple_element::type{}; + return true; + } + if (!interface.FromJSVal(cx, val[index_vals], std::get(outs))) + return false; + return convertFromJS()(interface, cx, val, outs); + } + }; + // Specialization for the base case "no arguments" -> return True. + template + struct convertFromJS { bool operator()(ScriptInterface&, JSContext*, JS::CallArgs&, tuple&) { return true; } }; + + + // Wrapper around convertFromJS to handle the optional CxPrivate* first argument. + template + static bool convertFromJS2(ScriptInterface& interface, JSContext* cx, JS::CallArgs& val, std::tuple& outs) + { + std::get<0>(outs) = ScriptInterface::GetScriptInterfaceAndCBData(cx); + return convertFromJS<1, 0, N, std::tuple>()(interface, cx, val, outs); + } + + template + static bool convertFromJS2(ScriptInterface& interface, JSContext* cx, JS::CallArgs& val, std::tuple& outs) + { + return convertFromJS<0, 0, N, std::tuple>()(interface, cx, val, outs); + } + + + template + static auto pickVal(T arg) -> typename std::enable_if::value, T>::type { return arg; } + template + static auto pickVal(T arg) -> typename std::enable_if< std::is_same::value, JS::HandleValue>::type { return *arg.t.get(); } + + /** + * These four templates take a function pointer, its arguments, call it, + * and set the return value of the CallArgs to whatever it returned, if anything. + * It's tag-dispatched for the "returns_void" and the regular return case. + */ + template + static void call(T* object, ScriptInterface* scriptInterface, JS::CallArgs& callArgs, std::tuple& args, std::false_type, index_sequence) + { + // This is perfectly readable, what are you talking about. + auto ret = ((*object).* callable)(pickVal(std::move(std::get(args)))...); + scriptInterface->ToJSVal(scriptInterface->GetContext(), callArgs.rval(), ret); + } + + template + static void call(T* object, ScriptInterface* UNUSED(scriptInterface), JS::CallArgs&, std::tuple& args, std::true_type, index_sequence) + { + // Void return specialization, just call the function. + ((*object).* callable)(pickVal(std::move(std::get(args)))...); + } + + // Global-scope variants. This mixes templates and overloading, which is a no-no, but it works. + // TODO C++17: if constexpr would work around this nicely. + template + static void call(void*, ScriptInterface* scriptInterface, JS::CallArgs& callArgs, std::tuple& args, std::false_type, index_sequence) + { + auto ret = (*callable)(pickVal(std::move(std::get(args)))...); + scriptInterface->ToJSVal(scriptInterface->GetContext(), callArgs.rval(), ret); + } + template + static void call(void*, ScriptInterface* UNUSED(scriptInterface), JS::CallArgs&, std::tuple& args, std::true_type, index_sequence) + { + (*callable)(pickVal(std::move(std::get(args)))...); + } + + /** + * Call a c++ function (templateparam callable), on @param object (and if void, in the global scope). + */ + template ::nb_args, typename tuple = typename args_info::convertible_args> + static bool JSToCppCall(JSContext* cx, JS::CallArgs& args, T* object = nullptr) + { + ScriptInterface* scriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; + // This is where the magic happens: instantiate a tuple to store the converted JS arguments, + // then 'unpack' the tuple to call the C++ function, convert & store the return value. + tuple outs; + if (!convertFromJS2(*scriptInterface, cx, args, outs)) + return false; + + static_assert(std::is_same::object_type, T>::value, + "C++ function called from JS with the wrong object type."); + + // TODO: We have limited failure handling here. It's non trivial in a generic sense since we may return a value. + // We could either try-catch and throw exceptions, + // or come C++17 return an std::optional/maybe or some kind of [bool, val] structured binding. + // For now, rely on code calling a JS error, but that's meh for code that doesn't expect to be called from JS. + using returns_void = std::is_same::return_type, void>; + call(object, scriptInterface, args, outs, returns_void{}, make_index_sequence{}); + return !ScriptInterface::IsExceptionPending(cx); + } + + /** + * Call a C++ Function from a JS Function. + * TODO C++14: the first two arguments can be + * TODO C++17: use if-constepxr instead of runtime-if for this. + * (runtime if is necessary as otherwise VS15 gets confused and refuses to compile). + */ + template ::object_type, + ObjType*(*thisGetter)(JSContext* cx, JS::CallArgs& callArgs) = ScriptInterface::getPrivate> + static bool scriptMethod(JSContext* cx, unsigned argc, JS::Value* vp) + { + JSAutoRequest rq(cx); + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + +// GCC complains that thisGetter is always true when the argument is not nullptr, which is what we want +// so de-activate this for now (see todo below). +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Waddress" +#endif + // TODO C++17: this should be if constexpr-ed out (I'm relying on optimisations for now). + ObjType* obj = thisGetter != nullptr ? thisGetter(cx, args) : nullptr; + if (thisGetter != nullptr && !obj) + return false; +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + if (!JSToCppCall(cx, args, obj)) + return false; + + return true; + } +} + +/** + * This could be in the above namespace, but it's convenient to be able to friend these by only early-declaring the class. + */ +class ScriptWrapper +{ + template + using args_info = ScriptWrapperHelper::args_info; +public: + + // flags must be a constant expression so until C++17 template-arguments it is. + template + static JSFunctionSpec Wrap(const char* name) + { + return JS_FN(name, (&ScriptWrapperHelper::scriptMethod), args_info::nb_args, flags); + } + + /** + * Wrap a function, and register it on the root function object (usually 'Engine') + * For global & static function, there is no 'this' computed to call the pointer on. + * For method functors, 'this' is by default computed using getPrivate. + * Otherwise, you can pass your own "this getter". + * This is SFINAE-d for the void case as VS15 does not seem to like ternaries in + * non-type template default arguments. + */ + template ::object_type, typename std::enable_if::value, ObjType*(*)(JSContext* cx, JS::CallArgs& callArgs)>::type thisGetter = ScriptInterface::getPrivate> + static void WrapAndRegister(const ScriptInterface& itf, const char* name) + { + itf.Register(name, &(ScriptWrapperHelper::scriptMethod), args_info::nb_args); + } + template ::object_type, typename std::enable_if::value, ObjType*(*)(JSContext* cx, JS::CallArgs& callArgs)>::type thisGetter = nullptr> + static void WrapAndRegister(const ScriptInterface& itf, const char* name) + { + itf.Register(name, &(ScriptWrapperHelper::scriptMethod), args_info::nb_args); + } +}; + +#endif // INCLUDED_FUNCTIONWRAPPER Index: source/scriptinterface/NativeWrapperDecls.h =================================================================== --- source/scriptinterface/NativeWrapperDecls.h +++ source/scriptinterface/NativeWrapperDecls.h @@ -15,79 +15,6 @@ * along with 0 A.D. If not, see . */ -#include -#include - -// MaybeRef should be private, but has to be public due to a compiler bug in clang. -// TODO: Make this private when the bug is fixed in all supported versions of clang. -template struct MaybeRef; - -// Define lots of useful macros: - -// Varieties of comma-separated list to fit on the head/tail/whole of another comma-separated list -#define NUMBERED_LIST_HEAD(z, i, data) data##i, -#define NUMBERED_LIST_TAIL(z, i, data) ,data##i -#define NUMBERED_LIST_TAIL_MAYBE_REF(z, i, data) , typename MaybeRef::Type -#define NUMBERED_LIST_BALANCED(z, i, data) BOOST_PP_COMMA_IF(i) data##i -#define NUMBERED_LIST_BALANCED_MAYBE_REF(z, i, data) BOOST_PP_COMMA_IF(i) typename MaybeRef::Type - -// TODO: We allow optional parameters when the C++ type can be converted from JS::UndefinedValue. -// FromJSVal is expected to either set a##i or return false (otherwise we could get undefined -// behaviour because some types have undefined values when not being initialized). -// This is not very clear and also a bit fragile. Another problem is that the error reporting lacks -// a bit. SpiderMonkey will throw a JS exception and abort the execution of the current function when -// we return false here (without printing a callstack or additional detail telling that an argument -// conversion failed). So we have two TODOs here: -// 1. On the conceptual side: How to consistently work with optional parameters (or drop them completely?) -// 2. On the technical side: Improve error handling, find a better way to ensure parameters are initialized -#define CONVERT_ARG(z, i, data) \ - bool typeConvRet##i; \ - T##i a##i = ScriptInterface::AssignOrFromJSVal( \ - cx, \ - i < args.length() ? args[i] : JS::UndefinedHandleValue, \ - typeConvRet##i); \ - if (!typeConvRet##i) return false; - -// List-generating macros, named roughly after their first list item -#define TYPENAME_T0_HEAD(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_HEAD, typename T) // "typename T0, typename T1, " -#define T0(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_BALANCED, T) // "T0, T1" -#define T0_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_BALANCED_MAYBE_REF, T) // "const T0&, T1" -#define T0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, T) // ", T0, T1" -#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) \ - template \ - static bool call(JSContext* cx, uint argc, JS::Value* vp); -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS - -// Similar, for class methods -#define OVERLOADS(z, i, data) \ - template \ - static bool callMethod(JSContext* cx, uint argc, JS::Value* vp); -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS - -// const methods -#define OVERLOADS(z, i, data) \ - template \ - static bool callMethodConst(JSContext* cx, uint argc, JS::Value* vp); -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS - // Argument-number counter template static size_t nargs() { return sizeof...(Ts); } Index: source/scriptinterface/NativeWrapperDefns.h =================================================================== --- source/scriptinterface/NativeWrapperDefns.h +++ source/scriptinterface/NativeWrapperDefns.h @@ -15,151 +15,6 @@ * along with 0 A.D. If not, see . */ -// Use the macro below to define types that will be passed by value to C++ functions. -// NOTE: References are used just to avoid superfluous copy constructor calls -// in the script wrapper code. They cannot be used as out-parameters. -// They are const T& by default to avoid confusion about this, especially -// because sometimes the function is not just exposed to scripts, but also -// called from C++ code. - -template struct ScriptInterface::MaybeRef -{ - typedef const T& Type; -}; - -#define PASS_BY_VALUE_IN_NATIVE_WRAPPER(T) \ -template <> struct ScriptInterface::MaybeRef \ -{ \ - typedef T Type; \ -}; \ - -PASS_BY_VALUE_IN_NATIVE_WRAPPER(JS::HandleValue) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(bool) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(int) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(uint8_t) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(uint16_t) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(uint32_t) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(fixed) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(float) -PASS_BY_VALUE_IN_NATIVE_WRAPPER(double) - -#undef PASS_BY_VALUE_IN_NATIVE_WRAPPER - -// This works around a bug in Visual Studio (error C2244 if ScriptInterface:: is included in the -// type specifier of MaybeRef::Type for parameters inside the member function declaration). -// It's probably the bug described here, but I'm not quite sure (at least the example there still -// cause error C2244): -// https://connect.microsoft.com/VisualStudio/feedback/details/611863/vs2010-c-fails-with-error-c2244-gcc-4-3-4-compiles-ok -// -// TODO: When dropping support for VS 2015, check if this bug is still present in the supported -// Visual Studio versions (replace the macro definitions in NativeWrapperDecls.h with these ones, -// remove them from here and check if this causes error C2244 when compiling. -#undef NUMBERED_LIST_TAIL_MAYBE_REF -#undef NUMBERED_LIST_BALANCED_MAYBE_REF -#define NUMBERED_LIST_TAIL_MAYBE_REF(z, i, data) , typename ScriptInterface::MaybeRef::Type -#define NUMBERED_LIST_BALANCED_MAYBE_REF(z, i, data) BOOST_PP_COMMA_IF(i) typename ScriptInterface::MaybeRef::Type - -// (NativeWrapperDecls.h set up a lot of the macros we use here) - -// ScriptInterface_NativeWrapper::call(cx, rval, fptr, args...) will call fptr(cbdata, args...), -// and if T != void then it will store the result in rval: - -// Templated on the return type so void can be handled separately -template -struct ScriptInterface_NativeWrapper -{ - template - static void call(JSContext* cx, JS::MutableHandleValue rval, F fptr, Ts... params) - { - ScriptInterface::AssignOrToJSValUnrooted(cx, rval, fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx), params...)); - } -}; - -// Overloaded to ignore the return value from void functions -template <> -struct ScriptInterface_NativeWrapper -{ - template - static void call(JSContext* cx, JS::MutableHandleValue UNUSED(rval), F fptr, Ts... params) - { - fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx), params...); - } -}; - -// Same idea but for method calls: - -template -struct ScriptInterface_NativeMethodWrapper -{ - template - static void call(JSContext* cx, JS::MutableHandleValue rval, TC* c, F fptr, Ts... params) - { - ScriptInterface::AssignOrToJSValUnrooted(cx, rval, (c->*fptr)(params...)); - } -}; - -template -struct ScriptInterface_NativeMethodWrapper -{ - template - static void call(JSContext* UNUSED(cx), JS::MutableHandleValue UNUSED(rval), TC* c, F fptr, Ts... params) - { - (c->*fptr)(params...); - } -}; - -// JSFastNative-compatible function that wraps the function identified in the template argument list -#define OVERLOADS(z, i, data) \ - template \ - bool ScriptInterface::call(JSContext* cx, uint argc, JS::Value* vp) \ - { \ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \ - JSAutoRequest rq(cx); \ - BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \ - JS::RootedValue rval(cx); \ - ScriptInterface_NativeWrapper::template call(cx, &rval, fptr A0_TAIL(z,i)); \ - args.rval().set(rval); \ - return !ScriptInterface::IsExceptionPending(cx); \ - } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS - -// Same idea but for methods -#define OVERLOADS(z, i, data) \ - template \ - bool ScriptInterface::callMethod(JSContext* cx, uint argc, JS::Value* vp) \ - { \ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \ - JSAutoRequest rq(cx); \ - TC* c = ScriptInterface::GetPrivate(cx, args, CLS); \ - if (! c) return false; \ - BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \ - JS::RootedValue rval(cx); \ - ScriptInterface_NativeMethodWrapper::template call(cx, &rval, c, fptr A0_TAIL(z,i)); \ - args.rval().set(rval); \ - return !ScriptInterface::IsExceptionPending(cx); \ - } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS - -// const methods -#define OVERLOADS(z, i, data) \ - template \ - bool ScriptInterface::callMethodConst(JSContext* cx, uint argc, JS::Value* vp) \ - { \ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \ - JSAutoRequest rq(cx); \ - TC* c = ScriptInterface::GetPrivate(cx, args, CLS); \ - if (! c) return false; \ - BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \ - JS::RootedValue rval(cx); \ - ScriptInterface_NativeMethodWrapper::template call(cx, &rval, c, fptr A0_TAIL(z,i)); \ - args.rval().set(rval); \ - return !ScriptInterface::IsExceptionPending(cx); \ - } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS - template static void AssignOrToJSValHelper(JSContext* cx, JS::AutoValueVector& argv, const T& a, const Ts&... params) { @@ -224,17 +79,3 @@ AssignOrToJSValHelper<0>(cx, argv, params...); return CallFunction_(val, name, argv, &jsRet); } - -// Clean up our mess -#undef NUMBERED_LIST_HEAD -#undef NUMBERED_LIST_TAIL -#undef NUMBERED_LIST_TAIL_MAYBE_REF -#undef NUMBERED_LIST_BALANCED -#undef NUMBERED_LIST_BALANCED_MAYBE_REF -#undef CONVERT_ARG -#undef TYPENAME_T0_HEAD -#undef T0 -#undef T0_MAYBE_REF -#undef T0_TAIL -#undef T0_TAIL_MAYBE_REF -#undef A0_TAIL Index: source/scriptinterface/ScriptInterface.h =================================================================== --- source/scriptinterface/ScriptInterface.h +++ source/scriptinterface/ScriptInterface.h @@ -58,6 +58,8 @@ extern shared_ptr g_ScriptRuntime; +// Early-declare to friend in ScriptInterface. +class ScriptWrapper; /** * Abstraction around a SpiderMonkey JSContext. @@ -71,6 +73,9 @@ { NONCOPYABLE(ScriptInterface); + + friend class ScriptWrapper; + public: /** @@ -263,6 +268,11 @@ */ void ReportError(const char* msg) const; + /** + * Return true if a JS exception is pending. + */ + static bool IsExceptionPending(JSContext* cx); + /** * Load and execute the given script in a new function scope. * @param filename Name for debugging purposes (not used to load the file) @@ -340,6 +350,26 @@ shared_ptr WriteStructuredClone(JS::HandleValue v) const; void ReadStructuredClone(const shared_ptr& ptr, JS::MutableHandleValue ret) const; + /** + * Retrieve the private data field of a JSObject. + * NB: if you know the JSClass, use one of the below instead. + */ + template + static T* getPrivate(JSContext* cx, JS::CallArgs& callArgs) + { + JSAutoRequest rq(cx); + if (!callArgs.thisv().isObject()) + { + JS_ReportError(cx, "Cannot retrieve private JS class data because from a non-object value!"); + return nullptr; + } + JS::RootedObject thisObj(cx, &callArgs.thisv().toObject()); + T* value = static_cast(JS_GetPrivate(thisObj)); + if (value == nullptr && !JS_IsExceptionPending(cx)) + JS_ReportError(cx, "Private data of the given object is null!"); + return value; + } + /** * Retrieve the private data field of a JSObject that is an instance of the given JSClass. */ @@ -431,7 +461,6 @@ bool SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool constant, bool enumerate) const; bool GetProperty_(JS::HandleValue obj, const char* name, JS::MutableHandleValue out) const; bool GetPropertyInt_(JS::HandleValue obj, int name, JS::MutableHandleValue value) const; - static bool IsExceptionPending(JSContext* cx); struct CustomType { Index: source/scriptinterface/ScriptInterface.cpp =================================================================== --- source/scriptinterface/ScriptInterface.cpp +++ source/scriptinterface/ScriptInterface.cpp @@ -399,7 +399,9 @@ { JSAutoRequest rq(m_cx); 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)); + JSFunction* func = JS_DefineFunction(m_cx, nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); + ENSURE(func); + //JS::RootedFunction func(m_cx, func); } ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr& runtime) : Index: source/scriptinterface/tests/test_FunctionWrapper.h =================================================================== --- /dev/null +++ source/scriptinterface/tests/test_FunctionWrapper.h @@ -0,0 +1,165 @@ +/* Copyright (C) 2020 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#include "lib/self_test.h" + +#include "ps/CLogger.h" + +#include "scriptinterface/FunctionWrapper.h" + +static bool simpleGlobalFunctionData = false; +static int setterGlobalFunctionData = 0; +static std::string stringGlobal = ""; + +void simpleGlobalFunction() +{ + simpleGlobalFunctionData = true; +} + +void setterGlobalFunction(int newData) +{ + setterGlobalFunctionData = newData; +} + +int returningGlobalFunction() +{ + return 3; +} + +int fancyReturningGlobalFunction(int data) +{ + return data; +} + +int adderGlobalFunction(int a, int b) +{ + return a + b; +} + +// Some fancier types +void stringSetterGlobalFunction(std::string newData) +{ + stringGlobal = newData; +} + +std::string substrGlobalFunction(std::string a, int start, int len) +{ + return a.substr(start, len); +} + +const JSClass m_PrivateDataClass = { + "m_PrivateDataClass", + JSCLASS_HAS_PRIVATE +}; + + +class TestFunctionWrapper : public CxxTest::TestSuite +{ +public: + std::string m_Data = ""; + + int mySetter(std::string input) + { + m_Data = input; + return m_Data.size(); + } + + void setUp() + { + simpleGlobalFunctionData = false; + setterGlobalFunctionData = 0; + stringGlobal = ""; + } + + void test_simple_functions() + { + ScriptInterface script("Test", "Test", g_ScriptRuntime); + JSAutoRequest rq(script.GetContext()); + + ScriptWrapper::WrapAndRegister(script, "simpleGlobal"); + script.Eval("Test.simpleGlobal()"); + TS_ASSERT_EQUALS(simpleGlobalFunctionData, true); + + ScriptWrapper::WrapAndRegister(script, "setterGlobal"); + script.Eval("Test.setterGlobal(3)"); + TS_ASSERT_EQUALS(setterGlobalFunctionData, 3); + script.Eval("Test.setterGlobal(5)"); + TS_ASSERT_EQUALS(setterGlobalFunctionData, 5); + } + + void test_simple_returns() + { + ScriptInterface script("Test", "Test", g_ScriptRuntime); + JSAutoRequest rq(script.GetContext()); + + ScriptWrapper::WrapAndRegister(script, "setterGlobal"); + + ScriptWrapper::WrapAndRegister(script, "returning"); + ScriptWrapper::WrapAndRegister(script, "fancyReturning"); + ScriptWrapper::WrapAndRegister(script, "adder"); + + TS_ASSERT_EQUALS(setterGlobalFunctionData, 0); + script.Eval("Test.setterGlobal(Test.returning())"); + TS_ASSERT_EQUALS(setterGlobalFunctionData, 3); + script.Eval("Test.setterGlobal(Test.fancyReturning(5))"); + TS_ASSERT_EQUALS(setterGlobalFunctionData, 5); + script.Eval("Test.setterGlobal(Test.adder(5, 4))"); + TS_ASSERT_EQUALS(setterGlobalFunctionData, 9); + } + + void test_strings() + { + ScriptInterface script("Test", "Test", g_ScriptRuntime); + JSAutoRequest rq(script.GetContext()); + + ScriptWrapper::WrapAndRegister(script, "set"); + ScriptWrapper::WrapAndRegister(script, "substr"); + + TS_ASSERT_EQUALS(stringGlobal, ""); + script.Eval("Test.set('fineas')"); + TS_ASSERT_EQUALS(stringGlobal, "fineas"); + script.Eval("Test.set(Test.substr('elem_0_2', 4, 2))"); + TS_ASSERT_EQUALS(stringGlobal, "_0"); + } + + void test_members() + { + ScriptInterface script("Test", "Test", g_ScriptRuntime); + JSContext* cx = script.GetContext(); + JSAutoRequest rq(cx); + + ScriptWrapper::WrapAndRegister(script, "setterGlobal"); + JSFunctionSpec spec[] = { + ScriptWrapper::Wrap("mySetter"), + JS_FS_END + }; + + JS::RootedObject obj(cx, JS_NewObject(cx, &m_PrivateDataClass)); + JS::RootedValue glob(cx, script.GetGlobalObject()); + JS::RootedValue bob(cx); + bob.setObjectOrNull(obj.get()); + script.SetProperty(glob, "bob", bob, false, true); + + JS_DefineFunctions(cx, obj, spec); + JS_SetPrivate(obj, this); + script.Eval("Test.setterGlobal(bob.mySetter('jack'))"); + + TS_ASSERT_EQUALS(setterGlobalFunctionData, 4); + TS_ASSERT_EQUALS(m_Data, "jack"); + + } +}; Index: source/simulation2/components/CCmpAIManager.cpp =================================================================== --- source/simulation2/components/CCmpAIManager.cpp +++ 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 "simulation2/components/ICmpAIInterface.h" #include "simulation2/components/ICmpCommandQueue.h" #include "simulation2/components/ICmpObstructionManager.h" @@ -230,14 +231,18 @@ m_SerializablePrototypes->init(); JS_AddExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), Trace, this); - m_ScriptInterface->RegisterFunction("PostCommand"); - m_ScriptInterface->RegisterFunction("IncludeModule"); - m_ScriptInterface->RegisterFunction("Exit"); + ScriptWrapper::WrapAndRegister(*m_ScriptInterface, "Exit"); - m_ScriptInterface->RegisterFunction("ComputePath"); +#define Register(func, name) \ +ScriptWrapper::WrapAndRegister(*m_ScriptInterface, name); + Register(CAIWorker::PostCommand, "PostCommand"); + Register(CAIWorker::LoadScripts, "IncludeModule"); - m_ScriptInterface->RegisterFunction, u32, u32, u32, CAIWorker::DumpImage>("DumpImage"); - m_ScriptInterface->RegisterFunction("GetTemplate"); + Register(CAIWorker::ComputePath, "ComputePath"); + + Register(CAIWorker::DumpImage, "DumpImage"); + Register(CAIWorker::GetTemplate, "GetTemplate"); +#undef Register JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get())); @@ -250,6 +255,13 @@ JS_RemoveExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), Trace, this); } + static CAIWorker* GetCAIWorkerFromCxPrivateData(JSContext* cx, JS::CallArgs&) + { + ScriptInterface::CxPrivate* pCxPrivate = ScriptInterface::GetScriptInterfaceAndCBData(cx); + ENSURE(pCxPrivate->pCBData); + return static_cast (pCxPrivate->pCBData); + } + bool HasLoadedEntityTemplates() const { return m_HasLoadedEntityTemplates; } bool LoadScripts(const std::wstring& moduleName) @@ -281,20 +293,6 @@ return true; } - static void IncludeModule(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name) - { - ENSURE(pCxPrivate->pCBData); - CAIWorker* self = static_cast (pCxPrivate->pCBData); - self->LoadScripts(name); - } - - static void PostCommand(ScriptInterface::CxPrivate* pCxPrivate, int playerid, JS::HandleValue cmd) - { - ENSURE(pCxPrivate->pCBData); - CAIWorker* self = static_cast (pCxPrivate->pCBData); - self->PostCommand(playerid, cmd); - } - void PostCommand(int playerid, JS::HandleValue cmd) { for (size_t i=0; ipCBData); - CAIWorker* self = static_cast (pCxPrivate->pCBData); - JSContext* cx(self->m_ScriptInterface->GetContext()); - JSAutoRequest rq(cx); - - CFixedVector2D pos, goalPos; - std::vector waypoints; - JS::RootedValue retVal(cx); - - self->m_ScriptInterface->FromJSVal(cx, position, pos); - self->m_ScriptInterface->FromJSVal(cx, goal, goalPos); - - self->ComputePath(pos, goalPos, passClass, waypoints); - self->m_ScriptInterface->ToJSVal >(cx, &retVal, waypoints); - - return retVal; - } - - void ComputePath(const CFixedVector2D& pos, const CFixedVector2D& goal, pass_class_t passClass, std::vector& waypoints) + std::vector ComputePath(const CFixedVector2D& pos, const CFixedVector2D& goal, pass_class_t passClass) { WaypointPath ret; PathGoal pathGoal = { PathGoal::POINT, goal.X, goal.Y }; m_LongPathfinder.ComputePath(m_HierarchicalPathfinder, pos.X, pos.Y, pathGoal, passClass, ret); + std::vector waypoints; for (Waypoint& wp : ret.m_Waypoints) waypoints.emplace_back(wp.x, wp.z); - } - - static CParamNode GetTemplate(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name) - { - ENSURE(pCxPrivate->pCBData); - CAIWorker* self = static_cast (pCxPrivate->pCBData); - - return self->GetTemplate(name); + return waypoints; } CParamNode GetTemplate(const std::string& name) @@ -355,15 +326,10 @@ return m_TemplateLoader.GetTemplateFileData(name).GetChild("Entity"); } - static void ExitProgram(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) - { - QuitEngine(); - } - /** * Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights). */ - static void DumpImage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& name, const std::vector& data, u32 w, u32 h, u32 max) + void DumpImage(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; Index: source/simulation2/components/ICmpAIInterface.cpp =================================================================== --- source/simulation2/components/ICmpAIInterface.cpp +++ source/simulation2/components/ICmpAIInterface.cpp @@ -19,6 +19,8 @@ #include "ICmpAIInterface.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpAIManager.cpp =================================================================== --- source/simulation2/components/ICmpAIManager.cpp +++ source/simulation2/components/ICmpAIManager.cpp @@ -19,15 +19,17 @@ #include "ICmpAIManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "lib/file/vfs/vfs_util.h" #include "ps/Filesystem.h" BEGIN_INTERFACE_WRAPPER(AIManager) -DEFINE_INTERFACE_METHOD_4("AddPlayer", void, ICmpAIManager, AddPlayer, std::wstring, player_id_t, uint8_t, std::wstring) -DEFINE_INTERFACE_METHOD_0("TryLoadSharedComponent", void, ICmpAIManager, TryLoadSharedComponent) -DEFINE_INTERFACE_METHOD_0("RunGamestateInit", void, ICmpAIManager, RunGamestateInit) +DEFINE_INTERFACE_METHOD("AddPlayer", ICmpAIManager, AddPlayer) +DEFINE_INTERFACE_METHOD("TryLoadSharedComponent", ICmpAIManager, TryLoadSharedComponent) +DEFINE_INTERFACE_METHOD("RunGamestateInit", ICmpAIManager, RunGamestateInit) END_INTERFACE_WRAPPER(AIManager) // Implement the static method that finds all AI scripts Index: source/simulation2/components/ICmpAttack.cpp =================================================================== --- source/simulation2/components/ICmpAttack.cpp +++ source/simulation2/components/ICmpAttack.cpp @@ -19,6 +19,8 @@ #include "ICmpAttack.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpCinemaManager.cpp =================================================================== --- source/simulation2/components/ICmpCinemaManager.cpp +++ source/simulation2/components/ICmpCinemaManager.cpp @@ -19,13 +19,15 @@ #include "ICmpCinemaManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(CinemaManager) -DEFINE_INTERFACE_METHOD_1("AddPath", void, ICmpCinemaManager, AddPath, CCinemaPath) -DEFINE_INTERFACE_METHOD_1("AddCinemaPathToQueue", void, ICmpCinemaManager, AddCinemaPathToQueue, CStrW) -DEFINE_INTERFACE_METHOD_1("DeletePath", void, ICmpCinemaManager, DeletePath, CStrW) -DEFINE_INTERFACE_METHOD_CONST_0("IsPlaying", bool, ICmpCinemaManager, IsEnabled) -DEFINE_INTERFACE_METHOD_0("Play", void, ICmpCinemaManager, Play) -DEFINE_INTERFACE_METHOD_0("Stop", void, ICmpCinemaManager, Stop) +DEFINE_INTERFACE_METHOD("AddPath", ICmpCinemaManager, AddPath) +DEFINE_INTERFACE_METHOD("AddCinemaPathToQueue", ICmpCinemaManager, AddCinemaPathToQueue) +DEFINE_INTERFACE_METHOD("DeletePath", ICmpCinemaManager, DeletePath) +DEFINE_INTERFACE_METHOD("IsPlaying", ICmpCinemaManager, IsEnabled) +DEFINE_INTERFACE_METHOD("Play", ICmpCinemaManager, Play) +DEFINE_INTERFACE_METHOD("Stop", ICmpCinemaManager, Stop) END_INTERFACE_WRAPPER(CinemaManager) Index: source/simulation2/components/ICmpCommandQueue.cpp =================================================================== --- source/simulation2/components/ICmpCommandQueue.cpp +++ source/simulation2/components/ICmpCommandQueue.cpp @@ -19,10 +19,12 @@ #include "ICmpCommandQueue.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(CommandQueue) -DEFINE_INTERFACE_METHOD_2("PushLocalCommand", void, ICmpCommandQueue, PushLocalCommand, player_id_t, JS::HandleValue) -DEFINE_INTERFACE_METHOD_1("PostNetworkCommand", void, ICmpCommandQueue, PostNetworkCommand, JS::HandleValue) +DEFINE_INTERFACE_METHOD("PushLocalCommand", ICmpCommandQueue, PushLocalCommand) +DEFINE_INTERFACE_METHOD("PostNetworkCommand", ICmpCommandQueue, PostNetworkCommand) // Excluded: FlushTurn (doesn't make sense for scripts to call it) END_INTERFACE_WRAPPER(CommandQueue) Index: source/simulation2/components/ICmpDecay.cpp =================================================================== --- source/simulation2/components/ICmpDecay.cpp +++ source/simulation2/components/ICmpDecay.cpp @@ -19,6 +19,8 @@ #include "ICmpDecay.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Decay) Index: source/simulation2/components/ICmpFogging.cpp =================================================================== --- source/simulation2/components/ICmpFogging.cpp +++ source/simulation2/components/ICmpFogging.cpp @@ -19,6 +19,8 @@ #include "ICmpFogging.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/scripting/ScriptComponent.h" #include "simulation2/system/InterfaceScripted.h" Index: source/simulation2/components/ICmpFootprint.cpp =================================================================== --- source/simulation2/components/ICmpFootprint.cpp +++ source/simulation2/components/ICmpFootprint.cpp @@ -19,6 +19,8 @@ #include "ICmpFootprint.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/system/SimContext.h" @@ -69,7 +71,7 @@ } BEGIN_INTERFACE_WRAPPER(Footprint) -DEFINE_INTERFACE_METHOD_CONST_1("PickSpawnPoint", CFixedVector3D, ICmpFootprint, PickSpawnPoint, entity_id_t) -DEFINE_INTERFACE_METHOD_CONST_1("PickSpawnPointBothPass", CFixedVector3D, ICmpFootprint, PickSpawnPointBothPass, entity_id_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetShape", JS::Value, ICmpFootprint, GetShape_wrapper) +DEFINE_INTERFACE_METHOD("PickSpawnPoint", ICmpFootprint, PickSpawnPoint) +DEFINE_INTERFACE_METHOD("PickSpawnPointBothPass", ICmpFootprint, PickSpawnPointBothPass) +DEFINE_INTERFACE_METHOD("GetShape", ICmpFootprint, GetShape_wrapper) END_INTERFACE_WRAPPER(Footprint) Index: source/simulation2/components/ICmpGarrisonHolder.cpp =================================================================== --- source/simulation2/components/ICmpGarrisonHolder.cpp +++ source/simulation2/components/ICmpGarrisonHolder.cpp @@ -19,6 +19,8 @@ #include "ICmpGarrisonHolder.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/scripting/ScriptComponent.h" #include "simulation2/system/InterfaceScripted.h" Index: source/simulation2/components/ICmpGuiInterface.cpp =================================================================== --- source/simulation2/components/ICmpGuiInterface.cpp +++ source/simulation2/components/ICmpGuiInterface.cpp @@ -19,6 +19,8 @@ #include "ICmpGuiInterface.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpIdentity.cpp =================================================================== --- source/simulation2/components/ICmpIdentity.cpp +++ source/simulation2/components/ICmpIdentity.cpp @@ -19,6 +19,8 @@ #include "ICmpIdentity.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpMinimap.cpp =================================================================== --- source/simulation2/components/ICmpMinimap.cpp +++ source/simulation2/components/ICmpMinimap.cpp @@ -19,8 +19,10 @@ #include "ICmpMinimap.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Minimap) -DEFINE_INTERFACE_METHOD_0("UpdateColor", void, ICmpMinimap, UpdateColor) +DEFINE_INTERFACE_METHOD("UpdateColor", ICmpMinimap, UpdateColor) END_INTERFACE_WRAPPER(Minimap) Index: source/simulation2/components/ICmpMirage.cpp =================================================================== --- source/simulation2/components/ICmpMirage.cpp +++ source/simulation2/components/ICmpMirage.cpp @@ -19,6 +19,8 @@ #include "ICmpMirage.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/scripting/ScriptComponent.h" #include "simulation2/system/InterfaceScripted.h" Index: source/simulation2/components/ICmpMotion.cpp =================================================================== --- source/simulation2/components/ICmpMotion.cpp +++ source/simulation2/components/ICmpMotion.cpp @@ -19,6 +19,8 @@ #include "ICmpMotion.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpObstruction.cpp =================================================================== --- source/simulation2/components/ICmpObstruction.cpp +++ source/simulation2/components/ICmpObstruction.cpp @@ -19,6 +19,8 @@ #include "ICmpObstruction.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/system/SimContext.h" @@ -46,18 +48,18 @@ } BEGIN_INTERFACE_WRAPPER(Obstruction) -DEFINE_INTERFACE_METHOD_CONST_0("GetUnitRadius", entity_pos_t, ICmpObstruction, GetUnitRadius) -DEFINE_INTERFACE_METHOD_CONST_0("CheckShorePlacement", bool, ICmpObstruction, CheckShorePlacement) -DEFINE_INTERFACE_METHOD_CONST_2("CheckFoundation", std::string, ICmpObstruction, CheckFoundation_wrapper, std::string, bool) -DEFINE_INTERFACE_METHOD_CONST_0("CheckDuplicateFoundation", bool, ICmpObstruction, CheckDuplicateFoundation) -DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesBlockingMovement", std::vector, ICmpObstruction, GetEntitiesBlockingMovement) -DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesBlockingConstruction", std::vector, ICmpObstruction, GetEntitiesBlockingConstruction) -DEFINE_INTERFACE_METHOD_CONST_0("GetEntitiesDeletedUponConstruction", std::vector, ICmpObstruction, GetEntitiesDeletedUponConstruction) -DEFINE_INTERFACE_METHOD_1("SetActive", void, ICmpObstruction, SetActive, bool) -DEFINE_INTERFACE_METHOD_3("SetDisableBlockMovementPathfinding", void, ICmpObstruction, SetDisableBlockMovementPathfinding, bool, bool, int32_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetBlockMovementFlag", bool, ICmpObstruction, GetBlockMovementFlag) -DEFINE_INTERFACE_METHOD_1("SetControlGroup", void, ICmpObstruction, SetControlGroup, entity_id_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetControlGroup", entity_id_t, ICmpObstruction, GetControlGroup) -DEFINE_INTERFACE_METHOD_1("SetControlGroup2", void, ICmpObstruction, SetControlGroup2, entity_id_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetControlGroup2", entity_id_t, ICmpObstruction, GetControlGroup2) +DEFINE_INTERFACE_METHOD("GetUnitRadius", ICmpObstruction, GetUnitRadius) +DEFINE_INTERFACE_METHOD("CheckShorePlacement", ICmpObstruction, CheckShorePlacement) +DEFINE_INTERFACE_METHOD("CheckFoundation", ICmpObstruction, CheckFoundation_wrapper) +DEFINE_INTERFACE_METHOD("CheckDuplicateFoundation", ICmpObstruction, CheckDuplicateFoundation) +DEFINE_INTERFACE_METHOD("GetEntitiesBlockingMovement", ICmpObstruction, GetEntitiesBlockingMovement) +DEFINE_INTERFACE_METHOD("GetEntitiesBlockingConstruction", ICmpObstruction, GetEntitiesBlockingConstruction) +DEFINE_INTERFACE_METHOD("GetEntitiesDeletedUponConstruction", ICmpObstruction, GetEntitiesDeletedUponConstruction) +DEFINE_INTERFACE_METHOD("SetActive", ICmpObstruction, SetActive) +DEFINE_INTERFACE_METHOD("SetDisableBlockMovementPathfinding", ICmpObstruction, SetDisableBlockMovementPathfinding) +DEFINE_INTERFACE_METHOD("GetBlockMovementFlag", ICmpObstruction, GetBlockMovementFlag) +DEFINE_INTERFACE_METHOD("SetControlGroup", ICmpObstruction, SetControlGroup) +DEFINE_INTERFACE_METHOD("GetControlGroup", ICmpObstruction, GetControlGroup) +DEFINE_INTERFACE_METHOD("SetControlGroup2", ICmpObstruction, SetControlGroup2) +DEFINE_INTERFACE_METHOD("GetControlGroup2", ICmpObstruction, GetControlGroup2) END_INTERFACE_WRAPPER(Obstruction) Index: source/simulation2/components/ICmpObstructionManager.cpp =================================================================== --- source/simulation2/components/ICmpObstructionManager.cpp +++ source/simulation2/components/ICmpObstructionManager.cpp @@ -19,16 +19,18 @@ #include "ICmpObstructionManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(ObstructionManager) -DEFINE_INTERFACE_METHOD_1("SetPassabilityCircular", void, ICmpObstructionManager, SetPassabilityCircular, bool) -DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpObstructionManager, SetDebugOverlay, bool) -DEFINE_INTERFACE_METHOD_CONST_3("DistanceToPoint", fixed, ICmpObstructionManager, DistanceToPoint, entity_id_t, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_CONST_3("MaxDistanceToPoint", fixed, ICmpObstructionManager, MaxDistanceToPoint, entity_id_t, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_CONST_2("DistanceToTarget", fixed, ICmpObstructionManager, DistanceToTarget, entity_id_t, entity_id_t) -DEFINE_INTERFACE_METHOD_CONST_2("MaxDistanceToTarget", fixed, ICmpObstructionManager, MaxDistanceToTarget, entity_id_t, entity_id_t) -DEFINE_INTERFACE_METHOD_CONST_6("IsInPointRange", bool, ICmpObstructionManager, IsInPointRange, entity_id_t, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t, bool) -DEFINE_INTERFACE_METHOD_CONST_5("IsInTargetRange", bool, ICmpObstructionManager, IsInTargetRange, entity_id_t, entity_id_t, entity_pos_t, entity_pos_t, bool) -DEFINE_INTERFACE_METHOD_CONST_6("IsPointInPointRange", bool, ICmpObstructionManager, IsPointInPointRange, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t) +DEFINE_INTERFACE_METHOD("SetPassabilityCircular", ICmpObstructionManager, SetPassabilityCircular) +DEFINE_INTERFACE_METHOD("SetDebugOverlay", ICmpObstructionManager, SetDebugOverlay) +DEFINE_INTERFACE_METHOD("DistanceToPoint", ICmpObstructionManager, DistanceToPoint) +DEFINE_INTERFACE_METHOD("MaxDistanceToPoint", ICmpObstructionManager, MaxDistanceToPoint) +DEFINE_INTERFACE_METHOD("DistanceToTarget", ICmpObstructionManager, DistanceToTarget) +DEFINE_INTERFACE_METHOD("MaxDistanceToTarget", ICmpObstructionManager, MaxDistanceToTarget) +DEFINE_INTERFACE_METHOD("IsInPointRange", ICmpObstructionManager, IsInPointRange) +DEFINE_INTERFACE_METHOD("IsInTargetRange", ICmpObstructionManager, IsInTargetRange) +DEFINE_INTERFACE_METHOD("IsPointInPointRange", ICmpObstructionManager, IsPointInPointRange) END_INTERFACE_WRAPPER(ObstructionManager) Index: source/simulation2/components/ICmpOverlayRenderer.cpp =================================================================== --- source/simulation2/components/ICmpOverlayRenderer.cpp +++ source/simulation2/components/ICmpOverlayRenderer.cpp @@ -19,11 +19,13 @@ #include "ICmpOverlayRenderer.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(OverlayRenderer) -DEFINE_INTERFACE_METHOD_0("Reset", void, ICmpOverlayRenderer, Reset) -DEFINE_INTERFACE_METHOD_5("AddSprite", void, ICmpOverlayRenderer, AddSprite, VfsPath, CFixedVector2D, CFixedVector2D, CFixedVector3D, std::string) +DEFINE_INTERFACE_METHOD("Reset", ICmpOverlayRenderer, Reset) +DEFINE_INTERFACE_METHOD("AddSprite", ICmpOverlayRenderer, AddSprite) END_INTERFACE_WRAPPER(OverlayRenderer) bool ICmpOverlayRenderer::m_OverrideVisible = true; Index: source/simulation2/components/ICmpOwnership.cpp =================================================================== --- source/simulation2/components/ICmpOwnership.cpp +++ source/simulation2/components/ICmpOwnership.cpp @@ -19,10 +19,12 @@ #include "ICmpOwnership.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Ownership) -DEFINE_INTERFACE_METHOD_CONST_0("GetOwner", player_id_t, ICmpOwnership, GetOwner) -DEFINE_INTERFACE_METHOD_1("SetOwner", void, ICmpOwnership, SetOwner, player_id_t) -DEFINE_INTERFACE_METHOD_1("SetOwnerQuiet", void, ICmpOwnership, SetOwnerQuiet, player_id_t) +DEFINE_INTERFACE_METHOD("GetOwner", ICmpOwnership, GetOwner) +DEFINE_INTERFACE_METHOD("SetOwner", ICmpOwnership, SetOwner) +DEFINE_INTERFACE_METHOD("SetOwnerQuiet", ICmpOwnership, SetOwnerQuiet) END_INTERFACE_WRAPPER(Ownership) Index: source/simulation2/components/ICmpParticleManager.cpp =================================================================== --- source/simulation2/components/ICmpParticleManager.cpp +++ source/simulation2/components/ICmpParticleManager.cpp @@ -19,6 +19,8 @@ #include "ICmpParticleManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(ParticleManager) Index: source/simulation2/components/ICmpPathfinder.cpp =================================================================== --- source/simulation2/components/ICmpPathfinder.cpp +++ source/simulation2/components/ICmpPathfinder.cpp @@ -19,10 +19,12 @@ #include "ICmpPathfinder.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Pathfinder) -DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpPathfinder, SetDebugOverlay, bool) -DEFINE_INTERFACE_METHOD_1("SetHierDebugOverlay", void, ICmpPathfinder, SetHierDebugOverlay, bool) -DEFINE_INTERFACE_METHOD_CONST_1("GetPassabilityClass", pass_class_t, ICmpPathfinder, GetPassabilityClass, std::string) +DEFINE_INTERFACE_METHOD("SetDebugOverlay", ICmpPathfinder, SetDebugOverlay) +DEFINE_INTERFACE_METHOD("SetHierDebugOverlay", ICmpPathfinder, SetHierDebugOverlay) +DEFINE_INTERFACE_METHOD("GetPassabilityClass", ICmpPathfinder, GetPassabilityClass) END_INTERFACE_WRAPPER(Pathfinder) Index: source/simulation2/components/ICmpPlayer.cpp =================================================================== --- source/simulation2/components/ICmpPlayer.cpp +++ source/simulation2/components/ICmpPlayer.cpp @@ -21,6 +21,8 @@ #include "graphics/Color.h" #include "maths/FixedVector3D.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpPlayerManager.cpp =================================================================== --- source/simulation2/components/ICmpPlayerManager.cpp +++ source/simulation2/components/ICmpPlayerManager.cpp @@ -19,6 +19,8 @@ #include "ICmpPlayerManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpPosition.cpp =================================================================== --- source/simulation2/components/ICmpPosition.cpp +++ source/simulation2/components/ICmpPosition.cpp @@ -19,32 +19,34 @@ #include "ICmpPosition.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Position) -DEFINE_INTERFACE_METHOD_2("SetTurretParent", void, ICmpPosition, SetTurretParent, entity_id_t, CFixedVector3D) -DEFINE_INTERFACE_METHOD_CONST_0("GetTurretParent", entity_id_t, ICmpPosition, GetTurretParent) -DEFINE_INTERFACE_METHOD_CONST_0("IsInWorld", bool, ICmpPosition, IsInWorld) -DEFINE_INTERFACE_METHOD_0("MoveOutOfWorld", void, ICmpPosition, MoveOutOfWorld) -DEFINE_INTERFACE_METHOD_2("MoveTo", void, ICmpPosition, MoveTo, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_3("MoveAndTurnTo", void, ICmpPosition, MoveAndTurnTo, entity_pos_t, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_2("JumpTo", void, ICmpPosition, JumpTo, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_1("SetHeightOffset", void, ICmpPosition, SetHeightOffset, entity_pos_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetHeightOffset", entity_pos_t, ICmpPosition, GetHeightOffset) -DEFINE_INTERFACE_METHOD_1("SetHeightFixed", void, ICmpPosition, SetHeightFixed, entity_pos_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetHeightFixed", entity_pos_t, ICmpPosition, GetHeightFixed) -DEFINE_INTERFACE_METHOD_CONST_0("IsHeightRelative", bool, ICmpPosition, IsHeightRelative) -DEFINE_INTERFACE_METHOD_1("SetHeightRelative", void, ICmpPosition, SetHeightRelative, bool) -DEFINE_INTERFACE_METHOD_CONST_0("CanFloat", bool, ICmpPosition, CanFloat) -DEFINE_INTERFACE_METHOD_1("SetFloating", void, ICmpPosition, SetFloating, bool) -DEFINE_INTERFACE_METHOD_1("SetConstructionProgress", void, ICmpPosition, SetConstructionProgress, fixed) -DEFINE_INTERFACE_METHOD_CONST_0("GetPosition", CFixedVector3D, ICmpPosition, GetPosition) -DEFINE_INTERFACE_METHOD_CONST_0("GetPosition2D", CFixedVector2D, ICmpPosition, GetPosition2D) -DEFINE_INTERFACE_METHOD_CONST_0("GetPreviousPosition", CFixedVector3D, ICmpPosition, GetPreviousPosition) -DEFINE_INTERFACE_METHOD_CONST_0("GetPreviousPosition2D", CFixedVector2D, ICmpPosition, GetPreviousPosition2D) -DEFINE_INTERFACE_METHOD_1("TurnTo", void, ICmpPosition, TurnTo, entity_angle_t) -DEFINE_INTERFACE_METHOD_1("SetYRotation", void, ICmpPosition, SetYRotation, entity_angle_t) -DEFINE_INTERFACE_METHOD_2("SetXZRotation", void, ICmpPosition, SetXZRotation, entity_angle_t, entity_angle_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetRotation", CFixedVector3D, ICmpPosition, GetRotation) +DEFINE_INTERFACE_METHOD("SetTurretParent", ICmpPosition, SetTurretParent) +DEFINE_INTERFACE_METHOD("GetTurretParent", ICmpPosition, GetTurretParent) +DEFINE_INTERFACE_METHOD("IsInWorld", ICmpPosition, IsInWorld) +DEFINE_INTERFACE_METHOD("MoveOutOfWorld", ICmpPosition, MoveOutOfWorld) +DEFINE_INTERFACE_METHOD("MoveTo", ICmpPosition, MoveTo) +DEFINE_INTERFACE_METHOD("MoveAndTurnTo", ICmpPosition, MoveAndTurnTo) +DEFINE_INTERFACE_METHOD("JumpTo", ICmpPosition, JumpTo) +DEFINE_INTERFACE_METHOD("SetHeightOffset", ICmpPosition, SetHeightOffset) +DEFINE_INTERFACE_METHOD("GetHeightOffset", ICmpPosition, GetHeightOffset) +DEFINE_INTERFACE_METHOD("SetHeightFixed", ICmpPosition, SetHeightFixed) +DEFINE_INTERFACE_METHOD("GetHeightFixed", ICmpPosition, GetHeightFixed) +DEFINE_INTERFACE_METHOD("IsHeightRelative", ICmpPosition, IsHeightRelative) +DEFINE_INTERFACE_METHOD("SetHeightRelative", ICmpPosition, SetHeightRelative) +DEFINE_INTERFACE_METHOD("CanFloat", ICmpPosition, CanFloat) +DEFINE_INTERFACE_METHOD("SetFloating", ICmpPosition, SetFloating) +DEFINE_INTERFACE_METHOD("SetConstructionProgress", ICmpPosition, SetConstructionProgress) +DEFINE_INTERFACE_METHOD("GetPosition", ICmpPosition, GetPosition) +DEFINE_INTERFACE_METHOD("GetPosition2D", ICmpPosition, GetPosition2D) +DEFINE_INTERFACE_METHOD("GetPreviousPosition", ICmpPosition, GetPreviousPosition) +DEFINE_INTERFACE_METHOD("GetPreviousPosition2D", ICmpPosition, GetPreviousPosition2D) +DEFINE_INTERFACE_METHOD("TurnTo", ICmpPosition, TurnTo) +DEFINE_INTERFACE_METHOD("SetYRotation", ICmpPosition, SetYRotation) +DEFINE_INTERFACE_METHOD("SetXZRotation", ICmpPosition, SetXZRotation) +DEFINE_INTERFACE_METHOD("GetRotation", ICmpPosition, GetRotation) // Excluded: GetInterpolatedTransform (not safe for scripts) END_INTERFACE_WRAPPER(Position) Index: source/simulation2/components/ICmpProjectileManager.cpp =================================================================== --- source/simulation2/components/ICmpProjectileManager.cpp +++ source/simulation2/components/ICmpProjectileManager.cpp @@ -19,9 +19,11 @@ #include "ICmpProjectileManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(ProjectileManager) -DEFINE_INTERFACE_METHOD_7("LaunchProjectileAtPoint", uint32_t, ICmpProjectileManager, LaunchProjectileAtPoint, CFixedVector3D, CFixedVector3D, fixed, fixed, std::wstring, std::wstring, fixed) -DEFINE_INTERFACE_METHOD_1("RemoveProjectile", void, ICmpProjectileManager, RemoveProjectile, uint32_t) +DEFINE_INTERFACE_METHOD("LaunchProjectileAtPoint", ICmpProjectileManager, LaunchProjectileAtPoint) +DEFINE_INTERFACE_METHOD("RemoveProjectile", ICmpProjectileManager, RemoveProjectile) END_INTERFACE_WRAPPER(ProjectileManager) Index: source/simulation2/components/ICmpRallyPoint.cpp =================================================================== --- source/simulation2/components/ICmpRallyPoint.cpp +++ source/simulation2/components/ICmpRallyPoint.cpp @@ -20,6 +20,8 @@ #include "ICmpRallyPoint.h" #include "maths/FixedVector2D.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpRallyPointRenderer.cpp =================================================================== --- source/simulation2/components/ICmpRallyPointRenderer.cpp +++ source/simulation2/components/ICmpRallyPointRenderer.cpp @@ -18,16 +18,18 @@ #include "precompiled.h" #include "ICmpRallyPointRenderer.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" class CFixedVector2D; BEGIN_INTERFACE_WRAPPER(RallyPointRenderer) -DEFINE_INTERFACE_METHOD_1("SetDisplayed", void, ICmpRallyPointRenderer, SetDisplayed, bool) -DEFINE_INTERFACE_METHOD_1("SetPosition", void, ICmpRallyPointRenderer, SetPosition, CFixedVector2D) -DEFINE_INTERFACE_METHOD_2("UpdatePosition", void, ICmpRallyPointRenderer, UpdatePosition, u32, CFixedVector2D) -DEFINE_INTERFACE_METHOD_1("AddPosition", void, ICmpRallyPointRenderer, AddPosition_wrapper, CFixedVector2D) -DEFINE_INTERFACE_METHOD_0("Reset", void, ICmpRallyPointRenderer, Reset) -DEFINE_INTERFACE_METHOD_CONST_0("IsSet", bool, ICmpRallyPointRenderer, IsSet) -DEFINE_INTERFACE_METHOD_0("UpdateColor", void, ICmpRallyPointRenderer, UpdateColor) +DEFINE_INTERFACE_METHOD("SetDisplayed", ICmpRallyPointRenderer, SetDisplayed) +DEFINE_INTERFACE_METHOD("SetPosition", ICmpRallyPointRenderer, SetPosition) +DEFINE_INTERFACE_METHOD("UpdatePosition", ICmpRallyPointRenderer, UpdatePosition) +DEFINE_INTERFACE_METHOD("AddPosition", ICmpRallyPointRenderer, AddPosition_wrapper) +DEFINE_INTERFACE_METHOD("Reset", ICmpRallyPointRenderer, Reset) +DEFINE_INTERFACE_METHOD("IsSet", ICmpRallyPointRenderer, IsSet) +DEFINE_INTERFACE_METHOD("UpdateColor", ICmpRallyPointRenderer, UpdateColor) END_INTERFACE_WRAPPER(RallyPointRenderer) Index: source/simulation2/components/ICmpRangeManager.cpp =================================================================== --- source/simulation2/components/ICmpRangeManager.cpp +++ source/simulation2/components/ICmpRangeManager.cpp @@ -19,6 +19,8 @@ #include "ICmpRangeManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" namespace { @@ -45,33 +47,33 @@ } BEGIN_INTERFACE_WRAPPER(RangeManager) -DEFINE_INTERFACE_METHOD_5("ExecuteQuery", std::vector, ICmpRangeManager, ExecuteQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector, int) -DEFINE_INTERFACE_METHOD_5("ExecuteQueryAroundPos", std::vector, ICmpRangeManager, ExecuteQueryAroundPos, CFixedVector2D, entity_pos_t, entity_pos_t, std::vector, int) -DEFINE_INTERFACE_METHOD_6("CreateActiveQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector, int, u8) -DEFINE_INTERFACE_METHOD_7("CreateActiveParabolicQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveParabolicQuery, entity_id_t, entity_pos_t, entity_pos_t, entity_pos_t, std::vector, int, u8) -DEFINE_INTERFACE_METHOD_1("DestroyActiveQuery", void, ICmpRangeManager, DestroyActiveQuery, ICmpRangeManager::tag_t) -DEFINE_INTERFACE_METHOD_1("EnableActiveQuery", void, ICmpRangeManager, EnableActiveQuery, ICmpRangeManager::tag_t) -DEFINE_INTERFACE_METHOD_1("DisableActiveQuery", void, ICmpRangeManager, DisableActiveQuery, ICmpRangeManager::tag_t) -DEFINE_INTERFACE_METHOD_CONST_1("IsActiveQueryEnabled", bool, ICmpRangeManager, IsActiveQueryEnabled, ICmpRangeManager::tag_t) -DEFINE_INTERFACE_METHOD_1("ResetActiveQuery", std::vector, ICmpRangeManager, ResetActiveQuery, ICmpRangeManager::tag_t) -DEFINE_INTERFACE_METHOD_3("SetEntityFlag", void, ICmpRangeManager, SetEntityFlag, entity_id_t, std::string, bool) -DEFINE_INTERFACE_METHOD_CONST_1("GetEntityFlagMask", u8, ICmpRangeManager, GetEntityFlagMask, std::string) -DEFINE_INTERFACE_METHOD_CONST_1("GetEntitiesByPlayer", std::vector, ICmpRangeManager, GetEntitiesByPlayer, player_id_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetNonGaiaEntities", std::vector, ICmpRangeManager, GetNonGaiaEntities) -DEFINE_INTERFACE_METHOD_CONST_0("GetGaiaAndNonGaiaEntities", std::vector, ICmpRangeManager, GetGaiaAndNonGaiaEntities) -DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpRangeManager, SetDebugOverlay, bool) -DEFINE_INTERFACE_METHOD_1("ExploreAllTiles", void, ICmpRangeManager, ExploreAllTiles, player_id_t) -DEFINE_INTERFACE_METHOD_0("ExploreTerritories", void, ICmpRangeManager, ExploreTerritories) -DEFINE_INTERFACE_METHOD_2("SetLosRevealAll", void, ICmpRangeManager, SetLosRevealAll, player_id_t, bool) -DEFINE_INTERFACE_METHOD_CONST_1("GetLosRevealAll", bool, ICmpRangeManager, GetLosRevealAll, player_id_t) -DEFINE_INTERFACE_METHOD_CONST_5("GetElevationAdaptedRange", entity_pos_t, ICmpRangeManager, GetElevationAdaptedRange, CFixedVector3D, CFixedVector3D, entity_pos_t, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_2("ActivateScriptedVisibility", void, ICmpRangeManager, ActivateScriptedVisibility, entity_id_t, bool) -DEFINE_INTERFACE_METHOD_CONST_2("GetLosVisibility", std::string, ICmpRangeManager, GetLosVisibility_wrapper, entity_id_t, player_id_t) -DEFINE_INTERFACE_METHOD_CONST_3("GetLosVisibilityPosition", std::string, ICmpRangeManager, GetLosVisibilityPosition_wrapper, entity_pos_t, entity_pos_t, player_id_t) -DEFINE_INTERFACE_METHOD_1("RequestVisibilityUpdate", void, ICmpRangeManager, RequestVisibilityUpdate, entity_id_t) -DEFINE_INTERFACE_METHOD_1("SetLosCircular", void, ICmpRangeManager, SetLosCircular, bool) -DEFINE_INTERFACE_METHOD_CONST_0("GetLosCircular", bool, ICmpRangeManager, GetLosCircular) -DEFINE_INTERFACE_METHOD_2("SetSharedLos", void, ICmpRangeManager, SetSharedLos, player_id_t, std::vector) -DEFINE_INTERFACE_METHOD_CONST_1("GetPercentMapExplored", u8, ICmpRangeManager, GetPercentMapExplored, player_id_t) -DEFINE_INTERFACE_METHOD_CONST_1("GetUnionPercentMapExplored", u8, ICmpRangeManager, GetUnionPercentMapExplored, std::vector) +DEFINE_INTERFACE_METHOD("ExecuteQuery", ICmpRangeManager, ExecuteQuery) +DEFINE_INTERFACE_METHOD("ExecuteQueryAroundPos", ICmpRangeManager, ExecuteQueryAroundPos) +DEFINE_INTERFACE_METHOD("CreateActiveQuery", ICmpRangeManager, CreateActiveQuery) +DEFINE_INTERFACE_METHOD("CreateActiveParabolicQuery", ICmpRangeManager, CreateActiveParabolicQuery) +DEFINE_INTERFACE_METHOD("DestroyActiveQuery", ICmpRangeManager, DestroyActiveQuery) +DEFINE_INTERFACE_METHOD("EnableActiveQuery", ICmpRangeManager, EnableActiveQuery) +DEFINE_INTERFACE_METHOD("DisableActiveQuery", ICmpRangeManager, DisableActiveQuery) +DEFINE_INTERFACE_METHOD("IsActiveQueryEnabled", ICmpRangeManager, IsActiveQueryEnabled) +DEFINE_INTERFACE_METHOD("ResetActiveQuery", ICmpRangeManager, ResetActiveQuery) +DEFINE_INTERFACE_METHOD("SetEntityFlag", ICmpRangeManager, SetEntityFlag) +DEFINE_INTERFACE_METHOD("GetEntityFlagMask", ICmpRangeManager, GetEntityFlagMask) +DEFINE_INTERFACE_METHOD("GetEntitiesByPlayer", ICmpRangeManager, GetEntitiesByPlayer) +DEFINE_INTERFACE_METHOD("GetNonGaiaEntities", ICmpRangeManager, GetNonGaiaEntities) +DEFINE_INTERFACE_METHOD("GetGaiaAndNonGaiaEntities", ICmpRangeManager, GetGaiaAndNonGaiaEntities) +DEFINE_INTERFACE_METHOD("SetDebugOverlay", ICmpRangeManager, SetDebugOverlay) +DEFINE_INTERFACE_METHOD("ExploreAllTiles", ICmpRangeManager, ExploreAllTiles) +DEFINE_INTERFACE_METHOD("ExploreTerritories", ICmpRangeManager, ExploreTerritories) +DEFINE_INTERFACE_METHOD("SetLosRevealAll", ICmpRangeManager, SetLosRevealAll) +DEFINE_INTERFACE_METHOD("GetLosRevealAll", ICmpRangeManager, GetLosRevealAll) +DEFINE_INTERFACE_METHOD("GetElevationAdaptedRange", ICmpRangeManager, GetElevationAdaptedRange) +DEFINE_INTERFACE_METHOD("ActivateScriptedVisibility", ICmpRangeManager, ActivateScriptedVisibility) +DEFINE_INTERFACE_METHOD("GetLosVisibility", ICmpRangeManager, GetLosVisibility_wrapper) +DEFINE_INTERFACE_METHOD("GetLosVisibilityPosition", ICmpRangeManager, GetLosVisibilityPosition_wrapper) +DEFINE_INTERFACE_METHOD("RequestVisibilityUpdate", ICmpRangeManager, RequestVisibilityUpdate) +DEFINE_INTERFACE_METHOD("SetLosCircular", ICmpRangeManager, SetLosCircular) +DEFINE_INTERFACE_METHOD("GetLosCircular", ICmpRangeManager, GetLosCircular) +DEFINE_INTERFACE_METHOD("SetSharedLos", ICmpRangeManager, SetSharedLos) +DEFINE_INTERFACE_METHOD("GetPercentMapExplored", ICmpRangeManager, GetPercentMapExplored) +DEFINE_INTERFACE_METHOD("GetUnionPercentMapExplored", ICmpRangeManager, GetUnionPercentMapExplored) END_INTERFACE_WRAPPER(RangeManager) Index: source/simulation2/components/ICmpRangeOverlayRenderer.cpp =================================================================== --- source/simulation2/components/ICmpRangeOverlayRenderer.cpp +++ source/simulation2/components/ICmpRangeOverlayRenderer.cpp @@ -18,10 +18,12 @@ #include "precompiled.h" #include "ICmpRangeOverlayRenderer.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(RangeOverlayRenderer) -DEFINE_INTERFACE_METHOD_4("AddRangeOverlay", void, ICmpRangeOverlayRenderer, AddRangeOverlay, float, std::string, std::string, float) -DEFINE_INTERFACE_METHOD_0("ResetRangeOverlays", void, ICmpRangeOverlayRenderer, ResetRangeOverlays) -DEFINE_INTERFACE_METHOD_0("UpdateColor", void, ICmpRangeOverlayRenderer, UpdateColor) +DEFINE_INTERFACE_METHOD("AddRangeOverlay", ICmpRangeOverlayRenderer, AddRangeOverlay) +DEFINE_INTERFACE_METHOD("ResetRangeOverlays", ICmpRangeOverlayRenderer, ResetRangeOverlays) +DEFINE_INTERFACE_METHOD("UpdateColor", ICmpRangeOverlayRenderer, UpdateColor) END_INTERFACE_WRAPPER(RangeOverlayRenderer) Index: source/simulation2/components/ICmpSelectable.cpp =================================================================== --- source/simulation2/components/ICmpSelectable.cpp +++ source/simulation2/components/ICmpSelectable.cpp @@ -19,13 +19,15 @@ #include "ICmpSelectable.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "graphics/Color.h" BEGIN_INTERFACE_WRAPPER(Selectable) -DEFINE_INTERFACE_METHOD_2("SetSelectionHighlight", void, ICmpSelectable, SetSelectionHighlight, CColor, bool) -DEFINE_INTERFACE_METHOD_0("UpdateColor", void, ICmpSelectable, UpdateColor) +DEFINE_INTERFACE_METHOD("SetSelectionHighlight", ICmpSelectable, SetSelectionHighlight) +DEFINE_INTERFACE_METHOD("UpdateColor", ICmpSelectable, UpdateColor) END_INTERFACE_WRAPPER(Selectable) bool ICmpSelectable::ms_EnableDebugOverlays = false; Index: source/simulation2/components/ICmpSettlement.cpp =================================================================== --- source/simulation2/components/ICmpSettlement.cpp +++ source/simulation2/components/ICmpSettlement.cpp @@ -19,6 +19,8 @@ #include "ICmpSettlement.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpSound.cpp =================================================================== --- source/simulation2/components/ICmpSound.cpp +++ source/simulation2/components/ICmpSound.cpp @@ -19,6 +19,8 @@ #include "ICmpSound.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/scripting/ScriptComponent.h" #include "simulation2/system/InterfaceScripted.h" Index: source/simulation2/components/ICmpSoundManager.cpp =================================================================== --- source/simulation2/components/ICmpSoundManager.cpp +++ source/simulation2/components/ICmpSoundManager.cpp @@ -19,10 +19,12 @@ #include "ICmpSoundManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(SoundManager) -DEFINE_INTERFACE_METHOD_2("PlaySoundGroup", void, ICmpSoundManager, PlaySoundGroup, std::wstring, entity_id_t) -DEFINE_INTERFACE_METHOD_2("PlaySoundGroupAtPosition", void, ICmpSoundManager, PlaySoundGroupAtPosition, std::wstring, CFixedVector3D) -DEFINE_INTERFACE_METHOD_0("StopMusic", void, ICmpSoundManager, StopMusic) +DEFINE_INTERFACE_METHOD("PlaySoundGroup", ICmpSoundManager, PlaySoundGroup) +DEFINE_INTERFACE_METHOD("PlaySoundGroupAtPosition", ICmpSoundManager, PlaySoundGroupAtPosition) +DEFINE_INTERFACE_METHOD("StopMusic", ICmpSoundManager, StopMusic) END_INTERFACE_WRAPPER(SoundManager) Index: source/simulation2/components/ICmpTemplateManager.cpp =================================================================== --- source/simulation2/components/ICmpTemplateManager.cpp +++ source/simulation2/components/ICmpTemplateManager.cpp @@ -19,13 +19,15 @@ #include "ICmpTemplateManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(TemplateManager) -DEFINE_INTERFACE_METHOD_1("GetTemplate", const CParamNode*, ICmpTemplateManager, GetTemplate, std::string) -DEFINE_INTERFACE_METHOD_1("GetTemplateWithoutValidation", const CParamNode*, ICmpTemplateManager, GetTemplateWithoutValidation, std::string) -DEFINE_INTERFACE_METHOD_CONST_1("TemplateExists", bool, ICmpTemplateManager, TemplateExists, std::string) -DEFINE_INTERFACE_METHOD_CONST_1("GetCurrentTemplateName", std::string, ICmpTemplateManager, GetCurrentTemplateName, entity_id_t) -DEFINE_INTERFACE_METHOD_CONST_1("FindAllTemplates", std::vector, ICmpTemplateManager, FindAllTemplates, bool) -DEFINE_INTERFACE_METHOD_CONST_1("GetEntitiesUsingTemplate", std::vector, ICmpTemplateManager, GetEntitiesUsingTemplate, std::string) +DEFINE_INTERFACE_METHOD("GetTemplate", ICmpTemplateManager, GetTemplate) +DEFINE_INTERFACE_METHOD("GetTemplateWithoutValidation", ICmpTemplateManager, GetTemplateWithoutValidation) +DEFINE_INTERFACE_METHOD("TemplateExists", ICmpTemplateManager, TemplateExists) +DEFINE_INTERFACE_METHOD("GetCurrentTemplateName", ICmpTemplateManager, GetCurrentTemplateName) +DEFINE_INTERFACE_METHOD("FindAllTemplates", ICmpTemplateManager, FindAllTemplates) +DEFINE_INTERFACE_METHOD("GetEntitiesUsingTemplate", ICmpTemplateManager, GetEntitiesUsingTemplate) END_INTERFACE_WRAPPER(TemplateManager) Index: source/simulation2/components/ICmpTerrain.cpp =================================================================== --- source/simulation2/components/ICmpTerrain.cpp +++ source/simulation2/components/ICmpTerrain.cpp @@ -19,11 +19,13 @@ #include "ICmpTerrain.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Terrain) -DEFINE_INTERFACE_METHOD_CONST_2("GetGroundLevel", entity_pos_t, ICmpTerrain, GetGroundLevel, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_CONST_2("CalcNormal", CFixedVector3D, ICmpTerrain, CalcNormal, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_CONST_0("GetTilesPerSide", u16, ICmpTerrain, GetTilesPerSide) -DEFINE_INTERFACE_METHOD_CONST_0("GetMapSize", u32, ICmpTerrain, GetMapSize) +DEFINE_INTERFACE_METHOD("GetGroundLevel", ICmpTerrain, GetGroundLevel) +DEFINE_INTERFACE_METHOD("CalcNormal", ICmpTerrain, CalcNormal) +DEFINE_INTERFACE_METHOD("GetTilesPerSide", ICmpTerrain, GetTilesPerSide) +DEFINE_INTERFACE_METHOD("GetMapSize", ICmpTerrain, GetMapSize) END_INTERFACE_WRAPPER(Terrain) Index: source/simulation2/components/ICmpTerritoryDecayManager.cpp =================================================================== --- source/simulation2/components/ICmpTerritoryDecayManager.cpp +++ source/simulation2/components/ICmpTerritoryDecayManager.cpp @@ -19,6 +19,8 @@ #include "ICmpTerritoryDecayManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpTerritoryInfluence.cpp =================================================================== --- source/simulation2/components/ICmpTerritoryInfluence.cpp +++ source/simulation2/components/ICmpTerritoryInfluence.cpp @@ -19,6 +19,8 @@ #include "ICmpTerritoryInfluence.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(TerritoryInfluence) Index: source/simulation2/components/ICmpTerritoryManager.cpp =================================================================== --- source/simulation2/components/ICmpTerritoryManager.cpp +++ source/simulation2/components/ICmpTerritoryManager.cpp @@ -19,14 +19,16 @@ #include "ICmpTerritoryManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(TerritoryManager) -DEFINE_INTERFACE_METHOD_2("GetOwner", player_id_t, ICmpTerritoryManager, GetOwner, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_3("GetNeighbours", std::vector, ICmpTerritoryManager, GetNeighbours, entity_pos_t, entity_pos_t, bool) -DEFINE_INTERFACE_METHOD_2("IsConnected", bool, ICmpTerritoryManager, IsConnected, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_3("SetTerritoryBlinking", void, ICmpTerritoryManager, SetTerritoryBlinking, entity_pos_t, entity_pos_t, bool) -DEFINE_INTERFACE_METHOD_2("IsTerritoryBlinking", bool, ICmpTerritoryManager, IsTerritoryBlinking, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_1("GetTerritoryPercentage", u8, ICmpTerritoryManager, GetTerritoryPercentage, player_id_t) -DEFINE_INTERFACE_METHOD_0("UpdateColors", void, ICmpTerritoryManager, UpdateColors) +DEFINE_INTERFACE_METHOD("GetOwner", ICmpTerritoryManager, GetOwner) +DEFINE_INTERFACE_METHOD("GetNeighbours", ICmpTerritoryManager, GetNeighbours) +DEFINE_INTERFACE_METHOD("IsConnected", ICmpTerritoryManager, IsConnected) +DEFINE_INTERFACE_METHOD("SetTerritoryBlinking", ICmpTerritoryManager, SetTerritoryBlinking) +DEFINE_INTERFACE_METHOD("IsTerritoryBlinking", ICmpTerritoryManager, IsTerritoryBlinking) +DEFINE_INTERFACE_METHOD("GetTerritoryPercentage", ICmpTerritoryManager, GetTerritoryPercentage) +DEFINE_INTERFACE_METHOD("UpdateColors", ICmpTerritoryManager, UpdateColors) END_INTERFACE_WRAPPER(TerritoryManager) Index: source/simulation2/components/ICmpTest.cpp =================================================================== --- source/simulation2/components/ICmpTest.cpp +++ source/simulation2/components/ICmpTest.cpp @@ -19,11 +19,13 @@ #include "ICmpTest.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Test1) END_INTERFACE_WRAPPER(Test1) BEGIN_INTERFACE_WRAPPER(Test2) -DEFINE_INTERFACE_METHOD_0("GetX", int, ICmpTest2, GetX) +DEFINE_INTERFACE_METHOD("GetX", ICmpTest2, GetX) END_INTERFACE_WRAPPER(Test2) Index: source/simulation2/components/ICmpUnitMotion.cpp =================================================================== --- source/simulation2/components/ICmpUnitMotion.cpp +++ source/simulation2/components/ICmpUnitMotion.cpp @@ -19,25 +19,27 @@ #include "ICmpUnitMotion.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" BEGIN_INTERFACE_WRAPPER(UnitMotion) -DEFINE_INTERFACE_METHOD_4("MoveToPointRange", bool, ICmpUnitMotion, MoveToPointRange, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_3("MoveToTargetRange", bool, ICmpUnitMotion, MoveToTargetRange, entity_id_t, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_3("MoveToFormationOffset", void, ICmpUnitMotion, MoveToFormationOffset, entity_id_t, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_2("FaceTowardsPoint", void, ICmpUnitMotion, FaceTowardsPoint, entity_pos_t, entity_pos_t) -DEFINE_INTERFACE_METHOD_0("StopMoving", void, ICmpUnitMotion, StopMoving) -DEFINE_INTERFACE_METHOD_CONST_0("GetCurrentSpeed", fixed, ICmpUnitMotion, GetCurrentSpeed) -DEFINE_INTERFACE_METHOD_CONST_0("IsMoveRequested", bool, ICmpUnitMotion, IsMoveRequested) -DEFINE_INTERFACE_METHOD_CONST_0("GetSpeed", fixed, ICmpUnitMotion, GetSpeed) -DEFINE_INTERFACE_METHOD_CONST_0("GetWalkSpeed", fixed, ICmpUnitMotion, GetWalkSpeed) -DEFINE_INTERFACE_METHOD_CONST_0("GetRunMultiplier", fixed, ICmpUnitMotion, GetRunMultiplier) -DEFINE_INTERFACE_METHOD_1("SetSpeedMultiplier", void, ICmpUnitMotion, SetSpeedMultiplier, fixed) -DEFINE_INTERFACE_METHOD_CONST_0("GetPassabilityClassName", std::string, ICmpUnitMotion, GetPassabilityClassName) -DEFINE_INTERFACE_METHOD_CONST_0("GetUnitClearance", entity_pos_t, ICmpUnitMotion, GetUnitClearance) -DEFINE_INTERFACE_METHOD_1("SetFacePointAfterMove", void, ICmpUnitMotion, SetFacePointAfterMove, bool) -DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitMotion, SetDebugOverlay, bool) +DEFINE_INTERFACE_METHOD("MoveToPointRange", ICmpUnitMotion, MoveToPointRange) +DEFINE_INTERFACE_METHOD("MoveToTargetRange", ICmpUnitMotion, MoveToTargetRange) +DEFINE_INTERFACE_METHOD("MoveToFormationOffset", ICmpUnitMotion, MoveToFormationOffset) +DEFINE_INTERFACE_METHOD("FaceTowardsPoint", ICmpUnitMotion, FaceTowardsPoint) +DEFINE_INTERFACE_METHOD("StopMoving", ICmpUnitMotion, StopMoving) +DEFINE_INTERFACE_METHOD("GetCurrentSpeed", ICmpUnitMotion, GetCurrentSpeed) +DEFINE_INTERFACE_METHOD("IsMoveRequested", ICmpUnitMotion, IsMoveRequested) +DEFINE_INTERFACE_METHOD("GetSpeed", ICmpUnitMotion, GetSpeed) +DEFINE_INTERFACE_METHOD("GetWalkSpeed", ICmpUnitMotion, GetWalkSpeed) +DEFINE_INTERFACE_METHOD("GetRunMultiplier", ICmpUnitMotion, GetRunMultiplier) +DEFINE_INTERFACE_METHOD("SetSpeedMultiplier", ICmpUnitMotion, SetSpeedMultiplier) +DEFINE_INTERFACE_METHOD("GetPassabilityClassName", ICmpUnitMotion, GetPassabilityClassName) +DEFINE_INTERFACE_METHOD("GetUnitClearance", ICmpUnitMotion, GetUnitClearance) +DEFINE_INTERFACE_METHOD("SetFacePointAfterMove", ICmpUnitMotion, SetFacePointAfterMove) +DEFINE_INTERFACE_METHOD("SetDebugOverlay", ICmpUnitMotion, SetDebugOverlay) END_INTERFACE_WRAPPER(UnitMotion) class CCmpUnitMotionScripted : public ICmpUnitMotion Index: source/simulation2/components/ICmpUnitRenderer.cpp =================================================================== --- source/simulation2/components/ICmpUnitRenderer.cpp +++ source/simulation2/components/ICmpUnitRenderer.cpp @@ -19,8 +19,10 @@ #include "ICmpUnitRenderer.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(UnitRenderer) -DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitRenderer, SetDebugOverlay, bool) +DEFINE_INTERFACE_METHOD("SetDebugOverlay", ICmpUnitRenderer, SetDebugOverlay) END_INTERFACE_WRAPPER(UnitRenderer) Index: source/simulation2/components/ICmpUnknownScript.cpp =================================================================== --- source/simulation2/components/ICmpUnknownScript.cpp +++ source/simulation2/components/ICmpUnknownScript.cpp @@ -19,6 +19,8 @@ #include "ICmpUnknownScript.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpValueModificationManager.cpp =================================================================== --- source/simulation2/components/ICmpValueModificationManager.cpp +++ source/simulation2/components/ICmpValueModificationManager.cpp @@ -19,6 +19,8 @@ #include "ICmpValueModificationManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" Index: source/simulation2/components/ICmpVisibility.cpp =================================================================== --- source/simulation2/components/ICmpVisibility.cpp +++ source/simulation2/components/ICmpVisibility.cpp @@ -19,6 +19,8 @@ #include "ICmpVisibility.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/scripting/ScriptComponent.h" #include "simulation2/system/InterfaceScripted.h" Index: source/simulation2/components/ICmpVision.cpp =================================================================== --- source/simulation2/components/ICmpVision.cpp +++ source/simulation2/components/ICmpVision.cpp @@ -19,8 +19,10 @@ #include "ICmpVision.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Vision) -DEFINE_INTERFACE_METHOD_CONST_0("GetRange", entity_pos_t, ICmpVision, GetRange) +DEFINE_INTERFACE_METHOD("GetRange", ICmpVision, GetRange) END_INTERFACE_WRAPPER(Vision) Index: source/simulation2/components/ICmpVisual.cpp =================================================================== --- source/simulation2/components/ICmpVisual.cpp +++ source/simulation2/components/ICmpVisual.cpp @@ -19,19 +19,21 @@ #include "ICmpVisual.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(Visual) -DEFINE_INTERFACE_METHOD_2("SetVariant", void, ICmpVisual, SetVariant, CStr, CStr) -DEFINE_INTERFACE_METHOD_CONST_0("GetAnimationName", std::string, ICmpVisual, GetAnimationName) -DEFINE_INTERFACE_METHOD_CONST_0("GetProjectileActor", std::wstring, ICmpVisual, GetProjectileActor) -DEFINE_INTERFACE_METHOD_CONST_0("GetProjectileLaunchPoint", CFixedVector3D, ICmpVisual, GetProjectileLaunchPoint) -DEFINE_INTERFACE_METHOD_3("SelectAnimation", void, ICmpVisual, SelectAnimation, std::string, bool, fixed) -DEFINE_INTERFACE_METHOD_1("SetAnimationSyncRepeat", void, ICmpVisual, SetAnimationSyncRepeat, fixed) -DEFINE_INTERFACE_METHOD_1("SetAnimationSyncOffset", void, ICmpVisual, SetAnimationSyncOffset, fixed) -DEFINE_INTERFACE_METHOD_4("SetShadingColor", void, ICmpVisual, SetShadingColor, fixed, fixed, fixed, fixed) -DEFINE_INTERFACE_METHOD_2("SetVariable", void, ICmpVisual, SetVariable, std::string, float) -DEFINE_INTERFACE_METHOD_CONST_0("GetActorSeed", u32, ICmpVisual, GetActorSeed) -DEFINE_INTERFACE_METHOD_1("SetActorSeed", void, ICmpVisual, SetActorSeed, u32) -DEFINE_INTERFACE_METHOD_CONST_0("HasConstructionPreview", bool, ICmpVisual, HasConstructionPreview) +DEFINE_INTERFACE_METHOD("SetVariant", ICmpVisual, SetVariant) +DEFINE_INTERFACE_METHOD("GetAnimationName", ICmpVisual, GetAnimationName) +DEFINE_INTERFACE_METHOD("GetProjectileActor", ICmpVisual, GetProjectileActor) +DEFINE_INTERFACE_METHOD("GetProjectileLaunchPoint", ICmpVisual, GetProjectileLaunchPoint) +DEFINE_INTERFACE_METHOD("SelectAnimation", ICmpVisual, SelectAnimation) +DEFINE_INTERFACE_METHOD("SetAnimationSyncRepeat", ICmpVisual, SetAnimationSyncRepeat) +DEFINE_INTERFACE_METHOD("SetAnimationSyncOffset", ICmpVisual, SetAnimationSyncOffset) +DEFINE_INTERFACE_METHOD("SetShadingColor", ICmpVisual, SetShadingColor) +DEFINE_INTERFACE_METHOD("SetVariable", ICmpVisual, SetVariable) +DEFINE_INTERFACE_METHOD("GetActorSeed", ICmpVisual, GetActorSeed) +DEFINE_INTERFACE_METHOD("SetActorSeed", ICmpVisual, SetActorSeed) +DEFINE_INTERFACE_METHOD("HasConstructionPreview", ICmpVisual, HasConstructionPreview) END_INTERFACE_WRAPPER(Visual) Index: source/simulation2/components/ICmpWaterManager.cpp =================================================================== --- source/simulation2/components/ICmpWaterManager.cpp +++ source/simulation2/components/ICmpWaterManager.cpp @@ -19,10 +19,12 @@ #include "ICmpWaterManager.h" +#include "scriptinterface/FunctionWrapper.h" +#include "scriptinterface/ScriptInterface.h" #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(WaterManager) -DEFINE_INTERFACE_METHOD_0("RecomputeWaterData", void, ICmpWaterManager, RecomputeWaterData) -DEFINE_INTERFACE_METHOD_1("SetWaterLevel", void, ICmpWaterManager, SetWaterLevel, entity_pos_t) -DEFINE_INTERFACE_METHOD_CONST_2("GetWaterLevel", entity_pos_t, ICmpWaterManager, GetWaterLevel, entity_pos_t, entity_pos_t) +DEFINE_INTERFACE_METHOD("RecomputeWaterData", ICmpWaterManager, RecomputeWaterData) +DEFINE_INTERFACE_METHOD("SetWaterLevel", ICmpWaterManager, SetWaterLevel) +DEFINE_INTERFACE_METHOD("GetWaterLevel", ICmpWaterManager, GetWaterLevel) END_INTERFACE_WRAPPER(WaterManager) Index: source/simulation2/components/tests/test_scripts.h =================================================================== --- source/simulation2/components/tests/test_scripts.h +++ source/simulation2/components/tests/test_scripts.h @@ -19,6 +19,8 @@ #include "ps/Filesystem.h" +#include "scriptinterface/FunctionWrapper.h" + class TestComponentScripts : public CxxTest::TestSuite { public: @@ -94,8 +96,8 @@ ScriptTestSetup(componentManager.GetScriptInterface()); - componentManager.GetScriptInterface().RegisterFunction ("LoadComponentScript"); - componentManager.GetScriptInterface().RegisterFunction ("LoadHelperScript"); + ScriptWrapper::WrapAndRegister(componentManager.GetScriptInterface(), "LoadComponentScript"); + ScriptWrapper::WrapAndRegister(componentManager.GetScriptInterface(), "LoadHelperScript"); componentManager.LoadComponentTypes(); Index: source/simulation2/scripting/JSInterface_Simulation.h =================================================================== --- source/simulation2/scripting/JSInterface_Simulation.h +++ source/simulation2/scripting/JSInterface_Simulation.h @@ -26,16 +26,16 @@ { JS::Value GuiInterfaceCall(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue data); void PostNetworkCommand(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue cmd); - entity_id_t PickEntityAtPoint(ScriptInterface::CxPrivate* pCxPrivate, int x, int y); - void DumpSimState(ScriptInterface::CxPrivate* pCxPrivate); - std::vector PickPlayerEntitiesInRect(ScriptInterface::CxPrivate* pCxPrivate, int x0, int y0, int x1, int y1, int player); - std::vector PickPlayerEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate, int player); - std::vector PickNonGaiaEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate); - std::vector GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CxPrivate* pCxPrivate); + entity_id_t PickEntityAtPoint(int x, int y); + void DumpSimState(); + std::vector PickPlayerEntitiesInRect(int x0, int y0, int x1, int y1, int player); + std::vector PickPlayerEntitiesOnScreen(int player); + std::vector PickNonGaiaEntitiesOnScreen(); + std::vector GetEntitiesWithStaticObstructionOnScreen(); JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInterface::CxPrivate* pCxPrivate, entity_pos_t x, entity_pos_t z); - std::vector PickSimilarPlayerEntities(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations); + std::vector PickSimilarPlayerEntities(const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations); JS::Value GetAIs(ScriptInterface::CxPrivate* pCxPrivate); - void SetBoundingBoxDebugOverlay(ScriptInterface::CxPrivate* pCxPrivate, bool enabled); + void SetBoundingBoxDebugOverlay(bool enabled); void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); } Index: source/simulation2/scripting/JSInterface_Simulation.cpp =================================================================== --- source/simulation2/scripting/JSInterface_Simulation.cpp +++ 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/Simulation2.h" #include "simulation2/system/Entity.h" @@ -77,34 +78,34 @@ cmpCommandQueue->PostNetworkCommand(cmd2); } -void JSI_Simulation::DumpSimState(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +void JSI_Simulation::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::CxPrivate* UNUSED(pCxPrivate), int x, int y) +entity_id_t JSI_Simulation::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::CxPrivate* UNUSED(pCxPrivate), int x0, int y0, int x1, int y1, int player) +std::vector JSI_Simulation::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::CxPrivate* UNUSED(pCxPrivate), int player) +std::vector JSI_Simulation::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::CxPrivate* UNUSED(pCxPrivate)) +std::vector JSI_Simulation::PickNonGaiaEntitiesOnScreen() { return EntitySelection::PickNonGaiaEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, false); } -std::vector JSI_Simulation::GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +std::vector JSI_Simulation::GetEntitiesWithStaticObstructionOnScreen() { struct StaticObstructionFilter { @@ -135,7 +136,7 @@ CFG_GET_VAL("gui.session.snaptoedgesdistancethreshold", distanceThreshold); CFixedVector2D entityPos(x, z); - std::vector entities = GetEntitiesWithStaticObstructionOnScreen(pCxPrivate); + std::vector entities = GetEntitiesWithStaticObstructionOnScreen(); for (entity_id_t entity : entities) { CmpPtr cmpObstruction(sim->GetSimContext(), entity); @@ -190,7 +191,7 @@ return edgeList; } -std::vector JSI_Simulation::PickSimilarPlayerEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) +std::vector JSI_Simulation::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); } @@ -200,23 +201,25 @@ return ICmpAIManager::GetAIs(*(pCxPrivate->pScriptInterface)); } -void JSI_Simulation::SetBoundingBoxDebugOverlay(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool enabled) +void JSI_Simulation::SetBoundingBoxDebugOverlay(bool enabled) { ICmpSelectable::ms_EnableDebugOverlays = enabled; } void JSI_Simulation::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - 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"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name); + Register(GuiInterfaceCall); + Register(PostNetworkCommand); + Register(DumpSimState); + Register(GetAIs); + Register(PickEntityAtPoint); + Register(PickPlayerEntitiesInRect); + Register(PickPlayerEntitiesOnScreen); + Register(PickNonGaiaEntitiesOnScreen); + Register(GetEntitiesWithStaticObstructionOnScreen); + Register(GetEdgesOfStaticObstructionsOnScreenNearTo); + Register(PickSimilarPlayerEntities); + Register(SetBoundingBoxDebugOverlay); +#undef Register } Index: source/simulation2/system/ComponentManager.h =================================================================== --- source/simulation2/system/ComponentManager.h +++ source/simulation2/system/ComponentManager.h @@ -272,25 +272,28 @@ ScriptInterface& GetScriptInterface() { return m_ScriptInterface; } +public: + static CComponentManager* GetComponentManagerFromCxPrivateData(JSContext* cx, JS::CallArgs& callArgs); private: // Implementations of functions exposed to scripts - static void Script_RegisterComponentType_Common(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent); - static void Script_RegisterComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor); - static void Script_RegisterSystemComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor); - static void Script_ReRegisterComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor); - static void Script_RegisterInterface(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name); - static void Script_RegisterMessageType(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name); - static void Script_RegisterGlobal(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name, JS::HandleValue value); - static IComponent* Script_QueryInterface(ScriptInterface::CxPrivate* pCxPrivate, int ent, int iid); - static std::vector Script_GetEntitiesWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid); - static std::vector Script_GetComponentsWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid); - static void Script_PostMessage(ScriptInterface::CxPrivate* pCxPrivate, int ent, int mtid, JS::HandleValue data); - static void Script_BroadcastMessage(ScriptInterface::CxPrivate* pCxPrivate, int mtid, JS::HandleValue data); - static int Script_AddEntity(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName); - static int Script_AddLocalEntity(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName); - static void Script_DestroyEntity(ScriptInterface::CxPrivate* pCxPrivate, int ent); - static void Script_FlushDestroyedEntities(ScriptInterface::CxPrivate* pCxPrivate); + void Script_RegisterComponentType_Common(int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent); + void Script_RegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor); + void Script_RegisterSystemComponentType(int iid, const std::string& cname, JS::HandleValue ctor); + void Script_ReRegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor); + void Script_RegisterInterface(const std::string& name); + void Script_RegisterMessageType(const std::string& name); + void Script_RegisterGlobal(const std::string& name, JS::HandleValue value); + IComponent* Script_QueryInterface(int ent, int iid); + std::vector Script_GetEntitiesWithInterface(int iid); + std::vector Script_GetComponentsWithInterface(int iid); + void Script_PostMessage(int ent, int mtid, JS::HandleValue data); + void Script_BroadcastMessage(int mtid, JS::HandleValue data); + int Script_AddEntity(const std::string& templateName); + int Script_AddLocalEntity(const std::string& templateName); + void Script_DestroyEntity(int ent); + void Script_FlushDestroyedEntities(); +private: CMessage* ConstructMessage(int mtid, JS::HandleValue data); void SendGlobalMessage(entity_id_t ent, const CMessage& msg); Index: source/simulation2/system/ComponentManager.cpp =================================================================== --- source/simulation2/system/ComponentManager.cpp +++ source/simulation2/system/ComponentManager.cpp @@ -24,6 +24,7 @@ #include "ps/Filesystem.h" #include "ps/Profile.h" #include "ps/scripting/JSInterface_VFS.h" +#include "scriptinterface/FunctionWrapper.h" #include "simulation2/components/ICmpTemplateManager.h" #include "simulation2/MessageTypes.h" #include "simulation2/system/DynamicSubscription.h" @@ -68,21 +69,24 @@ if (!skipScriptFunctions) { JSI_VFS::RegisterScriptFunctions_Simulation(m_ScriptInterface); - m_ScriptInterface.RegisterFunction ("RegisterComponentType"); - m_ScriptInterface.RegisterFunction ("RegisterSystemComponentType"); - m_ScriptInterface.RegisterFunction ("ReRegisterComponentType"); - m_ScriptInterface.RegisterFunction ("RegisterInterface"); - m_ScriptInterface.RegisterFunction ("RegisterMessageType"); - m_ScriptInterface.RegisterFunction ("RegisterGlobal"); - m_ScriptInterface.RegisterFunction ("QueryInterface"); - m_ScriptInterface.RegisterFunction, int, CComponentManager::Script_GetEntitiesWithInterface> ("GetEntitiesWithInterface"); - m_ScriptInterface.RegisterFunction, int, CComponentManager::Script_GetComponentsWithInterface> ("GetComponentsWithInterface"); - m_ScriptInterface.RegisterFunction ("PostMessage"); - m_ScriptInterface.RegisterFunction ("BroadcastMessage"); - m_ScriptInterface.RegisterFunction ("AddEntity"); - m_ScriptInterface.RegisterFunction ("AddLocalEntity"); - m_ScriptInterface.RegisterFunction ("DestroyEntity"); - m_ScriptInterface.RegisterFunction ("FlushDestroyedEntities"); +#define Register(name) ScriptWrapper::WrapAndRegister(m_ScriptInterface, #name); + Register(RegisterComponentType); + Register(RegisterSystemComponentType); + Register(ReRegisterComponentType); + Register(RegisterInterface); + Register(RegisterMessageType); + Register(RegisterGlobal); + Register(QueryInterface); + Register(GetEntitiesWithInterface); + Register(GetComponentsWithInterface); + Register(PostMessage); + Register(BroadcastMessage); + Register(AddEntity); + Register(AddLocalEntity); + Register(DestroyEntity); + Register(FlushDestroyedEntities); +#undef Register } // Globalscripts may use VFS script functions @@ -149,53 +153,57 @@ return ok; } -void CComponentManager::Script_RegisterComponentType_Common(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent) +CComponentManager* CComponentManager::GetComponentManagerFromCxPrivateData(JSContext* cx, JS::CallArgs&) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - JSContext* cx = componentManager->m_ScriptInterface.GetContext(); + return static_cast(ScriptInterface::GetScriptInterfaceAndCBData(cx)->pCBData); +} + +void CComponentManager::Script_RegisterComponentType_Common(int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent) +{ + JSContext* cx = m_ScriptInterface.GetContext(); JSAutoRequest rq(cx); // Find the C++ component that wraps the interface - int cidWrapper = componentManager->GetScriptWrapper(iid); + int cidWrapper = GetScriptWrapper(iid); if (cidWrapper == CID__Invalid) { - componentManager->m_ScriptInterface.ReportError("Invalid interface id"); + m_ScriptInterface.ReportError("Invalid interface id"); return; } - const ComponentType& ctWrapper = componentManager->m_ComponentTypesById[cidWrapper]; + const ComponentType& ctWrapper = m_ComponentTypesById[cidWrapper]; bool mustReloadComponents = false; // for hotloading - ComponentTypeId cid = componentManager->LookupCID(cname); + ComponentTypeId cid = LookupCID(cname); if (cid == CID__Invalid) { if (reRegister) { - componentManager->m_ScriptInterface.ReportError(("ReRegistering component type that was not registered before '" + cname + "'").c_str()); + m_ScriptInterface.ReportError(("ReRegistering component type that was not registered before '" + cname + "'").c_str()); return; } // Allocate a new cid number - cid = componentManager->m_NextScriptComponentTypeId++; - componentManager->m_ComponentTypeIdsByName[cname] = cid; + cid = m_NextScriptComponentTypeId++; + m_ComponentTypeIdsByName[cname] = cid; if (systemComponent) - componentManager->MarkScriptedComponentForSystemEntity(cid); + MarkScriptedComponentForSystemEntity(cid); } else { // Component type is already loaded, so do hotloading: - if (!componentManager->m_CurrentlyHotloading && !reRegister) + if (!m_CurrentlyHotloading && !reRegister) { - componentManager->m_ScriptInterface.ReportError(("Registering component type with already-registered name '" + cname + "'").c_str()); + m_ScriptInterface.ReportError(("Registering component type with already-registered name '" + cname + "'").c_str()); return; } - const ComponentType& ctPrevious = componentManager->m_ComponentTypesById[cid]; + const ComponentType& ctPrevious = m_ComponentTypesById[cid]; // We can only replace scripted component types, not native ones if (ctPrevious.type != CT_Script) { - componentManager->m_ScriptInterface.ReportError(("Loading script component type with same name '" + cname + "' as native component").c_str()); + m_ScriptInterface.ReportError(("Loading script component type with same name '" + cname + "' as native component").c_str()); return; } @@ -204,23 +212,23 @@ if (ctPrevious.iid != iid) { // ...though it only matters if any components exist with this type - if (!componentManager->m_ComponentsByTypeId[cid].empty()) + if (!m_ComponentsByTypeId[cid].empty()) { - componentManager->m_ScriptInterface.ReportError("Hotloading script component type mustn't change interface ID"); + m_ScriptInterface.ReportError("Hotloading script component type mustn't change interface ID"); return; } } // Remove the old component type's message subscriptions std::map >::iterator it; - for (it = componentManager->m_LocalMessageSubscriptions.begin(); it != componentManager->m_LocalMessageSubscriptions.end(); ++it) + for (it = m_LocalMessageSubscriptions.begin(); it != m_LocalMessageSubscriptions.end(); ++it) { std::vector& types = it->second; std::vector::iterator ctit = find(types.begin(), types.end(), cid); if (ctit != types.end()) types.erase(ctit); } - for (it = componentManager->m_GlobalMessageSubscriptions.begin(); it != componentManager->m_GlobalMessageSubscriptions.end(); ++it) + for (it = m_GlobalMessageSubscriptions.begin(); it != m_GlobalMessageSubscriptions.end(); ++it) { std::vector& types = it->second; std::vector::iterator ctit = find(types.begin(), types.end(), cid); @@ -232,20 +240,20 @@ } JS::RootedValue protoVal(cx); - if (!componentManager->m_ScriptInterface.GetProperty(ctor, "prototype", &protoVal)) + if (!m_ScriptInterface.GetProperty(ctor, "prototype", &protoVal)) { - componentManager->m_ScriptInterface.ReportError("Failed to get property 'prototype'"); + m_ScriptInterface.ReportError("Failed to get property 'prototype'"); return; } if (!protoVal.isObject()) { - componentManager->m_ScriptInterface.ReportError("Component has no constructor"); + m_ScriptInterface.ReportError("Component has no constructor"); return; } std::string schema = ""; - if (componentManager->m_ScriptInterface.HasProperty(protoVal, "Schema")) - componentManager->m_ScriptInterface.GetProperty(protoVal, "Schema", schema); + if (m_ScriptInterface.HasProperty(protoVal, "Schema")) + m_ScriptInterface.GetProperty(protoVal, "Schema", schema); // Construct a new ComponentType, using the wrapper's alloc functions ComponentType ct{ @@ -257,16 +265,16 @@ schema, DefPersistentRooted(cx, ctor) }; - componentManager->m_ComponentTypesById[cid] = std::move(ct); + m_ComponentTypesById[cid] = std::move(ct); - componentManager->m_CurrentComponent = cid; // needed by Subscribe + m_CurrentComponent = cid; // needed by Subscribe // Find all the ctor prototype's On* methods, and subscribe to the appropriate messages: std::vector methods; - if (!componentManager->m_ScriptInterface.EnumeratePropertyNames(protoVal, false, methods)) + if (!m_ScriptInterface.EnumeratePropertyNames(protoVal, false, methods)) { - componentManager->m_ScriptInterface.ReportError("Failed to enumerate component properties."); + m_ScriptInterface.ReportError("Failed to enumerate component properties."); return; } @@ -286,115 +294,105 @@ name = name.substr(6); } - std::map::const_iterator mit = componentManager->m_MessageTypeIdsByName.find(name); - if (mit == componentManager->m_MessageTypeIdsByName.end()) + std::map::const_iterator mit = m_MessageTypeIdsByName.find(name); + if (mit == m_MessageTypeIdsByName.end()) { - componentManager->m_ScriptInterface.ReportError(("Registered component has unrecognized '" + *it + "' message handler method").c_str()); + m_ScriptInterface.ReportError(("Registered component has unrecognized '" + *it + "' message handler method").c_str()); return; } if (isGlobal) - componentManager->SubscribeGloballyToMessageType(mit->second); + SubscribeGloballyToMessageType(mit->second); else - componentManager->SubscribeToMessageType(mit->second); + SubscribeToMessageType(mit->second); } - componentManager->m_CurrentComponent = CID__Invalid; + m_CurrentComponent = CID__Invalid; if (mustReloadComponents) { // For every script component with this cid, we need to switch its // prototype from the old constructor's prototype property to the new one's - const std::map& comps = componentManager->m_ComponentsByTypeId[cid]; + const std::map& comps = m_ComponentsByTypeId[cid]; std::map::const_iterator eit = comps.begin(); for (; eit != comps.end(); ++eit) { JS::RootedValue instance(cx, eit->second->GetJSInstance()); if (!instance.isNull()) - componentManager->m_ScriptInterface.SetPrototype(instance, protoVal); + m_ScriptInterface.SetPrototype(instance, protoVal); } } } -void CComponentManager::Script_RegisterComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor) +void CComponentManager::Script_RegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - componentManager->Script_RegisterComponentType_Common(pCxPrivate, iid, cname, ctor, false, false); - componentManager->m_ScriptInterface.SetGlobal(cname.c_str(), ctor, componentManager->m_CurrentlyHotloading); + Script_RegisterComponentType_Common(iid, cname, ctor, false, false); + m_ScriptInterface.SetGlobal(cname.c_str(), ctor, m_CurrentlyHotloading); } -void CComponentManager::Script_RegisterSystemComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor) +void CComponentManager::Script_RegisterSystemComponentType(int iid, const std::string& cname, JS::HandleValue ctor) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - componentManager->Script_RegisterComponentType_Common(pCxPrivate, iid, cname, ctor, false, true); - componentManager->m_ScriptInterface.SetGlobal(cname.c_str(), ctor, componentManager->m_CurrentlyHotloading); + Script_RegisterComponentType_Common(iid, cname, ctor, false, true); + m_ScriptInterface.SetGlobal(cname.c_str(), ctor, m_CurrentlyHotloading); } -void CComponentManager::Script_ReRegisterComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, const std::string& cname, JS::HandleValue ctor) +void CComponentManager::Script_ReRegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor) { - Script_RegisterComponentType_Common(pCxPrivate, iid, cname, ctor, true, false); + Script_RegisterComponentType_Common(iid, cname, ctor, true, false); } -void CComponentManager::Script_RegisterInterface(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name) +void CComponentManager::Script_RegisterInterface(const std::string& name) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - - std::map::iterator it = componentManager->m_InterfaceIdsByName.find(name); - if (it != componentManager->m_InterfaceIdsByName.end()) + std::map::iterator it = m_InterfaceIdsByName.find(name); + if (it != m_InterfaceIdsByName.end()) { // Redefinitions are fine (and just get ignored) when hotloading; otherwise // they're probably unintentional and should be reported - if (!componentManager->m_CurrentlyHotloading) - componentManager->m_ScriptInterface.ReportError(("Registering interface with already-registered name '" + name + "'").c_str()); + if (!m_CurrentlyHotloading) + m_ScriptInterface.ReportError(("Registering interface with already-registered name '" + name + "'").c_str()); return; } // IIDs start at 1, so size+1 is the next unused one - size_t id = componentManager->m_InterfaceIdsByName.size() + 1; - componentManager->m_InterfaceIdsByName[name] = (InterfaceId)id; - componentManager->m_ComponentsByInterface.resize(id+1); // add one so we can index by InterfaceId - componentManager->m_ScriptInterface.SetGlobal(("IID_" + name).c_str(), (int)id); + size_t id = m_InterfaceIdsByName.size() + 1; + m_InterfaceIdsByName[name] = (InterfaceId)id; + m_ComponentsByInterface.resize(id+1); // add one so we can index by InterfaceId + m_ScriptInterface.SetGlobal(("IID_" + name).c_str(), (int)id); } -void CComponentManager::Script_RegisterMessageType(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name) +void CComponentManager::Script_RegisterMessageType(const std::string& name) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - - std::map::iterator it = componentManager->m_MessageTypeIdsByName.find(name); - if (it != componentManager->m_MessageTypeIdsByName.end()) + std::map::iterator it = m_MessageTypeIdsByName.find(name); + if (it != m_MessageTypeIdsByName.end()) { // Redefinitions are fine (and just get ignored) when hotloading; otherwise // they're probably unintentional and should be reported - if (!componentManager->m_CurrentlyHotloading) - componentManager->m_ScriptInterface.ReportError(("Registering message type with already-registered name '" + name + "'").c_str()); + if (!m_CurrentlyHotloading) + m_ScriptInterface.ReportError(("Registering message type with already-registered name '" + name + "'").c_str()); return; } // MTIDs start at 1, so size+1 is the next unused one - size_t id = componentManager->m_MessageTypeIdsByName.size() + 1; - componentManager->RegisterMessageType((MessageTypeId)id, name.c_str()); - componentManager->m_ScriptInterface.SetGlobal(("MT_" + name).c_str(), (int)id); + size_t id = m_MessageTypeIdsByName.size() + 1; + RegisterMessageType((MessageTypeId)id, name.c_str()); + m_ScriptInterface.SetGlobal(("MT_" + name).c_str(), (int)id); } -void CComponentManager::Script_RegisterGlobal(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name, JS::HandleValue value) +void CComponentManager::Script_RegisterGlobal(const std::string& name, JS::HandleValue value) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - componentManager->m_ScriptInterface.SetGlobal(name.c_str(), value, componentManager->m_CurrentlyHotloading); + m_ScriptInterface.SetGlobal(name.c_str(), value, m_CurrentlyHotloading); } -IComponent* CComponentManager::Script_QueryInterface(ScriptInterface::CxPrivate* pCxPrivate, int ent, int iid) +// TESTDIRECT_CALL +IComponent* CComponentManager::Script_QueryInterface(int ent, int iid) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - IComponent* component = componentManager->QueryInterface((entity_id_t)ent, iid); - return component; + return QueryInterface((entity_id_t)ent, iid); } -std::vector CComponentManager::Script_GetEntitiesWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid) +std::vector CComponentManager::Script_GetEntitiesWithInterface(int iid) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - std::vector ret; - const InterfaceListUnordered& ents = componentManager->GetEntitiesWithInterfaceUnordered(iid); + const InterfaceListUnordered& ents = GetEntitiesWithInterfaceUnordered(iid); for (InterfaceListUnordered::const_iterator it = ents.begin(); it != ents.end(); ++it) if (!ENTITY_IS_LOCAL(it->first)) ret.push_back(it->first); @@ -402,12 +400,10 @@ return ret; } -std::vector CComponentManager::Script_GetComponentsWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid) +std::vector CComponentManager::Script_GetComponentsWithInterface(int iid) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - std::vector ret; - InterfaceList ents = componentManager->GetEntitiesWithInterface(iid); + InterfaceList ents = GetEntitiesWithInterface(iid); for (InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it) ret.push_back(it->second); // TODO: maybe we should exclude local entities return ret; @@ -428,67 +424,60 @@ } } -void CComponentManager::Script_PostMessage(ScriptInterface::CxPrivate* pCxPrivate, int ent, int mtid, JS::HandleValue data) +void CComponentManager::Script_PostMessage(int ent, int mtid, JS::HandleValue data) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - - CMessage* msg = componentManager->ConstructMessage(mtid, data); + CMessage* msg = ConstructMessage(mtid, data); if (!msg) return; // error - componentManager->PostMessage(ent, *msg); + PostMessage(ent, *msg); delete msg; } -void CComponentManager::Script_BroadcastMessage(ScriptInterface::CxPrivate* pCxPrivate, int mtid, JS::HandleValue data) +void CComponentManager::Script_BroadcastMessage(int mtid, JS::HandleValue data) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - - CMessage* msg = componentManager->ConstructMessage(mtid, data); + CMessage* msg = ConstructMessage(mtid, data); if (!msg) return; // error - componentManager->BroadcastMessage(*msg); + BroadcastMessage(*msg); delete msg; } -int CComponentManager::Script_AddEntity(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName) +// TESTDIRECT_CALL +int CComponentManager::Script_AddEntity(const std::string& templateName) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - std::wstring name(templateName.begin(), templateName.end()); // TODO: should validate the string to make sure it doesn't contain scary characters // that will let it access non-component-template files - entity_id_t ent = componentManager->AddEntity(name, componentManager->AllocateNewEntity()); + entity_id_t ent = AddEntity(name, AllocateNewEntity()); return (int)ent; } -int CComponentManager::Script_AddLocalEntity(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName) +// TESTDIRECT_CALL +int CComponentManager::Script_AddLocalEntity(const std::string& templateName) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - std::wstring name(templateName.begin(), templateName.end()); // TODO: should validate the string to make sure it doesn't contain scary characters // that will let it access non-component-template files - entity_id_t ent = componentManager->AddEntity(name, componentManager->AllocateNewLocalEntity()); + entity_id_t ent = AddEntity(name, AllocateNewLocalEntity()); return (int)ent; } -void CComponentManager::Script_DestroyEntity(ScriptInterface::CxPrivate* pCxPrivate, int ent) +// TESTDIRECT_CALL +void CComponentManager::Script_DestroyEntity(int ent) { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - - componentManager->DestroyComponentsSoon(ent); + DestroyComponentsSoon(ent); } -void CComponentManager::Script_FlushDestroyedEntities(ScriptInterface::CxPrivate *pCxPrivate) +// TESTDIRECT_CALL +void CComponentManager::Script_FlushDestroyedEntities() { - CComponentManager* componentManager = static_cast (pCxPrivate->pCBData); - componentManager->FlushDestroyedComponents(); + FlushDestroyedComponents(); } void CComponentManager::ResetState() Index: source/simulation2/system/InterfaceScripted.h =================================================================== --- source/simulation2/system/InterfaceScripted.h +++ source/simulation2/system/InterfaceScripted.h @@ -18,8 +18,6 @@ #ifndef INCLUDED_INTERFACE_SCRIPTED #define INCLUDED_INTERFACE_SCRIPTED -#include "scriptinterface/ScriptInterface.h" - #define BEGIN_INTERFACE_WRAPPER(iname) \ JSClass class_ICmp##iname = { \ "ICmp" #iname, JSCLASS_HAS_PRIVATE \ @@ -41,53 +39,7 @@ ICmp##iname::InterfaceInit(scriptInterface); \ } -#define DEFINE_INTERFACE_METHOD_0(scriptname, rettype, classname, methodname) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 0, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_1(scriptname, rettype, classname, methodname, arg1) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 1, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_2(scriptname, rettype, classname, methodname, arg1, arg2) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 2, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_3(scriptname, rettype, classname, methodname, arg1, arg2, arg3) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 3, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_4(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 4, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_5(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 5, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_6(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 6, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_7(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ - JS_FN(scriptname, (ScriptInterface::callMethod), 7, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -// const methods -#define DEFINE_INTERFACE_METHOD_CONST_0(scriptname, rettype, classname, methodname) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 0, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_CONST_1(scriptname, rettype, classname, methodname, arg1) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 1, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_CONST_2(scriptname, rettype, classname, methodname, arg1, arg2) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 2, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_CONST_3(scriptname, rettype, classname, methodname, arg1, arg2, arg3) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 3, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_CONST_4(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 4, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_CONST_5(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 5, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_CONST_6(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 6, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), - -#define DEFINE_INTERFACE_METHOD_CONST_7(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ - JS_FN(scriptname, (ScriptInterface::callMethodConst), 7, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT), +#define DEFINE_INTERFACE_METHOD(scriptname, classname, methodname) \ +ScriptWrapper::Wrap(scriptname), #endif // INCLUDED_INTERFACE_SCRIPTED Index: source/soundmanager/scripting/JSInterface_Sound.cpp =================================================================== --- source/soundmanager/scripting/JSInterface_Sound.cpp +++ 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 @@ { #if CONFIG2_AUDIO - void StartMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) + void StartMusic() { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMusicEnabled(true); } - void StopMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) + void StopMusic() { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMusicEnabled(false); } - void ClearPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) + void ClearPlaylist() { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->ClearPlayListItems(); } - void AddPlaylistItem(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& filename) + void AddPlaylistItem(const std::wstring& filename) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->AddPlayListItem(VfsPath(filename)); } - void StartPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool looping) + void StartPlaylist(bool looping) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->StartPlayList(looping ); } - void PlayMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), 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::CxPrivate* UNUSED(pCxPrivate), 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::CxPrivate* UNUSED(pCxPrivate), 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::CxPrivate* UNUSED(pCxPrivate)) + bool MusicPlaying() { return true; } - void SetMasterGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain) + void SetMasterGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMasterGain(gain); } - void SetMusicGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain) + void SetMusicGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetMusicGain(gain); } - void SetAmbientGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain) + void SetAmbientGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetAmbientGain(gain); } - void SetActionGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain) + void SetActionGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetActionGain(gain); } - void SetUIGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain) + void SetUIGain(float gain) { if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) sndManager->SetUIGain(gain); @@ -116,38 +117,40 @@ #else - bool MusicPlaying(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){ return false; } - void PlayAmbientSound(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ){} - void PlayUISound(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} - void PlayMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} - void StartPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool UNUSED(looping) ){} - void AddPlaylistItem(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& UNUSED(filename) ){} - void ClearPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){} - void StopMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){} - void StartMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){} - void SetMasterGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain){} - void SetMusicGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain){} - void SetAmbientGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain){} - void SetActionGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float gain){} - void SetUIGain(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float 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 gain){} + void SetMusicGain(float gain){} + void SetAmbientGain(float gain){} + void SetActionGain(float gain){} + void SetUIGain(float gain){} #endif void RegisterScriptFunctions(const ScriptInterface& scriptInterface) { - 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"); +#define Register(name) ScriptWrapper::WrapAndRegister(scriptInterface, #name) + Register(StartMusic); + Register(StopMusic); + Register(ClearPlaylist); + Register(AddPlaylistItem); + Register(StartPlaylist); + Register(PlayMusic); + Register(PlayUISound); + Register(PlayAmbientSound); + Register(MusicPlaying); + Register(SetMasterGain); + Register(SetMusicGain); + Register(SetAmbientGain); + Register(SetActionGain); + Register(SetUIGain); +#undef Register } } Index: source/test_setup.cpp =================================================================== --- source/test_setup.cpp +++ source/test_setup.cpp @@ -36,6 +36,7 @@ #include "lib/timer.h" #include "lib/sysdep/sysdep.h" #include "ps/Profiler2.h" +#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/ScriptEngine.h" #include "scriptinterface/ScriptInterface.h" @@ -129,7 +130,7 @@ namespace { - void script_TS_FAIL(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& msg) + void script_TS_FAIL(const std::wstring& msg) { TS_FAIL(utf8_from_wstring(msg).c_str()); } @@ -137,7 +138,7 @@ void ScriptTestSetup(const ScriptInterface& scriptinterface) { - scriptinterface.RegisterFunction("TS_FAIL"); + ScriptWrapper::WrapAndRegister(scriptinterface, "TS_FAIL"); // Load the TS_* function definitions // (We don't use VFS because tests might not have the normal VFS paths loaded)