/* Crafter.Build Copyright (C) 2025 Catcrafts® Catcrafts.net This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ module; #include #include export module Crafter.Component:ComponentRef; import :Component; import Crafter.Event; namespace Crafter { export template class ComponentRef { public: Event refChanged; Event componentDeleted; T* component; ComponentRef() : component(nullptr) { }; ComponentRef(T* component) { SetRef(component); } virtual void SetRef(T* component) { if (component != nullptr) { onDeleteListener.SetEvent(&component->onDelete, [this, component]() { this->componentDeleted.Invoke(component); }); } refChanged.Invoke(component); this->component = component; } protected: EventListener onDeleteListener; }; export template class ComponentRefOwning : public ComponentRef { public: ComponentRefOwning() : ComponentRef() { }; ComponentRefOwning(T* component) : ComponentRef(component) { component->AddOwner(); } ~ComponentRefOwning() { if (ComponentRef::component) { ComponentRef::component->RemoveOwner(); } } void SetRef(T* component) override { if (this->component != nullptr) { this->component->RemoveOwner(); } if (component != nullptr) { ComponentRef::onDeleteListener.SetEvent(&component->onDelete, [this, component]() { this->componentDeleted.Invoke(component); }); component->AddOwner(); } this->component = component; } }; export template class ComponentRefVector { public: Event componentRemoved; Event componentDeleted; Event componentAdded; std::vector components; ComponentRefVector() { } ComponentRefVector(std::vector components) : components(components) { } virtual void AddComponent(T* component) { componentAdded.Invoke(component); components.push_back(component); listeners.emplace_back(&component->onDelete, [this, component]() { this->componentDeleted.Invoke(component); components.erase(std::remove(components.begin(), components.end(), component), components.end()); }); } virtual void RemoveComponent(T* component) { componentRemoved.Invoke(component); auto it = find(components.begin(), components.end(), component); int index = it - components.begin(); components.erase(components.begin() + index); } private: std::vector> listeners; }; export template class ComponentRefVectorOwning : public ComponentRefVector { public: ComponentRefVectorOwning() { } ComponentRefVectorOwning(std::vector components) : ComponentRefVector(components) { } ~ComponentRefVectorOwning() { for (size_t i = 0; i < ComponentRefVector::components.size(); i++) { ComponentRefVector::components[i]->RemoveOwner(); } } void AddComponent(T* component) override { ComponentRefVector::AddComponent(component); component->AddOwner(); } void RemoveComponent(T* component) override { ComponentRefVector::RemoveComponent(component); component->RemoveOwner(); } }; }