#pragma once #include "EditorAttachment.hpp" #include "RcPtr.hpp" #include "Uid.hpp" #include "Utils.hpp" #include #include #include #include #include // Forward declarations class EditorInstance; class IresManager; class IresWritingContext; class IresLoadingContext; class IresObject : public RefCounted { friend class IresManager; public: enum Kind { KD_Texture, KD_Shader, KD_Material, KD_SpriteFiles, KD_Spritesheet, KD_COUNT, }; private: std::string mName; // Serialized as filename Uid mUid; // Serialized in full mode std::unique_ptr mEditorAttachment; // Transient IresManager* mMan = nullptr; // Transient Kind mKind; // Serialized in full mode public: IresObject(Kind kind); virtual ~IresObject() = default; static std::string_view ToString(Kind kind); static Kind FromString(std::string_view name); static std::unique_ptr Create(Kind kind); Kind GetKind() const { return mKind; } IresManager* GetAssociatedManager() const { return mMan; } bool IsAnnoymous() const; const std::string& GetName() const { return mName; } void SetName(std::string name); const Uid& GetUid() const { return mUid; } static void ShowNameSafe(IresObject* ires); static void ShowNameNull(); void ShowName() const; static void ShowReferenceSafe(EditorInstance& editor, IresObject* ires); static void ShowReferenceNull(EditorInstance& editor); void ShowReference(EditorInstance& editor); virtual void ShowEditor(EditorInstance& editor); EditorAttachment* GetEditorAttachment() const { return mEditorAttachment.get(); } void SetEditorAttachment(EditorAttachment* attachment) { mEditorAttachment.reset(attachment); } static void WriteFull(IresWritingContext& ctx, IresObject* ires, rapidjson::Value& value, rapidjson::Document& root); /// Sequentially call ReadBasic() and then ReadPartial() static std::unique_ptr ReadFull(IresLoadingContext& ctx, const rapidjson::Value& value); /// Reads the type and UID of the object from data, and return a newly constructed Ires object. static std::unique_ptr ReadBasic(const rapidjson::Value& value); /// Reads all object-speific data from the root-level data object into the given Ires object. static bool ReadPartial(IresLoadingContext& ctx, IresObject* ires, const rapidjson::Value& value); virtual void Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjson::Document& root) const; virtual void Read(IresLoadingContext& ctx, const rapidjson::Value& value); protected: rapidjson::Value WriteIresRef(IresObject* object); }; class IresWritingContext { public: virtual ~IresWritingContext() = default; }; class IresLoadingContext { public: virtual ~IresLoadingContext() = default; virtual IresObject* FindIres(const Uid& uid) const = 0; }; class IresManager final : public IresWritingContext, public IresLoadingContext { public: static inline IresManager* instance = nullptr; private: robin_hood::unordered_map> mObjByUid; public: void DiscoverFilesDesignatedLocation(); void DiscoverFiles(const std::filesystem::path& dir); std::pair Add(IresObject* mat); IresObject* Load(const std::filesystem::path& filePath); void Delete(IresObject* ires); bool Rename(IresObject* ires, std::string newName); void Reload(IresObject* ires); void Save(IresObject* ires); void Save(IresObject* ires, const std::filesystem::path& filePath); const auto& GetObjects() const { return mObjByUid; } virtual IresObject* FindIres(const Uid& uid) const override; };