Changeset 24969

Timestamp:
Mar 1, 2021, 9:52:24 PM (3 years ago)
Author:
wraitii
Message:

Introduce C++ templates replacements for DEFINE_INTERFACE_X and RegisterFunction macros

The new methods:

  • aren't included in ScriptInterface.h directly, lightening that header
  • don't use boost CPP
  • don't need argument types or number or constness to be specified
  • can work with object methods somewhat transparently
  • support optional cmptPrivate (allowing removal of many UNUSED macro)
  • support optional const ScriptRequest&, which is safer.

This first diff changes only some of the JSI files & the component manager. Further diffs will update other files and finally delete the current code.

Differential Revision: https://code.wildfiregames.com/D2818

Location:
ps/trunk/source
Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/source/gui/Scripting/ScriptFunctions.cpp

    r24229 r24969  
    1 /* Copyright (C) 2019 Wildfire Games.
     1/* Copyright (C) 20 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    5151void GuiScriptingInit(ScriptInterface& scriptInterface)
    5252{
     53
     54
    5355    JSI_GUISize::RegisterScriptClass(scriptInterface);
    5456    JSI_ConfigDB::RegisterScriptFunctions(scriptInterface);
    55     JSI_Console::RegisterScriptFunctions(scriptInterface);
     57    JSI_Console::RegisterScriptFunctions();
    5658    JSI_Debug::RegisterScriptFunctions(scriptInterface);
    5759    JSI_GUIManager::RegisterScriptFunctions(scriptInterface);
  • ps/trunk/source/ps/CConsole.h

    r22344 r24969  
    1 /* Copyright (C) 2019 Wildfire Games.
     1/* Copyright (C) 20 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    8383    void FlushBuffer();
    8484
    85     bool IsActive() { return m_bVisible; }
     85    bool IsActive() { return m_bVisible; }
    8686
    8787    int m_iFontHeight;
  • ps/trunk/source/ps/GameSetup/HWDetect.cpp

    r24625 r24969  
    1818#include "precompiled.h"
    1919
    20 #include "scriptinterface/ScriptInterface.h"
    21 
    2220#include "lib/ogl.h"
    2321#include "lib/svn_revision.h"
     
    4644#include "ps/UserReport.h"
    4745#include "ps/VideoMode.h"
     46
     47
    4848
    4949// TODO: Support OpenGL platforms which don't use GLX as well.
     
    7575static void ReportGLLimits(const ScriptInterface& scriptInterface, JS::HandleValue settings);
    7676
    77 void SetDisableAudio(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool disabled)
     77void SetDisableAudio(bool disabled)
    7878{
    7979    g_DisableAudio = disabled;
     
    9191    JSI_ConfigDB::RegisterScriptFunctions(scriptInterface);
    9292
    93     scriptInterface.RegisterFunction<void, bool, &SetDisableAudio>("SetDisableAudio");
     93    "SetDisableAudio");
    9494
    9595    // Load the detection script:
  • ps/trunk/source/ps/scripting/JSInterface_Console.cpp

    r24177 r24969  
    1 /* Copyright (C) 2018 Wildfire Games.
     1/* Copyright (C) 20 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    2222#include "ps/CConsole.h"
    2323#include "ps/CLogger.h"
    24 #include "scriptinterface/ScriptInterface.h"
     24#include "scriptinterface/.h"
    2525
    26 bool JSI_Console::CheckGlobalInitialized()
     26namespace
     27{
     28CConsole* ConsoleGetter(const ScriptRequest&, JS::CallArgs&)
    2729{
    2830    if (!g_Console)
    2931    {
    3032        LOGERROR("Trying to access the console when it's not initialized!");
    31         return false;
     33        return ;
    3234    }
    33     return true;
     35    return g_Console;
     36}
    3437}
    3538
    36 bool JSI_Console::GetVisibleEnabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
     39)
    3740{
    38     if (!CheckGlobalInitialized())
    39         return false;
    40     return g_Console->IsActive();
     41    ScriptFunction::Register<&CConsole::IsActive, ConsoleGetter>(rq, "Console_GetVisibleEnabled");
     42    ScriptFunction::Register<&CConsole::SetVisible, ConsoleGetter>(rq, "Console_SetVisibleEnabled");
    4143}
    42 
    43 void JSI_Console::SetVisibleEnabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool Enabled)
    44 {
    45     if (!CheckGlobalInitialized())
    46         return;
    47     g_Console->SetVisible(Enabled);
    48 }
    49 
    50 void JSI_Console::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
    51 {
    52     scriptInterface.RegisterFunction<bool, &JSI_Console::GetVisibleEnabled>("Console_GetVisibleEnabled");
    53     scriptInterface.RegisterFunction<void, bool, &JSI_Console::SetVisibleEnabled>("Console_SetVisibleEnabled");
    54 }
  • ps/trunk/source/ps/scripting/JSInterface_Console.h

    r24177 r24969  
    1 /* Copyright (C) 2018 Wildfire Games.
     1/* Copyright (C) 20 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    1919#define INCLUDED_JSI_CONSOLE
    2020
    21 #include "scriptinterface/ScriptInterface.h"
     21class ScriptRequest;
    2222
    2323namespace JSI_Console
    2424{
    25     bool CheckGlobalInitialized();
    26     bool GetVisibleEnabled(ScriptInterface::CmptPrivate* pCmptPrivate);
    27     void SetVisibleEnabled(ScriptInterface::CmptPrivate* pCmptPrivate, bool Enabled);
    28 
    29     void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
     25    void RegisterScriptFunctions(const ScriptRequest& rq);
    3026}
    3127
  • ps/trunk/source/ps/scripting/JSInterface_Hotkey.cpp

    r24675 r24969  
    2525#include "ps/Hotkey.h"
    2626#include "ps/KeyName.h"
     27
    2728#include "scriptinterface/ScriptConversions.h"
    2829
     
    6768}
    6869
     70
     71
    6972/**
    7073 * @return a (js) object mapping hotkey name (from cfg files) to a list ofscancode names
    7174 */
    72 JS::Value GetHotkeyMap(ScriptInterface::CmptPrivate* pCmptPrivate)
     75JS::Value GetHotkeyMap()
    7376{
    74     ScriptRequest rq(*pCmptPrivate->pScriptInterface);
    75 
    7677    JS::RootedValue hotkeyMap(rq.cx);
    7778
     
    9091                hotkeys[mapping.name].emplace_back(keymap);
    9192        }
    92     pCmptPrivate->pScriptInterface->ToJSVal(rq, &hotkeyMap, hotkeys);
     93    ToJSVal(rq, &hotkeyMap, hotkeys);
    9394
    9495    return hotkeyMap;
     
    9899 * @return a (js) object mapping scancode names to their locale-dependent name.
    99100 */
    100 JS::Value GetScancodeKeyNames(ScriptInterface::CmptPrivate* pCmptPrivate)
     101JS::Value GetScancodeKeyNames()
    101102{
    102     ScriptRequest rq(*pCmptPrivate->pScriptInterface);
    103 
    104103    JS::RootedValue obj(rq.cx);
    105104    std::unordered_map<std::string, std::string> map;
     
    109108    for (int i = 0; i < MOUSE_LAST; ++i)
    110109        map[FindScancodeName(static_cast<SDL_Scancode>(i))] = FindKeyName(static_cast<SDL_Scancode>(i));
    111     pCmptPrivate->pScriptInterface->ToJSVal(rq, &obj, map);
     110    ToJSVal(rq, &obj, map);
    112111
    113112    return obj;
    114113}
    115114
    116 void ReloadHotkeys(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
     115void ReloadHotkeys()
    117116{
    118117    UnloadHotkeys();
     
    120119}
    121120
    122 JS::Value GetConflicts(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue combination)
     121JS::Value GetConflicts(, JS::HandleValue combination)
    123122{
    124     ScriptInterface* scriptInterface = pCmptPrivate->pScriptInterface;
    125     ScriptRequest rq(*scriptInterface);
    126 
    127123    std::vector<std::string> keys;
    128     if (!scriptInterface->FromJSVal(rq, combination, keys))
     124    if (!FromJSVal(rq, combination, keys))
    129125    {
    130126        LOGERROR("Invalid hotkey combination");
     
    162158
    163159    JS::RootedValue ret(rq.cx);
    164     scriptInterface->ToJSVal(rq, &ret, conflicts);
     160    ToJSVal(rq, &ret, conflicts);
    165161    return ret;
    166162}
     163
    167164
    168 void JSI_Hotkey::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
     165void JSI_Hotkey::RegisterScriptFunctions(const Script)
    169166{
    170     scriptInterface.RegisterFunction<JS::Value, &GetHotkeyMap>("GetHotkeyMap");
    171     scriptInterface.RegisterFunction<JS::Value, &GetScancodeKeyNames>("GetScancodeKeyNames");
    172     scriptInterface.RegisterFunction<void, &ReloadHotkeys>("ReloadHotkeys");
    173     scriptInterface.RegisterFunction<JS::Value, JS::HandleValue, &GetConflicts>("GetConflicts");
     167    "GetHotkeyMap");
     168    "GetScancodeKeyNames");
     169    "ReloadHotkeys");
     170    "GetConflicts");
    174171}
  • ps/trunk/source/ps/scripting/JSInterface_Hotkey.h

    r24215 r24969  
    1 /* Copyright (C) 2020 Wildfire Games.
     1/* Copyright (C) 202 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    1919#define INCLUDED_JSI_HOTKEY
    2020
    21 #include "scriptinterface/ScriptInterface.h"
     21class ScriptRequest;
    2222
    2323namespace JSI_Hotkey
    2424{
    25     void RegisterScriptFunctions(const ScriptInterface& ScriptInterface);
     25    void RegisterScriptFunctions(const Script);
    2626}
    2727
  • ps/trunk/source/ps/scripting/JSInterface_Mod.cpp

    r24177 r24969  
    1 /* Copyright (C) 2018 Wildfire Games.
     1/* Copyright (C) 20 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    2121
    2222#include "ps/Mod.h"
     23
    2324#include "scriptinterface/ScriptInterface.h"
    2425
    2526extern void RestartEngine();
    2627
    27 JS::Value JSI_Mod::GetEngineInfo(ScriptInterface::CmptPrivate* pCmptPrivate)
     28namespace
     29{
     30JS::Value GetEngineInfo(ScriptInterface::CmptPrivate* pCmptPrivate)
    2831{
    2932    return Mod::GetEngineInfo(*(pCmptPrivate->pScriptInterface));
     
    4043 *         properties.
    4144 */
    42 JS::Value JSI_Mod::GetAvailableMods(ScriptInterface::CmptPrivate* pCmptPrivate)
     45JS::Value GetAvailableMods(ScriptInterface::CmptPrivate* pCmptPrivate)
    4346{
    4447    return Mod::GetAvailableMods(*(pCmptPrivate->pScriptInterface));
    4548}
    4649
    47 void JSI_Mod::RestartEngine(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
    48 {
    49     ::RestartEngine();
    50 }
    51 
    52 void JSI_Mod::SetMods(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::vector<CStr>& mods)
     50void SetMods(const std::vector<CStr>& mods)
    5351{
    5452    g_modsLoaded = mods;
    5553}
     54
    5655
    57 void JSI_Mod::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
     56void JSI_Mod::RegisterScriptFunctions(const Script)
    5857{
    59     scriptInterface.RegisterFunction<JS::Value, &GetEngineInfo>("GetEngineInfo");
    60     scriptInterface.RegisterFunction<JS::Value, &JSI_Mod::GetAvailableMods>("GetAvailableMods");
    61     scriptInterface.RegisterFunction<void, &JSI_Mod::RestartEngine>("RestartEngine");
    62     scriptInterface.RegisterFunction<void, std::vector<CStr>, &JSI_Mod::SetMods>("SetMods");
     58    "GetEngineInfo");
     59    "GetAvailableMods");
     60    "RestartEngine");
     61    "SetMods");
    6362}
  • ps/trunk/source/ps/scripting/JSInterface_Mod.h

    r24177 r24969  
    1 /* Copyright (C) 2018 Wildfire Games.
     1/* Copyright (C) 20 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    1919#define INCLUDED_JSI_MOD
    2020
    21 #include "ps/CStr.h"
    22 #include "scriptinterface/ScriptInterface.h"
     21class ScriptRequest;
    2322
    2423namespace JSI_Mod
    2524{
    26     void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
    27 
    28     JS::Value GetEngineInfo(ScriptInterface::CmptPrivate* pCmptPrivate);
    29     JS::Value GetAvailableMods(ScriptInterface::CmptPrivate* pCmptPrivate);
    30     void RestartEngine(ScriptInterface::CmptPrivate* pCmptPrivate);
    31     void SetMods(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStr>& mods);
     25    void RegisterScriptFunctions(const ScriptRequest& rq);
    3226}
    3327
  • ps/trunk/source/scriptinterface/ScriptInterface.cpp

    r24915 r24969  
    7373
    7474ScriptRequest::ScriptRequest(const ScriptInterface& scriptInterface) :
    75     cx(scriptInterface.m->m_cx)
     75    cx(scriptInterface.m->m_cx)
    7676{
    7777    m_formerRealm = JS::EnterRealm(cx, scriptInterface.m->m_glob);
  • ps/trunk/source/scriptinterface/ScriptInterface.h

    r24462 r24969  
    1 /* Copyright (C) 2020 Wildfire Games.
     1/* Copyright (C) 202 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    8484    JSContext* cx;
    8585    JSObject* glob;
     86
    8687private:
    8788    JS::Realm* m_formerRealm;
  • ps/trunk/source/simulation2/components/tests/test_scripts.h

    r24462 r24969  
    1 /* Copyright (C) 2020 Wildfire Games.
     1/* Copyright (C) 202 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    2222#include "ps/Filesystem.h"
    2323
     24
    2425#include "scriptinterface/ScriptContext.h"
    2526
     
    119120            ScriptTestSetup(componentManager.GetScriptInterface());
    120121
    121             componentManager.GetScriptInterface().RegisterFunction<void, VfsPath, Script_LoadComponentScript> ("LoadComponentScript");
    122             componentManager.GetScriptInterface().RegisterFunction<void, VfsPath, Script_LoadHelperScript> ("LoadHelperScript");
    123             componentManager.GetScriptInterface().RegisterFunction<JS::Value, JS::HandleValue, Script_SerializationRoundTrip> ("SerializationRoundTrip");
     122            ScriptRequest rq(componentManager.GetScriptInterface());
     123            ScriptFunction::Register<Script_LoadComponentScript>(rq, "LoadComponentScript");
     124            ScriptFunction::Register<Script_LoadHelperScript>(rq, "LoadHelperScript");
     125            ScriptFunction::Register<Script_SerializationRoundTrip>(rq, "SerializationRoundTrip");
    124126
    125127            componentManager.LoadComponentTypes();
  • ps/trunk/source/simulation2/system/ComponentManager.cpp

    r24915 r24969  
    1 /* Copyright (C) 2020 Wildfire Games.
     1/* Copyright (C) 202 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    2525#include "ps/Profile.h"
    2626#include "ps/scripting/JSInterface_VFS.h"
     27
    2728#include "simulation2/components/ICmpTemplateManager.h"
    2829#include "simulation2/MessageTypes.h"
     
    6970    {
    7071        JSI_VFS::RegisterScriptFunctions_Simulation(m_ScriptInterface);
    71         m_ScriptInterface.RegisterFunction<void, int, std::string, JS::HandleValue, CComponentManager::Script_RegisterComponentType> ("RegisterComponentType");
    72         m_ScriptInterface.RegisterFunction<void, int, std::string, JS::HandleValue, CComponentManager::Script_RegisterSystemComponentType> ("RegisterSystemComponentType");
    73         m_ScriptInterface.RegisterFunction<void, int, std::string, JS::HandleValue, CComponentManager::Script_ReRegisterComponentType> ("ReRegisterComponentType");
    74         m_ScriptInterface.RegisterFunction<void, std::string, CComponentManager::Script_RegisterInterface> ("RegisterInterface");
    75         m_ScriptInterface.RegisterFunction<void, std::string, CComponentManager::Script_RegisterMessageType> ("RegisterMessageType");
    76         m_ScriptInterface.RegisterFunction<void, std::string, JS::HandleValue, CComponentManager::Script_RegisterGlobal> ("RegisterGlobal");
    77         m_ScriptInterface.RegisterFunction<IComponent*, int, int, CComponentManager::Script_QueryInterface> ("QueryInterface");
    78         m_ScriptInterface.RegisterFunction<std::vector<int>, int, CComponentManager::Script_GetEntitiesWithInterface> ("GetEntitiesWithInterface");
    79         m_ScriptInterface.RegisterFunction<std::vector<IComponent*>, int, CComponentManager::Script_GetComponentsWithInterface> ("GetComponentsWithInterface");
    80         m_ScriptInterface.RegisterFunction<void, int, int, JS::HandleValue, CComponentManager::Script_PostMessage> ("PostMessage");
    81         m_ScriptInterface.RegisterFunction<void, int, JS::HandleValue, CComponentManager::Script_BroadcastMessage> ("BroadcastMessage");
    82         m_ScriptInterface.RegisterFunction<int, std::string, CComponentManager::Script_AddEntity> ("AddEntity");
    83         m_ScriptInterface.RegisterFunction<int, std::string, CComponentManager::Script_AddLocalEntity> ("AddLocalEntity");
    84         m_ScriptInterface.RegisterFunction<void, int, CComponentManager::Script_DestroyEntity> ("DestroyEntity");
    85         m_ScriptInterface.RegisterFunction<void, CComponentManager::Script_FlushDestroyedEntities> ("FlushDestroyedEntities");
     72        ScriptRequest rq(m_ScriptInterface);
     73        constexpr ScriptFunction::ObjectGetter<CComponentManager> Getter = &ScriptFunction::ObjectFromCBData<CComponentManager>;
     74        ScriptFunction::Register<&CComponentManager::Script_RegisterComponentType, Getter>(rq, "RegisterComponentType");
     75        ScriptFunction::Register<&CComponentManager::Script_RegisterSystemComponentType, Getter>(rq, "RegisterSystemComponentType");
     76        ScriptFunction::Register<&CComponentManager::Script_ReRegisterComponentType, Getter>(rq, "ReRegisterComponentType");
     77        ScriptFunction::Register<&CComponentManager::Script_RegisterInterface, Getter>(rq, "RegisterInterface");
     78        ScriptFunction::Register<&CComponentManager::Script_RegisterMessageType, Getter>(rq, "RegisterMessageType");
     79        ScriptFunction::Register<&CComponentManager::Script_RegisterGlobal, Getter>(rq, "RegisterGlobal");
     80        ScriptFunction::Register<&CComponentManager::Script_GetEntitiesWithInterface, Getter>(rq, "GetEntitiesWithInterface");
     81        ScriptFunction::Register<&CComponentManager::Script_GetComponentsWithInterface, Getter>(rq, "GetComponentsWithInterface");
     82        ScriptFunction::Register<&CComponentManager::Script_PostMessage, Getter>(rq, "PostMessage");
     83        ScriptFunction::Register<&CComponentManager::Script_BroadcastMessage, Getter>(rq, "BroadcastMessage");
     84        ScriptFunction::Register<&CComponentManager::Script_AddEntity, Getter>(rq, "AddEntity");
     85        ScriptFunction::Register<&CComponentManager::Script_AddLocalEntity, Getter>(rq, "AddLocalEntity");
     86        ScriptFunction::Register<&CComponentManager::QueryInterface, Getter>(rq, "QueryInterface");
     87        ScriptFunction::Register<&CComponentManager::DestroyComponentsSoon, Getter>(rq, "DestroyEntity");
     88        ScriptFunction::Register<&CComponentManager::FlushDestroyedComponents, Getter>(rq, "FlushDestroyedEntities");
    8689    }
    8790
     
    150153}
    151154
    152 void CComponentManager::Script_RegisterComponentType_Common(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent)
    153 {
    154     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    155     ScriptRequest rq(componentManager->m_ScriptInterface);
     155void CComponentManager::Script_RegisterComponentType_Common(int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent)
     156{
     157    ScriptRequest rq(m_ScriptInterface);
    156158
    157159    // Find the C++ component that wraps the interface
    158     int cidWrapper = componentManager->GetScriptWrapper(iid);
     160    int cidWrapper = GetScriptWrapper(iid);
    159161    if (cidWrapper == CID__Invalid)
    160162    {
     
    162164        return;
    163165    }
    164     const ComponentType& ctWrapper = componentManager->m_ComponentTypesById[cidWrapper];
     166    const ComponentType& ctWrapper = m_ComponentTypesById[cidWrapper];
    165167
    166168    bool mustReloadComponents = false; // for hotloading
    167169
    168     ComponentTypeId cid = componentManager->LookupCID(cname);
     170    ComponentTypeId cid = LookupCID(cname);
    169171    if (cid == CID__Invalid)
    170172    {
     
    175177        }
    176178        // Allocate a new cid number
    177         cid = componentManager->m_NextScriptComponentTypeId++;
    178         componentManager->m_ComponentTypeIdsByName[cname] = cid;
     179        cid = m_NextScriptComponentTypeId++;
     180        m_ComponentTypeIdsByName[cname] = cid;
    179181        if (systemComponent)
    180             componentManager->MarkScriptedComponentForSystemEntity(cid);
     182            MarkScriptedComponentForSystemEntity(cid);
    181183    }
    182184    else
     
    184186        // Component type is already loaded, so do hotloading:
    185187
    186         if (!componentManager->m_CurrentlyHotloading && !reRegister)
     188        if (!m_CurrentlyHotloading && !reRegister)
    187189        {
    188190            ScriptException::Raise(rq, "Registering component type with already-registered name '%s'", cname.c_str());
     
    190192        }
    191193
    192         const ComponentType& ctPrevious = componentManager->m_ComponentTypesById[cid];
     194        const ComponentType& ctPrevious = m_ComponentTypesById[cid];
    193195
    194196        // We can only replace scripted component types, not native ones
     
    204206        {
    205207            // ...though it only matters if any components exist with this type
    206             if (!componentManager->m_ComponentsByTypeId[cid].empty())
     208            if (!m_ComponentsByTypeId[cid].empty())
    207209            {
    208210                ScriptException::Raise(rq, "Hotloading script component type mustn't change interface ID");
     
    213215        // Remove the old component type's message subscriptions
    214216        std::map<MessageTypeId, std::vector<ComponentTypeId> >::iterator it;
    215         for (it = componentManager->m_LocalMessageSubscriptions.begin(); it != componentManager->m_LocalMessageSubscriptions.end(); ++it)
     217        for (it = m_LocalMessageSubscriptions.end(); ++it)
    216218        {
    217219            std::vector<ComponentTypeId>& types = it->second;
     
    220222                types.erase(ctit);
    221223        }
    222         for (it = componentManager->m_GlobalMessageSubscriptions.begin(); it != componentManager->m_GlobalMessageSubscriptions.end(); ++it)
     224        for (it = m_GlobalMessageSubscriptions.end(); ++it)
    223225        {
    224226            std::vector<ComponentTypeId>& types = it->second;
     
    232234
    233235    JS::RootedValue protoVal(rq.cx);
    234     if (!componentManager->m_ScriptInterface.GetProperty(ctor, "prototype", &protoVal))
     236    if (!m_ScriptInterface.GetProperty(ctor, "prototype", &protoVal))
    235237    {
    236238        ScriptException::Raise(rq, "Failed to get property 'prototype'");
     
    244246    std::string schema = "<empty/>";
    245247
    246     if (componentManager->m_ScriptInterface.HasProperty(protoVal, "Schema"))
    247         componentManager->m_ScriptInterface.GetProperty(protoVal, "Schema", schema);
     248    if (m_ScriptInterface.HasProperty(protoVal, "Schema"))
     249        m_ScriptInterface.GetProperty(protoVal, "Schema", schema);
    248250
    249251    // Construct a new ComponentType, using the wrapper's alloc functions
     
    257259        std::make_unique<JS::PersistentRootedValue>(rq.cx, ctor)
    258260    };
    259     componentManager->m_ComponentTypesById[cid] = std::move(ct);
    260 
    261     componentManager->m_CurrentComponent = cid; // needed by Subscribe
     261    m_ComponentTypesById[cid] = std::move(ct);
     262
     263    m_CurrentComponent = cid; // needed by Subscribe
    262264
    263265    // Find all the ctor prototype's On* methods, and subscribe to the appropriate messages:
    264266    std::vector<std::string> methods;
    265267
    266     if (!componentManager->m_ScriptInterface.EnumeratePropertyNames(protoVal, false, methods))
     268    if (!m_ScriptInterface.EnumeratePropertyNames(protoVal, false, methods))
    267269    {
    268270        ScriptException::Raise(rq, "Failed to enumerate component properties.");
     
    286288        }
    287289
    288         std::map<std::string, MessageTypeId>::const_iterator mit = componentManager->m_MessageTypeIdsByName.find(name);
    289         if (mit == componentManager->m_MessageTypeIdsByName.end())
     290        std::map<std::string, MessageTypeId>::const_iterator mit = m_MessageTypeIdsByName.find(name);
     291        if (mit == m_MessageTypeIdsByName.end())
    290292        {
    291293            ScriptException::Raise(rq, "Registered component has unrecognized '%s' message handler method", it->c_str());
     
    294296
    295297        if (isGlobal)
    296             componentManager->SubscribeGloballyToMessageType(mit->second);
     298            SubscribeGloballyToMessageType(mit->second);
    297299        else
    298             componentManager->SubscribeToMessageType(mit->second);
    299     }
    300 
    301     componentManager->m_CurrentComponent = CID__Invalid;
     300            SubscribeToMessageType(mit->second);
     301    }
     302
     303    m_CurrentComponent = CID__Invalid;
    302304
    303305    if (mustReloadComponents)
     
    305307        // For every script component with this cid, we need to switch its
    306308        // prototype from the old constructor's prototype property to the new one's
    307         const std::map<entity_id_t, IComponent*>& comps = componentManager->m_ComponentsByTypeId[cid];
     309        const std::map<entity_id_t, IComponent*>& comps = m_ComponentsByTypeId[cid];
    308310        std::map<entity_id_t, IComponent*>::const_iterator eit = comps.begin();
    309311        for (; eit != comps.end(); ++eit)
     
    311313            JS::RootedValue instance(rq.cx, eit->second->GetJSInstance());
    312314            if (!instance.isNull())
    313                 componentManager->m_ScriptInterface.SetPrototype(instance, protoVal);
    314         }
    315     }
    316 }
    317 
    318 void CComponentManager::Script_RegisterComponentType(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor)
    319 {
    320     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    321     componentManager->Script_RegisterComponentType_Common(pCmptPrivate, iid, cname, ctor, false, false);
    322     componentManager->m_ScriptInterface.SetGlobal(cname.c_str(), ctor, componentManager->m_CurrentlyHotloading);
    323 }
    324 
    325 void CComponentManager::Script_RegisterSystemComponentType(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor)
    326 {
    327     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    328     componentManager->Script_RegisterComponentType_Common(pCmptPrivate, iid, cname, ctor, false, true);
    329     componentManager->m_ScriptInterface.SetGlobal(cname.c_str(), ctor, componentManager->m_CurrentlyHotloading);
    330 }
    331 
    332 void CComponentManager::Script_ReRegisterComponentType(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor)
    333 {
    334     Script_RegisterComponentType_Common(pCmptPrivate, iid, cname, ctor, true, false);
    335 }
    336 
    337 void CComponentManager::Script_RegisterInterface(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name)
    338 {
    339     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    340 
    341     std::map<std::string, InterfaceId>::iterator it = componentManager->m_InterfaceIdsByName.find(name);
    342     if (it != componentManager->m_InterfaceIdsByName.end())
     315                m_ScriptInterface.SetPrototype(instance, protoVal);
     316        }
     317    }
     318}
     319
     320void CComponentManager::Script_RegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor)
     321{
     322    Script_RegisterComponentType_Common(iid, cname, ctor, false, false);
     323    m_ScriptInterface.SetGlobal(cname.c_str(), ctor, m_CurrentlyHotloading);
     324}
     325
     326void CComponentManager::Script_RegisterSystemComponentType(int iid, const std::string& cname, JS::HandleValue ctor)
     327{
     328    Script_RegisterComponentType_Common(iid, cname, ctor, false, true);
     329    m_ScriptInterface.SetGlobal(cname.c_str(), ctor, m_CurrentlyHotloading);
     330}
     331
     332void CComponentManager::Script_ReRegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor)
     333{
     334    Script_RegisterComponentType_Common(iid, cname, ctor, true, false);
     335}
     336
     337void CComponentManager::Script_RegisterInterface(const std::string& name)
     338{
     339    std::map<std::string, InterfaceId>::iterator it = m_InterfaceIdsByName.find(name);
     340    if (it != m_InterfaceIdsByName.end())
    343341    {
    344342        // Redefinitions are fine (and just get ignored) when hotloading; otherwise
    345343        // they're probably unintentional and should be reported
    346         if (!componentManager->m_CurrentlyHotloading)
    347         {
    348             ScriptRequest rq(componentManager->m_ScriptInterface);
     344        if (!m_CurrentlyHotloading)
     345        {
     346            ScriptRequest rq(m_ScriptInterface);
    349347            ScriptException::Raise(rq, "Registering interface with already-registered name '%s'", name.c_str());
    350348        }
     
    353351
    354352    // IIDs start at 1, so size+1 is the next unused one
    355     size_t id = componentManager->m_InterfaceIdsByName.size() + 1;
    356     componentManager->m_InterfaceIdsByName[name] = (InterfaceId)id;
    357     componentManager->m_ComponentsByInterface.resize(id+1); // add one so we can index by InterfaceId
    358     componentManager->m_ScriptInterface.SetGlobal(("IID_" + name).c_str(), (int)id);
    359 }
    360 
    361 void CComponentManager::Script_RegisterMessageType(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name)
    362 {
    363     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    364 
    365     std::map<std::string, MessageTypeId>::iterator it = componentManager->m_MessageTypeIdsByName.find(name);
    366     if (it != componentManager->m_MessageTypeIdsByName.end())
     353    size_t id = m_InterfaceIdsByName.size() + 1;
     354    m_InterfaceIdsByName[name] = (InterfaceId)id;
     355    m_ComponentsByInterface.resize(id+1); // add one so we can index by InterfaceId
     356    m_ScriptInterface.SetGlobal(("IID_" + name).c_str(), (int)id);
     357}
     358
     359void CComponentManager::Script_RegisterMessageType(const std::string& name)
     360{
     361    std::map<std::string, MessageTypeId>::iterator it = m_MessageTypeIdsByName.find(name);
     362    if (it != m_MessageTypeIdsByName.end())
    367363    {
    368364        // Redefinitions are fine (and just get ignored) when hotloading; otherwise
    369365        // they're probably unintentional and should be reported
    370         if (!componentManager->m_CurrentlyHotloading)
    371         {
    372             ScriptRequest rq(componentManager->m_ScriptInterface);
     366        if (!m_CurrentlyHotloading)
     367        {
     368            ScriptRequest rq(m_ScriptInterface);
    373369            ScriptException::Raise(rq, "Registering message type with already-registered name '%s'", name.c_str());
    374370        }
     
    377373
    378374    // MTIDs start at 1, so size+1 is the next unused one
    379     size_t id = componentManager->m_MessageTypeIdsByName.size() + 1;
    380     componentManager->RegisterMessageType((MessageTypeId)id, name.c_str());
    381     componentManager->m_ScriptInterface.SetGlobal(("MT_" + name).c_str(), (int)id);
    382 }
    383 
    384 void CComponentManager::Script_RegisterGlobal(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name, JS::HandleValue value)
    385 {
    386     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    387     componentManager->m_ScriptInterface.SetGlobal(name.c_str(), value, componentManager->m_CurrentlyHotloading);
    388 }
    389 
    390 IComponent* CComponentManager::Script_QueryInterface(ScriptInterface::CmptPrivate* pCmptPrivate, int ent, int iid)
    391 {
    392     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    393     IComponent* component = componentManager->QueryInterface((entity_id_t)ent, iid);
    394     return component;
    395 }
    396 
    397 std::vector<int> CComponentManager::Script_GetEntitiesWithInterface(ScriptInterface::CmptPrivate* pCmptPrivate, int iid)
    398 {
    399     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    400 
     375    size_t id = m_MessageTypeIdsByName.size() + 1;
     376    RegisterMessageType((MessageTypeId)id, name.c_str());
     377    m_ScriptInterface.SetGlobal(("MT_" + name).c_str(), (int)id);
     378}
     379
     380void CComponentManager::Script_RegisterGlobal(const std::string& name, JS::HandleValue value)
     381{
     382    m_ScriptInterface.SetGlobal(name.c_str(), value, m_CurrentlyHotloading);
     383}
     384
     385std::vector<int> CComponentManager::Script_GetEntitiesWithInterface(int iid)
     386{
    401387    std::vector<int> ret;
    402     const InterfaceListUnordered& ents = componentManager->GetEntitiesWithInterfaceUnordered(iid);
     388    const InterfaceListUnordered& ents = GetEntitiesWithInterfaceUnordered(iid);
    403389    for (InterfaceListUnordered::const_iterator it = ents.begin(); it != ents.end(); ++it)
    404390        if (!ENTITY_IS_LOCAL(it->first))
     
    408394}
    409395
    410 std::vector<IComponent*> CComponentManager::Script_GetComponentsWithInterface(ScriptInterface::CmptPrivate* pCmptPrivate, int iid)
    411 {
    412     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    413 
     396std::vector<IComponent*> CComponentManager::Script_GetComponentsWithInterface(int iid)
     397{
    414398    std::vector<IComponent*> ret;
    415     InterfaceList ents = componentManager->GetEntitiesWithInterface(iid);
     399    InterfaceList ents = GetEntitiesWithInterface(iid);
    416400    for (InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it)
    417401        ret.push_back(it->second); // TODO: maybe we should exclude local entities
     
    434418}
    435419
    436 void CComponentManager::Script_PostMessage(ScriptInterface::CmptPrivate* pCmptPrivate, int ent, int mtid, JS::HandleValue data)
    437 {
    438     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    439 
    440     CMessage* msg = componentManager->ConstructMessage(mtid, data);
     420void CComponentManager::Script_PostMessage(int ent, int mtid, JS::HandleValue data)
     421{
     422    CMessage* msg = ConstructMessage(mtid, data);
    441423    if (!msg)
    442424        return; // error
    443425
    444     componentManager->PostMessage(ent, *msg);
     426    PostMessage(ent, *msg);
    445427
    446428    delete msg;
    447429}
    448430
    449 void CComponentManager::Script_BroadcastMessage(ScriptInterface::CmptPrivate* pCmptPrivate, int mtid, JS::HandleValue data)
    450 {
    451     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    452 
    453     CMessage* msg = componentManager->ConstructMessage(mtid, data);
     431void CComponentManager::Script_BroadcastMessage(int mtid, JS::HandleValue data)
     432{
     433    CMessage* msg = ConstructMessage(mtid, data);
    454434    if (!msg)
    455435        return; // error
    456436
    457     componentManager->BroadcastMessage(*msg);
     437    BroadcastMessage(*msg);
    458438
    459439    delete msg;
    460440}
    461441
    462 int CComponentManager::Script_AddEntity(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName)
    463 {
    464     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    465 
    466     std::wstring name(templateName.begin(), templateName.end());
     442int CComponentManager::Script_AddEntity(const std::wstring& templateName)
     443{
    467444    // TODO: should validate the string to make sure it doesn't contain scary characters
    468445    // that will let it access non-component-template files
    469 
    470     entity_id_t ent = componentManager->AddEntity(name, componentManager->AllocateNewEntity());
    471     return (int)ent;
    472 }
    473 
    474 int CComponentManager::Script_AddLocalEntity(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName)
    475 {
    476     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    477 
    478     std::wstring name(templateName.begin(), templateName.end());
     446    return AddEntity(templateName, AllocateNewEntity());
     447}
     448
     449int CComponentManager::Script_AddLocalEntity(const std::wstring& templateName)
     450{
    479451    // TODO: should validate the string to make sure it doesn't contain scary characters
    480452    // that will let it access non-component-template files
    481 
    482     entity_id_t ent = componentManager->AddEntity(name, componentManager->AllocateNewLocalEntity());
    483     return (int)ent;
    484 }
    485 
    486 void CComponentManager::Script_DestroyEntity(ScriptInterface::CmptPrivate* pCmptPrivate, int ent)
    487 {
    488     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    489 
    490     componentManager->DestroyComponentsSoon(ent);
    491 }
    492 
    493 void CComponentManager::Script_FlushDestroyedEntities(ScriptInterface::CmptPrivate *pCmptPrivate)
    494 {
    495     CComponentManager* componentManager = static_cast<CComponentManager*> (pCmptPrivate->pCBData);
    496     componentManager->FlushDestroyedComponents();
     453    return AddEntity(templateName, AllocateNewLocalEntity());
    497454}
    498455
  • ps/trunk/source/simulation2/system/ComponentManager.h

    r24203 r24969  
    1 /* Copyright (C) 2020 Wildfire Games.
     1/* Copyright (C) 202 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    274274private:
    275275    // Implementations of functions exposed to scripts
    276     static void Script_RegisterComponentType_Common(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent);
    277     static void Script_RegisterComponentType(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor);
    278     static void Script_RegisterSystemComponentType(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor);
    279     static void Script_ReRegisterComponentType(ScriptInterface::CmptPrivate* pCmptPrivate, int iid, const std::string& cname, JS::HandleValue ctor);
    280     static void Script_RegisterInterface(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name);
    281     static void Script_RegisterMessageType(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name);
    282     static void Script_RegisterGlobal(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name, JS::HandleValue value);
    283     static IComponent* Script_QueryInterface(ScriptInterface::CmptPrivate* pCmptPrivate, int ent, int iid);
    284     static std::vector<int> Script_GetEntitiesWithInterface(ScriptInterface::CmptPrivate* pCmptPrivate, int iid);
    285     static std::vector<IComponent*> Script_GetComponentsWithInterface(ScriptInterface::CmptPrivate* pCmptPrivate, int iid);
    286     static void Script_PostMessage(ScriptInterface::CmptPrivate* pCmptPrivate, int ent, int mtid, JS::HandleValue data);
    287     static void Script_BroadcastMessage(ScriptInterface::CmptPrivate* pCmptPrivate, int mtid, JS::HandleValue data);
    288     static int Script_AddEntity(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName);
    289     static int Script_AddLocalEntity(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName);
    290     static void Script_DestroyEntity(ScriptInterface::CmptPrivate* pCmptPrivate, int ent);
    291     static void Script_FlushDestroyedEntities(ScriptInterface::CmptPrivate* pCmptPrivate);
     276    void Script_RegisterComponentType_Common(int iid, const std::string& cname, JS::HandleValue ctor, bool reRegister, bool systemComponent);
     277    void Script_RegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor);
     278    void Script_RegisterSystemComponentType(int iid, const std::string& cname, JS::HandleValue ctor);
     279    void Script_ReRegisterComponentType(int iid, const std::string& cname, JS::HandleValue ctor);
     280    void Script_RegisterInterface(const std::string& name);
     281    void Script_RegisterMessageType(const std::string& name);
     282    void Script_RegisterGlobal(const std::string& name, JS::HandleValue value);
     283    std::vector<int> Script_GetEntitiesWithInterface(int iid);
     284    std::vector<IComponent*> Script_GetComponentsWithInterface(int iid);
     285    void Script_PostMessage(int ent, int mtid, JS::HandleValue data);
     286    void Script_BroadcastMessage(int mtid, JS::HandleValue data);
     287    int Script_AddEntity(const std::wstring& templateName);
     288    int Script_AddLocalEntity(const std::wstring& templateName);
    292289
    293290    CMessage* ConstructMessage(int mtid, JS::HandleValue data);
  • ps/trunk/source/test_setup.cpp

    r24530 r24969  
    3737#include "lib/sysdep/sysdep.h"
    3838#include "ps/Profiler2.h"
     39
    3940#include "scriptinterface/ScriptEngine.h"
    4041#include "scriptinterface/ScriptContext.h"
     
    139140namespace
    140141{
    141     void script_TS_FAIL(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& msg)
     142    void script_TS_FAIL(const std::wstring& msg)
    142143    {
    143144        TS_FAIL(utf8_from_wstring(msg).c_str());
     
    145146}
    146147
    147 void ScriptTestSetup(const ScriptInterface& scriptinterface)
     148void ScriptTestSetup(const ScriptInterface& scriptnterface)
    148149{
    149     scriptinterface.RegisterFunction<void, std::wstring, script_TS_FAIL>("TS_FAIL");
     150    ScriptRequest rq(scriptInterface);
     151    ScriptFunction::Register<script_TS_FAIL>(rq, "TS_FAIL");
    150152
    151153    // Load the TS_* function definitions
     
    155157    ENSURE(ifs.good());
    156158    std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
    157     ENSURE(scriptinterface.LoadScript(L"test_setup.js", content));
     159    ENSURE(scriptnterface.LoadScript(L"test_setup.js", content));
    158160}
Note: See TracChangeset for help on using the changeset viewer.