#pragma once #include #include #include #include #include #include #include #include #include #include #include <../include/expected.hpp> #include "member.h" class Instance; typedef std::shared_ptr(*InstanceConstructor)(); // Struct describing information about an instance struct InstanceType { const InstanceType* super; // May be null std::string className; InstanceConstructor constructor; std::string explorerIcon = ""; }; // Base class for all instances in the data model // Note: enable_shared_from_this HAS to be public or else its field will not be populated // Maybe this could be replaced with a friendship? But that seems unnecessary. // https://stackoverflow.com/q/56415222/16255372 class Instance : public std::enable_shared_from_this { private: std::optional> parent; std::vector> children; std::optional> cachedMemberList; bool ancestryContinuityCheck(std::optional> newParent); protected: bool parentLocked; std::unique_ptr memberMap; Instance(const InstanceType*); virtual ~Instance(); virtual void OnParentUpdated(std::optional> oldParent, std::optional> newParent); public: const static InstanceType TYPE; std::string name; // Instance is abstract, so it should not implement GetClass directly virtual const InstanceType* GetClass() = 0; bool SetParent(std::optional> newParent); std::optional> GetParent(); inline const std::vector> GetChildren() { return children; } // Utility functions inline void AddChild(std::shared_ptr object) { object->SetParent(this->shared_from_this()); } // Properties // Do I like using expected? tl::expected GetPropertyValue(std::string name); tl::expected SetPropertyValue(std::string name, Data::Variant value); tl::expected GetPropertyMeta(std::string name); // Returning a list of property names feels kinda janky. Is this really the way to go? std::vector GetProperties(); }; typedef std::shared_ptr InstanceRef; typedef std::weak_ptr InstanceRefWeak;