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(); } }; }