diff --git a/source/simulation2/scripting/ScriptComponent.h b/source/simulation2/scripting/ScriptComponent.h index fb9ece0096..845d052a2e 100644 --- a/source/simulation2/scripting/ScriptComponent.h +++ b/source/simulation2/scripting/ScriptComponent.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -82,8 +82,9 @@ private: #define REGISTER_COMPONENT_SCRIPT_WRAPPER(cname) \ void RegisterComponentType_##cname(CComponentManager& mgr) \ { \ - IComponent::RegisterComponentTypeScriptWrapper(mgr, CCmp##cname::GetInterfaceId(), CID_##cname, CCmp##cname::Allocate, CCmp##cname::Deallocate, #cname, CCmp##cname::GetSchema()); \ - CCmp##cname::ClassInit(mgr); \ + IComponent::RegisterComponentTypeScriptWrapper(mgr, CCmp##cname::GetInterfaceId(), \ + CID_##cname, CCmp##cname::Allocate, CCmp##cname::Deallocate, #cname, \ + CCmp##cname::GetSchema(), CCmp##cname::ClassInit); \ } diff --git a/source/simulation2/system/ComponentManager.cpp b/source/simulation2/system/ComponentManager.cpp index 3f15d08522..152e6b135a 100644 --- a/source/simulation2/system/ComponentManager.cpp +++ b/source/simulation2/system/ComponentManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -267,6 +267,9 @@ void CComponentManager::Script_RegisterComponentType_Common(int iid, const std:: m_CurrentComponent = cid; // needed by Subscribe + // Only now that we have constructed the CT_Script for this CT_ScriptWrapper, we can subscribe the CT_Script + ctWrapper.classInit(*this); + // Find all the ctor prototype's On* methods, and subscribe to the appropriate messages: std::vector methods; @@ -528,10 +531,12 @@ void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId c m_ComponentTypeIdsByName[name] = cid; } -void CComponentManager::RegisterComponentTypeScriptWrapper(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, - DeallocFunc dealloc, const char* name, const std::string& schema) +void CComponentManager::RegisterComponentTypeScriptWrapper(InterfaceId iid, ComponentTypeId cid, + AllocFunc alloc, DeallocFunc dealloc, const char* name, const std::string& schema, + ClassInitFunc classInit) { - ComponentType c{ CT_ScriptWrapper, iid, alloc, dealloc, name, schema, std::unique_ptr() }; + ComponentType c{ CT_ScriptWrapper, iid, alloc, dealloc, name, schema, + std::unique_ptr(), classInit }; m_ComponentTypesById.insert(std::make_pair(cid, std::move(c))); m_ComponentTypeIdsByName[name] = cid; // TODO: merge with RegisterComponentType diff --git a/source/simulation2/system/ComponentManager.h b/source/simulation2/system/ComponentManager.h index ce0d4cb8a8..8efa35a57e 100644 --- a/source/simulation2/system/ComponentManager.h +++ b/source/simulation2/system/ComponentManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -49,6 +49,7 @@ public: private: using AllocFunc = IComponent::AllocFunc; using DeallocFunc = IComponent::DeallocFunc; + using ClassInitFunc = IComponent::ClassInitFunc; // ComponentTypes come in three types: // Native: normal C++ component @@ -71,6 +72,7 @@ private: std::string name; std::string schema; // RelaxNG fragment std::unique_ptr ctor; // only valid if type == CT_Script + ClassInitFunc classInit; }; public: @@ -90,7 +92,8 @@ public: void RegisterMessageType(MessageTypeId mtid, const char* name); void RegisterComponentType(InterfaceId, ComponentTypeId, AllocFunc, DeallocFunc, const char*, const std::string& schema); - void RegisterComponentTypeScriptWrapper(InterfaceId, ComponentTypeId, AllocFunc, DeallocFunc, const char*, const std::string& schema); + void RegisterComponentTypeScriptWrapper(InterfaceId, ComponentTypeId, AllocFunc, DeallocFunc, + const char*, const std::string& schema, ClassInitFunc classInit); void MarkScriptedComponentForSystemEntity(CComponentManager::ComponentTypeId cid); diff --git a/source/simulation2/system/IComponent.cpp b/source/simulation2/system/IComponent.cpp index 76c63483bf..3c26399ddf 100644 --- a/source/simulation2/system/IComponent.cpp +++ b/source/simulation2/system/IComponent.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -38,9 +38,11 @@ void IComponent::RegisterComponentType(CComponentManager& mgr, EInterfaceId iid, mgr.RegisterComponentType(iid, cid, alloc, dealloc, name, schema); } -void IComponent::RegisterComponentTypeScriptWrapper(CComponentManager& mgr, EInterfaceId iid, EComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, const char* name, const std::string& schema) +void IComponent::RegisterComponentTypeScriptWrapper(CComponentManager& mgr, EInterfaceId iid, + EComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, const char* name, + const std::string& schema, ClassInitFunc classInit) { - mgr.RegisterComponentTypeScriptWrapper(iid, cid, alloc, dealloc, name, schema); + mgr.RegisterComponentTypeScriptWrapper(iid, cid, alloc, dealloc, name, schema, classInit); } void IComponent::HandleMessage(const CMessage& UNUSED(msg), bool UNUSED(global)) diff --git a/source/simulation2/system/IComponent.h b/source/simulation2/system/IComponent.h index 63a887573c..9c46c47f02 100644 --- a/source/simulation2/system/IComponent.h +++ b/source/simulation2/system/IComponent.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -35,13 +35,16 @@ public: // Component allocation types using AllocFunc = IComponent* (*)(const ScriptInterface& scriptInterface, JS::HandleValue ctor); using DeallocFunc = void (*)(IComponent*); + using ClassInitFunc = void (*)(CComponentManager& componentManager); virtual ~IComponent(); static std::string GetSchema(); static void RegisterComponentType(CComponentManager& mgr, EInterfaceId iid, EComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, const char* name, const std::string& schema); - static void RegisterComponentTypeScriptWrapper(CComponentManager& mgr, EInterfaceId iid, EComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, const char* name, const std::string& schema); + static void RegisterComponentTypeScriptWrapper(CComponentManager& mgr, EInterfaceId iid, + EComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, const char* name, + const std::string& schema, ClassInitFunc classInit); virtual void Init(const CParamNode& paramNode) = 0; virtual void Deinit() = 0;