From ca22b4438f88daab4f6f221004a3449bbc785d1e Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sun, 12 Jan 2025 17:18:03 +0100 Subject: [PATCH] infra: Base Instance classes --- src/objects/base.h | 4 ++++ src/objects/base/instance.cpp | 37 +++++++++++++++++++++++++++++++++++ src/objects/base/instance.h | 30 ++++++++++++++++++++++++++++ src/objects/base/metadata.h | 3 ++- 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/objects/base.h create mode 100644 src/objects/base/instance.cpp create mode 100644 src/objects/base/instance.h diff --git a/src/objects/base.h b/src/objects/base.h new file mode 100644 index 0000000..8e9856d --- /dev/null +++ b/src/objects/base.h @@ -0,0 +1,4 @@ +#pragma once + +#include "base/metadata.h" +#include "base/instance.h" \ No newline at end of file diff --git a/src/objects/base/instance.cpp b/src/objects/base/instance.cpp new file mode 100644 index 0000000..28a2aa6 --- /dev/null +++ b/src/objects/base/instance.cpp @@ -0,0 +1,37 @@ +#include "instance.h" +#include +#include +#include + +// Static so that this variable name is "local" to this source file +static InstanceType TYPE_ { + .super = NULL, + .className = "Instance", + .constructor = NULL, // Instance is abstract and therefore not creatable +}; + +InstanceType* Instance::TYPE = &TYPE_; + +InstanceType* GetClass() { + return &TYPE_; +} + +void Instance::SetParent(std::optional> newParent) { + // If we currently have a parent, remove ourselves from it before adding ourselves to the new one + if (this->parent.has_value() && !this->parent.value().expired()) { + auto oldParent = this->parent.value().lock(); + oldParent->children.erase(std::find(oldParent->children.begin(), oldParent->children.end(), this->shared_from_this())); + } + // Add ourselves to the new parent + if (newParent.has_value()) { + newParent.value()->children.push_back(this->shared_from_this()); + } + this->parent = newParent; + // TODO: Add code for sending signals for parent updates +} + +std::optional> Instance::GetParent() { + if (!parent.has_value()) return std::nullopt; + if (parent.value().expired()) return std::nullopt; + return parent.value().lock(); +} \ No newline at end of file diff --git a/src/objects/base/instance.h b/src/objects/base/instance.h new file mode 100644 index 0000000..614951e --- /dev/null +++ b/src/objects/base/instance.h @@ -0,0 +1,30 @@ +#pragma once + +#include "metadata.h" +#include +#include + +// Struct describing information about an instance +struct InstanceType { + InstanceType* super; // May be null + std::string className; + InstanceConstructor constructor; +}; + +// Base class for all instances in the data model +class Instance : std::enable_shared_from_this { +private: + std::optional> parent; + std::vector> children; +public: + static InstanceType* TYPE; + std::string name; + + InstanceType* GetClass(); + void SetParent(std::optional> newParent); + std::optional> GetParent(); + inline const std::vector> GetChildren() { return children; } +}; + +typedef std::shared_ptr InstanceRef; +typedef std::weak_ptr InstanceRefWeak; \ No newline at end of file diff --git a/src/objects/base/metadata.h b/src/objects/base/metadata.h index 3bff353..83b2416 100644 --- a/src/objects/base/metadata.h +++ b/src/objects/base/metadata.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -9,7 +10,7 @@ #include "../../datatype.h" class Instance; -typedef Instance(*InstanceConstructor)(); +typedef std::shared_ptr(*InstanceConstructor)(); const uint INST_NOT_CREATABLE = 1; // const uint INST_SINGLETON = 2;