Index: source/scriptinterface/ScriptInterface.h =================================================================== --- source/scriptinterface/ScriptInterface.h +++ source/scriptinterface/ScriptInterface.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,7 +24,7 @@ #include "scriptinterface/ScriptRequest.h" #include "scriptinterface/ScriptTypes.h" -#include +#include ERROR_GROUP(Scripting); ERROR_TYPE(Scripting, SetupFailed); @@ -273,7 +273,7 @@ // members have to be called before the custom destructor of ScriptInterface_impl. std::unique_ptr m; - std::map m_CustomObjectTypes; + std::unordered_map m_CustomObjectTypes; }; // Explicitly instantiate void* as that is used for the generic template, Index: source/scriptinterface/ScriptInterface.cpp =================================================================== --- source/scriptinterface/ScriptInterface.cpp +++ source/scriptinterface/ScriptInterface.cpp @@ -513,7 +513,7 @@ JSObject* ScriptInterface::CreateCustomObject(const std::string& typeName) const { - std::map::const_iterator it = m_CustomObjectTypes.find(typeName); + std::unordered_map::const_iterator it = m_CustomObjectTypes.find(typeName); if (it == m_CustomObjectTypes.end()) throw PSERROR_Scripting_TypeDoesNotExist(); Index: source/simulation2/components/CCmpFootprint.cpp =================================================================== --- source/simulation2/components/CCmpFootprint.cpp +++ source/simulation2/components/CCmpFootprint.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -39,6 +39,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(Footprint) + CACHE_WRAPPED_SCRIPT(Footprint); EShape m_Shape; entity_pos_t m_Size0; // width/radius Index: source/simulation2/components/CCmpObstruction.cpp =================================================================== --- source/simulation2/components/CCmpObstruction.cpp +++ source/simulation2/components/CCmpObstruction.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -53,6 +53,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(Obstruction) + CACHE_WRAPPED_SCRIPT(Obstruction); typedef ICmpObstructionManager::tag_t tag_t; typedef ICmpObstructionManager::flags_t flags_t; Index: source/simulation2/components/CCmpObstructionManager.cpp =================================================================== --- source/simulation2/components/CCmpObstructionManager.cpp +++ source/simulation2/components/CCmpObstructionManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -132,6 +132,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(ObstructionManager) + CACHE_WRAPPED_SCRIPT(ObstructionManager); bool m_DebugOverlayEnabled; bool m_DebugOverlayDirty; Index: source/simulation2/components/CCmpOwnership.cpp =================================================================== --- source/simulation2/components/CCmpOwnership.cpp +++ source/simulation2/components/CCmpOwnership.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -34,6 +34,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(Ownership) + CACHE_WRAPPED_SCRIPT(Ownership); player_id_t m_Owner; Index: source/simulation2/components/CCmpPosition.cpp =================================================================== --- source/simulation2/components/CCmpPosition.cpp +++ source/simulation2/components/CCmpPosition.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -57,6 +57,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(Position) + CACHE_WRAPPED_SCRIPT(Position); // Template state: Index: source/simulation2/components/CCmpProjectileManager.cpp =================================================================== --- source/simulation2/components/CCmpProjectileManager.cpp +++ source/simulation2/components/CCmpProjectileManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -51,6 +51,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(ProjectileManager) + CACHE_WRAPPED_SCRIPT(ProjectileManager); static std::string GetSchema() { Index: source/simulation2/components/CCmpRangeManager.cpp =================================================================== --- source/simulation2/components/CCmpRangeManager.cpp +++ source/simulation2/components/CCmpRangeManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -367,6 +367,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(RangeManager) + CACHE_WRAPPED_SCRIPT(RangeManager); bool m_DebugOverlayEnabled; bool m_DebugOverlayDirty; Index: source/simulation2/components/CCmpRangeOverlayRenderer.cpp =================================================================== --- source/simulation2/components/CCmpRangeOverlayRenderer.cpp +++ source/simulation2/components/CCmpRangeOverlayRenderer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -43,6 +43,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(RangeOverlayRenderer) + CACHE_WRAPPED_SCRIPT(RangeOverlayRenderer); CCmpRangeOverlayRenderer() : m_RangeOverlayData() { Index: source/simulation2/components/CCmpSoundManager.cpp =================================================================== --- source/simulation2/components/CCmpSoundManager.cpp +++ source/simulation2/components/CCmpSoundManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -35,6 +35,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(SoundManager) + CACHE_WRAPPED_SCRIPT(SoundManager); static std::string GetSchema() { Index: source/simulation2/components/CCmpTemplateManager.cpp =================================================================== --- source/simulation2/components/CCmpTemplateManager.cpp +++ source/simulation2/components/CCmpTemplateManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -37,6 +37,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(TemplateManager) + CACHE_WRAPPED_SCRIPT(TemplateManager); static std::string GetSchema() { Index: source/simulation2/components/CCmpTerritoryManager.cpp =================================================================== --- source/simulation2/components/CCmpTerritoryManager.cpp +++ source/simulation2/components/CCmpTerritoryManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -73,6 +73,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(TerritoryManager) + CACHE_WRAPPED_SCRIPT(TerritoryManager); static std::string GetSchema() { Index: source/simulation2/components/CCmpUnitMotion.h =================================================================== --- source/simulation2/components/CCmpUnitMotion.h +++ source/simulation2/components/CCmpUnitMotion.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -146,6 +146,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(UnitMotion) + CACHE_WRAPPED_SCRIPT(UnitMotion); bool m_DebugOverlayEnabled; std::vector m_DebugOverlayLongPathLines; Index: source/simulation2/components/CCmpVision.cpp =================================================================== --- source/simulation2/components/CCmpVision.cpp +++ source/simulation2/components/CCmpVision.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -36,6 +36,7 @@ } DEFAULT_COMPONENT_ALLOCATOR(Vision) + CACHE_WRAPPED_SCRIPT(Vision); // Template state: Index: source/simulation2/components/CCmpVisualActor.cpp =================================================================== --- source/simulation2/components/CCmpVisualActor.cpp +++ source/simulation2/components/CCmpVisualActor.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -65,6 +65,30 @@ DEFAULT_COMPONENT_ALLOCATOR(VisualActor) + mutable JS::PersistentRootedValue m_Instance; + JS::Value GetJSInstance() const override + { + if (m_Instance.isObject()) + return m_Instance.get(); + + const ScriptInterface& si = GetSimContext().GetScriptInterface(); + ScriptRequest rq(si); + + JS::RootedObject obj(rq.cx); + if (!NewJSObject(rq.GetScriptInterface(), &obj)) + { + /* Report as an error, since scripts really shouldn't try to use unscriptable interfaces*/ + LOGERROR("IComponent does not have a scriptable interface"); + return JS::UndefinedHandleValue; + } + + JS::SetPrivate(obj, static_cast(static_cast(const_cast(this)))); + JS::RootedValue ret(rq.cx); + ret.setObject(*obj); + m_Instance.init(rq.cx, ret); + return m_Instance.get(); + } + private: std::wstring m_BaseActorName, m_ActorName; bool m_IsFoundationActor; Index: source/simulation2/system/Component.h =================================================================== --- source/simulation2/system/Component.h +++ source/simulation2/system/Component.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -44,6 +44,30 @@ return CID_##cname; \ } +#define CACHE_WRAPPED_SCRIPT(iname) \ + mutable JS::PersistentRootedValue m_Instance; \ + JS::Value GetJSInstance() const override \ + { \ + if (m_Instance.isObject()) \ + return m_Instance.get(); \ + const ScriptInterface& si = GetSimContext().GetScriptInterface(); \ + ScriptRequest rq(si); \ + \ + JS::RootedObject obj(rq.cx); \ + if (!NewJSObject(rq.GetScriptInterface(), &obj)) \ + { \ + /* Report as an error, since scripts really shouldn't try to use unscriptable interfaces*/ \ + LOGERROR("IComponent does not have a scriptable interface"); \ + return JS::UndefinedHandleValue; \ + } \ + \ + JS::SetPrivate(obj, static_cast(static_cast(const_cast(this)))); \ + JS::RootedValue ret(rq.cx); \ + ret.setObject(*obj); \ + m_Instance.init(rq.cx, ret); \ + return m_Instance.get(); \ + } + #define DEFAULT_MOCK_COMPONENT() \ int GetComponentTypeId() const override \ { \