From 211e667351a641c8cf2f60197f311acd70b2a434 Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sat, 1 Feb 2025 14:18:53 +0100 Subject: [PATCH] fix: objects being parented to themselves/descendents of themselves --- src/objects/base/instance.cpp | 15 ++++++++++++++- src/objects/base/instance.h | 4 +++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/objects/base/instance.cpp b/src/objects/base/instance.cpp index 3889262..d17be0f 100644 --- a/src/objects/base/instance.cpp +++ b/src/objects/base/instance.cpp @@ -38,7 +38,19 @@ Instance::Instance(InstanceType* type) { Instance::~Instance () { } -void Instance::SetParent(std::optional> newParent) { +// TODO: Test this +bool Instance::ancestryContinuityCheck(std::optional> newParent) { + for (std::optional> currentParent = newParent; currentParent.has_value(); currentParent = currentParent.value()->GetParent()) { + if (currentParent.value() == this->shared_from_this()) + return false; + } + return true; +} + +bool Instance::SetParent(std::optional> newParent) { + if (!ancestryContinuityCheck(newParent)) + return false; + auto lastParent = GetParent(); if (hierarchyPreUpdateHandler.has_value()) hierarchyPreUpdateHandler.value()(this->shared_from_this(), lastParent, newParent); // If we currently have a parent, remove ourselves from it before adding ourselves to the new one @@ -56,6 +68,7 @@ void Instance::SetParent(std::optional> newParent) { if (hierarchyPostUpdateHandler.has_value()) hierarchyPostUpdateHandler.value()(this->shared_from_this(), lastParent, newParent); this->OnParentUpdated(lastParent, newParent); + return true; } std::optional> Instance::GetParent() { diff --git a/src/objects/base/instance.h b/src/objects/base/instance.h index d39b146..e85aded 100644 --- a/src/objects/base/instance.h +++ b/src/objects/base/instance.h @@ -35,6 +35,8 @@ private: std::vector> children; std::optional> cachedMemberList; + + bool ancestryContinuityCheck(std::optional> newParent); protected: std::unique_ptr memberMap; @@ -48,7 +50,7 @@ public: // Instance is abstract, so it should not implement GetClass directly virtual InstanceType* GetClass() = 0; - void SetParent(std::optional> newParent); + bool SetParent(std::optional> newParent); std::optional> GetParent(); inline const std::vector> GetChildren() { return children; }