From 19f0c0ea7022748a3e22b89ed6128652c02ce0e3 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sun, 13 Nov 2022 11:43:08 +0800 Subject: [PATCH] Copy/Paste of entities can now be undone Fixed bug where Shift Select would reset in a duplicate entity selection Moved editor window manager to its own file. --- .../AssetBrowser/SHAssetBrowser.cpp | 1 + .../HierarchyPanel/SHHierarchyPanel.cpp | 74 +++++++----------- .../HierarchyPanel/SHHierarchyPanel.h | 30 -------- .../SHHierarchyPanelCommands.cpp | 63 +++++++++++++++ .../HierarchyPanel/SHHierarchyPanelCommands.h | 55 +++++++++++++ .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 2 +- .../EditorWindow/SHEditorWindowManager.cpp | 8 ++ .../EditorWindow/SHEditorWindowManager.h | 77 +++++++++++++++++++ .../src/Editor/Gizmos/SHTransformGizmo.cpp | 2 + SHADE_Engine/src/Editor/SHEditor.cpp | 3 +- SHADE_Engine/src/Editor/SHEditor.h | 66 ---------------- .../src/Serialization/SHSerialization.cpp | 72 ++++++++++++----- .../src/Serialization/SHSerialization.h | 14 +++- 13 files changed, 300 insertions(+), 167 deletions(-) create mode 100644 SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.cpp create mode 100644 SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.h create mode 100644 SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp create mode 100644 SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 37521581..889c24cc 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -13,6 +13,7 @@ #include "Editor/SHEditor.h" #include "Editor/DragDrop/SHDragDrop.hpp" #include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h" +#include "Editor/EditorWindow/SHEditorWindowManager.h" namespace SHADE { diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index ff65ba58..07446115 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -15,6 +15,7 @@ #include "Editor/DragDrop/SHDragDrop.hpp" #include "Tools/SHException.h" #include "Editor/IconsMaterialDesign.h" +#include "SHHierarchyPanelCommands.h" //#==============================================================# //|| Library Includes || @@ -110,9 +111,12 @@ namespace SHADE } if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { - ParentSelectedEntities(MAX_EID, draggingEntities); - draggingEntities.clear(); - ImGui::ClearDragDrop(); + if(ImGui::IsDragDropActive()) + { + ParentSelectedEntities(MAX_EID, draggingEntities); + draggingEntities.clear(); + ImGui::ClearDragDrop(); + } } ImGui::End(); } @@ -282,9 +286,12 @@ namespace SHADE } else editor->selectedEntities.clear(); } - else if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) - editor->selectedEntities.clear(); - editor->selectedEntities.push_back(eid); + else + { + if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + editor->selectedEntities.clear(); + editor->selectedEntities.push_back(eid); + } }//if not selected else { @@ -365,14 +372,16 @@ namespace SHADE if (eid == beginEID || eid == endEID) { startSelecting = true; - editor->selectedEntities.push_back(eid); + if(std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end()) + editor->selectedEntities.push_back(eid); } } else { if (!endSelecting) { - editor->selectedEntities.push_back(eid); + if (std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end()) + editor->selectedEntities.push_back(eid); if (eid == endEID || eid == beginEID) { endSelecting = true; @@ -397,47 +406,20 @@ namespace SHADE void SHHierarchyPanel::CopySelectedEntities() { const auto editor = SHSystemManager::GetSystem(); - SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities)); + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + std::vector entitiesToCopy{}; + std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToCopy), [&sceneGraph](EntityID const& eid) + { + if(sceneGraph.GetParent(eid)->GetEntityID() == MAX_EID) + return true; + return false; + }); + SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy)); } void SHHierarchyPanel::PasteEntities(EntityID parentEID) { - SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID)); - } - - void SHCreateEntityCommand::Execute() - { - EntityID newEID = SHEntityManager::CreateEntity(eid); - if (eid == MAX_EID) - eid = newEID; - } - - void SHCreateEntityCommand::Undo() - { - SHEntityManager::DestroyEntity(eid); - } - - void SHEntityParentCommand::Execute() - { - auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - for (auto const& eid : entities) - { - if (entityParentData[eid].newParentEID == MAX_EID) - sceneGraph.SetParent(eid, nullptr); - else - sceneGraph.SetParent(eid, entityParentData[eid].newParentEID); - } - } - - void SHEntityParentCommand::Undo() - { - auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - for (auto const& eid : entities) - { - if (entityParentData[eid].oldParentEID == MAX_EID) - sceneGraph.SetParent(eid, nullptr); - else - sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID); - } + //SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID).front()); + SHCommandManager::PerformCommand(std::make_shared(SHClipboardUtilities::GetDataFromClipboard(), parentEID)); } }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h index 64f841d6..b667bae7 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h @@ -10,7 +10,6 @@ #include "imgui_internal.h" #include "ECS_Base/SHECSMacros.h" #include "Editor/EditorWindow/SHEditorWindow.h" -#include "Editor/Command/SHCommand.hpp" namespace SHADE { class SHSceneNode; @@ -41,33 +40,4 @@ namespace SHADE };//class SHHierarchyPanel - //Might move to a different file - class SHCreateEntityCommand final : public SHBaseCommand - { - public: - void Execute() override; - void Undo() override; - private: - EntityID eid = MAX_EID; - }; - - class SHEntityParentCommand final : public SHBaseCommand - { - public: - struct Data - { - EntityID oldParentEID = MAX_EID; - EntityID newParentEID = MAX_EID; - }; - using EntityParentData = std::unordered_map; - - SHEntityParentCommand(std::vector entityIDs, EntityParentData inEntityParentData):entities(entityIDs),entityParentData(inEntityParentData){} - - void Execute() override; - void Undo() override; - private: - std::vector entities; - std::unordered_map entityParentData; - }; - }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.cpp new file mode 100644 index 00000000..dfae969e --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.cpp @@ -0,0 +1,63 @@ +#include "SHpch.h" +#include "SHHierarchyPanelCommands.h" +#include "ECS_Base/Managers/SHEntityManager.h" +#include "Scene/SHSceneManager.h" +#include "Serialization/SHSerialization.h" +#include "SHHierarchyPanel.h" +#include "Editor/EditorWindow/SHEditorWindowManager.h" + +namespace SHADE +{ + void SHCreateEntityCommand::Execute() + { + EntityID newEID = SHEntityManager::CreateEntity(eid); + if (eid == MAX_EID) + eid = newEID; + } + + void SHCreateEntityCommand::Undo() + { + SHEntityManager::DestroyEntity(eid); + } + + void SHEntityParentCommand::Execute() + { + auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + for (auto const& eid : entities) + { + if (entityParentData[eid].newParentEID == MAX_EID) + sceneGraph.SetParent(eid, nullptr); + else + sceneGraph.SetParent(eid, entityParentData[eid].newParentEID); + } + } + + void SHEntityParentCommand::Undo() + { + auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + for (auto const& eid : entities) + { + if (entityParentData[eid].oldParentEID == MAX_EID) + sceneGraph.SetParent(eid, nullptr); + else + sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID); + } + } + + void SHPasteEntityCommand::Execute() + { + data.createdEntities.clear(); + data.createdEntities = SHSerialization::DeserializeEntitiesFromString(data.entityData, data.parentEID); + data.entityData = SHSerialization::ResolveSerializedEntityIndices(data.entityData, data.createdEntities); + SHEditorWindowManager::GetEditorWindow()->SetScrollTo(data.createdEntities.begin()->second); + } + + void SHPasteEntityCommand::Undo() + { + for (auto const& [oldEID, newEID] : data.createdEntities) + { + SHEntityManager::DestroyEntity(newEID); + } + } + +} diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.h new file mode 100644 index 00000000..8bad9df2 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanelCommands.h @@ -0,0 +1,55 @@ +#pragma once + +#include + +#include "ECS_Base/SHECSMacros.h" +#include "Editor/Command/SHCommand.hpp" +#include "Serialization/SHSerialization.h" +namespace SHADE +{ + class SHCreateEntityCommand final : public SHBaseCommand + { + public: + void Execute() override; + void Undo() override; + private: + EntityID eid = MAX_EID; + }; + + class SHEntityParentCommand final : public SHBaseCommand + { + public: + struct Data + { + EntityID oldParentEID = MAX_EID; + EntityID newParentEID = MAX_EID; + }; + using EntityParentData = std::unordered_map; + + SHEntityParentCommand(std::vector entityIDs, EntityParentData inEntityParentData) :entities(entityIDs), entityParentData(inEntityParentData) {} + + void Execute() override; + void Undo() override; + private: + std::vector entities{}; + std::unordered_map entityParentData{}; + }; + + class SHPasteEntityCommand final : public SHBaseCommand + { + public: + struct Data + { + SHSerialization::CreatedEntitiesList createdEntities{}; + EntityID parentEID{MAX_EID}; + std::string entityData{}; + }; + SHPasteEntityCommand() = delete; + SHPasteEntityCommand(std::string const& serializedEntityData, EntityID parentEid = MAX_EID):data({{}, parentEid, serializedEntityData}){} + + void Execute() override; + void Undo() override; + private: + Data data; + }; +} diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index ce3ca8b5..223f9b83 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -23,7 +23,7 @@ #include "Scene/SHSceneManager.h" #include "Serialization/SHSerialization.h" #include "Serialization/Configurations/SHConfigurationManager.h" - +#include "Editor/EditorWindow/SHEditorWindowManager.h" const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" }; diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp new file mode 100644 index 00000000..420b5414 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp @@ -0,0 +1,8 @@ +#include "SHpch.h" +#include "SHEditorWindowManager.h" + +namespace SHADE +{ + SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{}; + SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{}; +} diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h new file mode 100644 index 00000000..9e6dd3f4 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include "SHEditorWindow.h" +#include "Tools/SHLog.h" + +namespace SHADE +{ + class SH_API SHEditorWindowManager + { + public: + //#==============================================================# + //|| Type Aliases || + //#==============================================================# + using EditorWindowID = uint8_t; + using EditorWindowPtr = std::unique_ptr; + using EditorWindowMap = std::unordered_map; + /** + * @brief Get ID for the Editor Window Type + * + * @tparam T Type of Editor Window + * @return EditorWindowID ID of Editor Window Type + */ + template , bool> = true> + static EditorWindowID GetEditorWindowID() + { + static EditorWindowID id; + static bool idCreated = false; + if (!idCreated) + { + id = windowCount++; + idCreated = true; + } + return id; + } + + /** + * @brief Create an Editor Window + * + * @tparam T Type of Editor Window to create + */ + template , bool> = true> + static void CreateEditorWindow() + { + static bool isCreated = false; + if (!isCreated) + { + editorWindows[GetEditorWindowID()] = std::make_unique(); + isCreated = true; + } + else + { + SHLog::Warning("Attempt to create duplicate of Editor window type"); + } + } + + /** + * @brief Get pointer to the Editor Window + * + * @tparam T Type of editor window to retrieve + * @return T* Pointer to the editor window + */ + template , bool> = true> + static T* GetEditorWindow() + { + return reinterpret_cast(editorWindows[GetEditorWindowID()].get()); + } + + static EditorWindowMap editorWindows; + private: + // Number of windows; used for Editor Window ID Generation + static EditorWindowID windowCount; + // Map of Editor Windows + friend class SHEditor; + }; +} diff --git a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp index e3bbc809..deea62fc 100644 --- a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp +++ b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp @@ -11,6 +11,8 @@ #include "Camera/SHCameraSystem.h" #include "Editor/Command/SHCommandManager.h" #include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h" +#include "Editor/EditorWindow/SHEditorWindowManager.h" + namespace SHADE { void SHTransformGizmo::Init() diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 90655a62..077c7025 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -29,6 +29,7 @@ //#==============================================================# //|| Editor Window Includes || //#==============================================================# +#include "EditorWindow/SHEditorWindowManager.h" #include "EditorWindow/SHEditorWindowIncludes.h" //#==============================================================# @@ -77,8 +78,6 @@ namespace SHADE //#==============================================================# //Handle SHEditor::imguiCommandPool; //Handle SHEditor::imguiCommandBuffer; - SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{}; - SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{}; //std::vector SHEditor::selectedEntities; //#==============================================================# diff --git a/SHADE_Engine/src/Editor/SHEditor.h b/SHADE_Engine/src/Editor/SHEditor.h index 0de7796a..5897c8b7 100644 --- a/SHADE_Engine/src/Editor/SHEditor.h +++ b/SHADE_Engine/src/Editor/SHEditor.h @@ -36,73 +36,7 @@ namespace SHADE class SHVkCommandBuffer; class SHVkCommandPool; - class SHEditorWindowManager - { - public: - //#==============================================================# - //|| Type Aliases || - //#==============================================================# - using EditorWindowID = uint8_t; - using EditorWindowPtr = std::unique_ptr; - using EditorWindowMap = std::unordered_map; - /** - * @brief Get ID for the Editor Window Type - * - * @tparam T Type of Editor Window - * @return EditorWindowID ID of Editor Window Type - */ - template , bool> = true> - static EditorWindowID GetEditorWindowID() - { - static EditorWindowID id; - static bool idCreated = false; - if (!idCreated) - { - id = windowCount++; - idCreated = true; - } - return id; - } - /** - * @brief Create an Editor Window - * - * @tparam T Type of Editor Window to create - */ - template , bool> = true> - static void CreateEditorWindow() - { - static bool isCreated = false; - if (!isCreated) - { - editorWindows[GetEditorWindowID()] = std::make_unique(); - isCreated = true; - } - else - { - SHLog::Warning("Attempt to create duplicate of Editor window type"); - } - } - - /** - * @brief Get pointer to the Editor Window - * - * @tparam T Type of editor window to retrieve - * @return T* Pointer to the editor window - */ - template , bool> = true> - static T* GetEditorWindow() - { - return reinterpret_cast(editorWindows[GetEditorWindowID()].get()); - } - - static EditorWindowMap editorWindows; - private: - // Number of windows; used for Editor Window ID Generation - static EditorWindowID windowCount; - // Map of Editor Windows - friend class SHEditor; - }; /** * @brief SHEditor static class contains editor variables and implementation of editor functions. diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index f2829b95..d2312627 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -61,20 +61,21 @@ namespace SHADE out << YAML::EndSeq; } - static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector& createdEntities, EntityID parentEID = MAX_EID) + static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, SHSerialization::CreatedEntitiesList& createdEntities, EntityID parentEID = MAX_EID) { - EntityID eid = MAX_EID; + EntityID eid{MAX_EID}, oldEID{MAX_EID}; if (!node) return eid; if (node[EIDNode]) - eid = node[EIDNode].as(); - std::string name = "Default"; + oldEID = eid = node[EIDNode].as(); + std::string name = "UnnamedEntitiy"; if (node[EntityNameNode]) name = node[EntityNameNode].as(); //Compile component IDs const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]); eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID); - createdEntities.push_back(eid); + createdEntities[oldEID] = eid; + //createdEntities.push_back(eid); if (node[NumberOfChildrenNode]) { if (const int numOfChildren = node[NumberOfChildrenNode].as(); numOfChildren > 0) @@ -106,7 +107,7 @@ namespace SHADE return NewSceneName.data(); } YAML::Node entities = YAML::Load(assetData->data); - std::vector createdEntities{}; + CreatedEntitiesList createdEntities{}; //Create Entities for (auto it = entities.begin(); it != entities.end(); ++it) @@ -122,14 +123,14 @@ namespace SHADE AssetQueue assetQueue; for (auto it = entities.begin(); it != entities.end(); ++it) { - SHSerializationHelper::FetchAssetsFromComponent((*it)[ComponentsNode], *entityVecIt, assetQueue); + SHSerializationHelper::FetchAssetsFromComponent((*it)[ComponentsNode], createdEntities[(*it)[EIDNode].as()], assetQueue); } LoadAssetsFromAssetQueue(assetQueue); //Initialize Entity entityVecIt = createdEntities.begin(); for (auto it = entities.begin(); it != entities.end(); ++it) { - InitializeEntity(*it, *entityVecIt++); + InitializeEntity(*it, createdEntities[(*it)[EIDNode].as()]); } return assetData->name; @@ -160,9 +161,9 @@ namespace SHADE return std::string(out.c_str()); } - void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path) - { - } + //void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path) + //{ + //} template, bool> = true> static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid) @@ -218,13 +219,13 @@ namespace SHADE return node; } - EntityID SHSerialization::DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID) noexcept + SHSerialization::CreatedEntitiesList SHSerialization::DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID) noexcept { if (data.empty()) - return MAX_EID; + return {}; YAML::Node entities = YAML::Load(data.c_str()); EntityID eid{ MAX_EID }; - std::vector createdEntities; + CreatedEntitiesList createdEntities{}; for (auto it = entities.begin(); it != entities.end(); ++it) { eid = DeserializeEntity(it, *it, createdEntities, parentEID); @@ -232,14 +233,14 @@ namespace SHADE if (createdEntities.empty()) { SHLOG_ERROR("Failed to create entities from deserializaiton") - return MAX_EID; + return createdEntities; } - auto entityVecIt = createdEntities.begin(); + //auto entityVecIt = createdEntities.begin(); for (auto it = entities.begin(); it != entities.end(); ++it) { - InitializeEntity(*it, *entityVecIt++); + InitializeEntity(*it, createdEntities[(*it)[EIDNode].as()]); } - return eid; + return createdEntities; } template, bool> = true> @@ -290,6 +291,41 @@ namespace SHADE SHResourceManager::FinaliseChanges(); } + void ResolveSerializedEntityID(YAML::Emitter& out, YAML::iterator& it, YAML::Node const& entityNode, SHSerialization::CreatedEntitiesList const& createdEntities) + { + EntityID eid = entityNode[EIDNode].as(); + YAML::Node resolvedNode = entityNode; + resolvedNode[EIDNode] = createdEntities.at(eid); + out << resolvedNode; + if (entityNode[NumberOfChildrenNode]) + { + if (const int numOfChildren = entityNode[NumberOfChildrenNode].as(); numOfChildren > 0) + { + ++it; + for (int i = 0; i < numOfChildren; ++i) + { + ResolveSerializedEntityID(out, it, (*it), createdEntities); + //DeserializeEntity(it, (*it), createdEntities, eid); + if ((i + 1) < numOfChildren) + ++it; + } + } + } + } + + std::string SHSerialization::ResolveSerializedEntityIndices(std::string serializedEntityData, CreatedEntitiesList const& createdEntities) noexcept + { + YAML::Node entities = YAML::Load(serializedEntityData); + YAML::Emitter out; + out << YAML::BeginSeq; + for (auto it = entities.begin(); it != entities.end(); ++it) + { + ResolveSerializedEntityID(out, it, (*it), createdEntities); + } + out << YAML::EndSeq; + return out.c_str(); + } + void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid) { auto const componentsNode = entityNode[ComponentsNode]; diff --git a/SHADE_Engine/src/Serialization/SHSerialization.h b/SHADE_Engine/src/Serialization/SHSerialization.h index 3cb268f2..dd487662 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.h +++ b/SHADE_Engine/src/Serialization/SHSerialization.h @@ -2,7 +2,6 @@ #include "SH_API.h" #include -#include #include "ECS_Base/SHECSMacros.h" @@ -26,8 +25,12 @@ namespace SHADE constexpr const char* NumberOfChildrenNode = "NumberOfChildren"; constexpr const char* ScriptsNode = "Scripts"; - struct SH_API SHSerialization + class SH_API SHSerialization { + public: + //Original EID : New EID + using CreatedEntitiesList = std::unordered_map; + static bool SerializeSceneToFile(AssetID const& sceneAssetID); static std::string SerializeSceneToString(); static void SerializeSceneToEmitter(YAML::Emitter& out); @@ -38,15 +41,18 @@ namespace SHADE static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out); static std::string SerializeEntitiesToString(std::vector const& entities) noexcept; - static void SerializeEntityToFile(std::filesystem::path const& path); + //static void SerializeEntityToFile(std::filesystem::path const& path); static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode); - static EntityID DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept; + static CreatedEntitiesList DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept; static std::vector GetComponentIDList(YAML::Node const& componentsNode); static void LoadAssetsFromAssetQueue(std::unordered_map& assetQueue); + + static std::string ResolveSerializedEntityIndices(std::string serializedEntityData, CreatedEntitiesList const& createdEntities) noexcept; private: + //static void ResolveSerializedEntityID(YAML::Emitter& out, YAML::iterator& it, YAML::Node const& entityNode, CreatedEntitiesList const& createdEntities); static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid); static constexpr std::string_view NewSceneName = "New Scene";