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.
This commit is contained in:
parent
e2bcb0bbbb
commit
19f0c0ea70
|
@ -13,6 +13,7 @@
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
|
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
#include "Tools/SHException.h"
|
#include "Tools/SHException.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "SHHierarchyPanelCommands.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -109,11 +110,14 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
if(ImGui::IsDragDropActive())
|
||||||
{
|
{
|
||||||
ParentSelectedEntities(MAX_EID, draggingEntities);
|
ParentSelectedEntities(MAX_EID, draggingEntities);
|
||||||
draggingEntities.clear();
|
draggingEntities.clear();
|
||||||
ImGui::ClearDragDrop();
|
ImGui::ClearDragDrop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,9 +286,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else editor->selectedEntities.clear();
|
else editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
else if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
else
|
||||||
|
{
|
||||||
|
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
|
}
|
||||||
}//if not selected
|
}//if not selected
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -365,6 +372,7 @@ namespace SHADE
|
||||||
if (eid == beginEID || eid == endEID)
|
if (eid == beginEID || eid == endEID)
|
||||||
{
|
{
|
||||||
startSelecting = true;
|
startSelecting = true;
|
||||||
|
if(std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end())
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,6 +380,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (!endSelecting)
|
if (!endSelecting)
|
||||||
{
|
{
|
||||||
|
if (std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end())
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
if (eid == endEID || eid == beginEID)
|
if (eid == endEID || eid == beginEID)
|
||||||
{
|
{
|
||||||
|
@ -397,47 +406,20 @@ namespace SHADE
|
||||||
void SHHierarchyPanel::CopySelectedEntities()
|
void SHHierarchyPanel::CopySelectedEntities()
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities));
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
std::vector<EntityID> 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)
|
void SHHierarchyPanel::PasteEntities(EntityID parentEID)
|
||||||
{
|
{
|
||||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID));
|
//SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID).front());
|
||||||
}
|
SHCommandManager::PerformCommand(std::make_shared<SHPasteEntityCommand>(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
#include "Editor/Command/SHCommand.hpp"
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHSceneNode;
|
class SHSceneNode;
|
||||||
|
@ -41,33 +40,4 @@ namespace SHADE
|
||||||
|
|
||||||
};//class SHHierarchyPanel
|
};//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<EntityID, Data>;
|
|
||||||
|
|
||||||
SHEntityParentCommand(std::vector<EntityID> entityIDs, EntityParentData inEntityParentData):entities(entityIDs),entityParentData(inEntityParentData){}
|
|
||||||
|
|
||||||
void Execute() override;
|
|
||||||
void Undo() override;
|
|
||||||
private:
|
|
||||||
std::vector<EntityID> entities;
|
|
||||||
std::unordered_map<EntityID, Data> entityParentData;
|
|
||||||
};
|
|
||||||
|
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -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<SHHierarchyPanel>()->SetScrollTo(data.createdEntities.begin()->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPasteEntityCommand::Undo()
|
||||||
|
{
|
||||||
|
for (auto const& [oldEID, newEID] : data.createdEntities)
|
||||||
|
{
|
||||||
|
SHEntityManager::DestroyEntity(newEID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#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<EntityID, Data>;
|
||||||
|
|
||||||
|
SHEntityParentCommand(std::vector<EntityID> entityIDs, EntityParentData inEntityParentData) :entities(entityIDs), entityParentData(inEntityParentData) {}
|
||||||
|
|
||||||
|
void Execute() override;
|
||||||
|
void Undo() override;
|
||||||
|
private:
|
||||||
|
std::vector<EntityID> entities{};
|
||||||
|
std::unordered_map<EntityID, Data> 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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -23,7 +23,7 @@
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
#include "Serialization/Configurations/SHConfigurationManager.h"
|
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
||||||
|
|
||||||
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHEditorWindowManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
|
||||||
|
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
#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<SHEditorWindow>;
|
||||||
|
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
||||||
|
/**
|
||||||
|
* @brief Get ID for the Editor Window Type
|
||||||
|
*
|
||||||
|
* @tparam T Type of Editor Window
|
||||||
|
* @return EditorWindowID ID of Editor Window Type
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, 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 <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static void CreateEditorWindow()
|
||||||
|
{
|
||||||
|
static bool isCreated = false;
|
||||||
|
if (!isCreated)
|
||||||
|
{
|
||||||
|
editorWindows[GetEditorWindowID<T>()] = std::make_unique<T>();
|
||||||
|
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 <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static T* GetEditorWindow()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
||||||
|
}
|
||||||
|
|
||||||
|
static EditorWindowMap editorWindows;
|
||||||
|
private:
|
||||||
|
// Number of windows; used for Editor Window ID Generation
|
||||||
|
static EditorWindowID windowCount;
|
||||||
|
// Map of Editor Windows
|
||||||
|
friend class SHEditor;
|
||||||
|
};
|
||||||
|
}
|
|
@ -11,6 +11,8 @@
|
||||||
#include "Camera/SHCameraSystem.h"
|
#include "Camera/SHCameraSystem.h"
|
||||||
#include "Editor/Command/SHCommandManager.h"
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
|
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
void SHTransformGizmo::Init()
|
void SHTransformGizmo::Init()
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Editor Window Includes ||
|
//|| Editor Window Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
#include "EditorWindow/SHEditorWindowManager.h"
|
||||||
#include "EditorWindow/SHEditorWindowIncludes.h"
|
#include "EditorWindow/SHEditorWindowIncludes.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -77,8 +78,6 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
//Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
||||||
//Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
//Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
||||||
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
|
|
||||||
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
|
|
||||||
//std::vector<EntityID> SHEditor::selectedEntities;
|
//std::vector<EntityID> SHEditor::selectedEntities;
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
|
|
@ -36,73 +36,7 @@ namespace SHADE
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkCommandPool;
|
class SHVkCommandPool;
|
||||||
|
|
||||||
class SHEditorWindowManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//#==============================================================#
|
|
||||||
//|| Type Aliases ||
|
|
||||||
//#==============================================================#
|
|
||||||
using EditorWindowID = uint8_t;
|
|
||||||
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
|
||||||
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
|
||||||
/**
|
|
||||||
* @brief Get ID for the Editor Window Type
|
|
||||||
*
|
|
||||||
* @tparam T Type of Editor Window
|
|
||||||
* @return EditorWindowID ID of Editor Window Type
|
|
||||||
*/
|
|
||||||
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, 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 <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
|
||||||
static void CreateEditorWindow()
|
|
||||||
{
|
|
||||||
static bool isCreated = false;
|
|
||||||
if (!isCreated)
|
|
||||||
{
|
|
||||||
editorWindows[GetEditorWindowID<T>()] = std::make_unique<T>();
|
|
||||||
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 <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
|
||||||
static T* GetEditorWindow()
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].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.
|
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
||||||
|
|
|
@ -61,20 +61,21 @@ namespace SHADE
|
||||||
out << YAML::EndSeq;
|
out << YAML::EndSeq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& 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)
|
if (!node)
|
||||||
return eid;
|
return eid;
|
||||||
if (node[EIDNode])
|
if (node[EIDNode])
|
||||||
eid = node[EIDNode].as<EntityID>();
|
oldEID = eid = node[EIDNode].as<EntityID>();
|
||||||
std::string name = "Default";
|
std::string name = "UnnamedEntitiy";
|
||||||
if (node[EntityNameNode])
|
if (node[EntityNameNode])
|
||||||
name = node[EntityNameNode].as<std::string>();
|
name = node[EntityNameNode].as<std::string>();
|
||||||
//Compile component IDs
|
//Compile component IDs
|
||||||
const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]);
|
const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]);
|
||||||
eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID);
|
eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID);
|
||||||
createdEntities.push_back(eid);
|
createdEntities[oldEID] = eid;
|
||||||
|
//createdEntities.push_back(eid);
|
||||||
if (node[NumberOfChildrenNode])
|
if (node[NumberOfChildrenNode])
|
||||||
{
|
{
|
||||||
if (const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
|
if (const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
|
||||||
|
@ -106,7 +107,7 @@ namespace SHADE
|
||||||
return NewSceneName.data();
|
return NewSceneName.data();
|
||||||
}
|
}
|
||||||
YAML::Node entities = YAML::Load(assetData->data);
|
YAML::Node entities = YAML::Load(assetData->data);
|
||||||
std::vector<EntityID> createdEntities{};
|
CreatedEntitiesList createdEntities{};
|
||||||
|
|
||||||
//Create Entities
|
//Create Entities
|
||||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
@ -122,14 +123,14 @@ namespace SHADE
|
||||||
AssetQueue assetQueue;
|
AssetQueue assetQueue;
|
||||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
{
|
{
|
||||||
SHSerializationHelper::FetchAssetsFromComponent<SHRenderable>((*it)[ComponentsNode], *entityVecIt, assetQueue);
|
SHSerializationHelper::FetchAssetsFromComponent<SHRenderable>((*it)[ComponentsNode], createdEntities[(*it)[EIDNode].as<EntityID>()], assetQueue);
|
||||||
}
|
}
|
||||||
LoadAssetsFromAssetQueue(assetQueue);
|
LoadAssetsFromAssetQueue(assetQueue);
|
||||||
//Initialize Entity
|
//Initialize Entity
|
||||||
entityVecIt = createdEntities.begin();
|
entityVecIt = createdEntities.begin();
|
||||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
{
|
{
|
||||||
InitializeEntity(*it, *entityVecIt++);
|
InitializeEntity(*it, createdEntities[(*it)[EIDNode].as<EntityID>()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return assetData->name;
|
return assetData->name;
|
||||||
|
@ -160,9 +161,9 @@ namespace SHADE
|
||||||
return std::string(out.c_str());
|
return std::string(out.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
|
//void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
|
||||||
{
|
//{
|
||||||
}
|
//}
|
||||||
|
|
||||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
||||||
|
@ -218,13 +219,13 @@ namespace SHADE
|
||||||
return node;
|
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())
|
if (data.empty())
|
||||||
return MAX_EID;
|
return {};
|
||||||
YAML::Node entities = YAML::Load(data.c_str());
|
YAML::Node entities = YAML::Load(data.c_str());
|
||||||
EntityID eid{ MAX_EID };
|
EntityID eid{ MAX_EID };
|
||||||
std::vector<EntityID> createdEntities;
|
CreatedEntitiesList createdEntities{};
|
||||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
{
|
{
|
||||||
eid = DeserializeEntity(it, *it, createdEntities, parentEID);
|
eid = DeserializeEntity(it, *it, createdEntities, parentEID);
|
||||||
|
@ -232,14 +233,14 @@ namespace SHADE
|
||||||
if (createdEntities.empty())
|
if (createdEntities.empty())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
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)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
{
|
{
|
||||||
InitializeEntity(*it, *entityVecIt++);
|
InitializeEntity(*it, createdEntities[(*it)[EIDNode].as<EntityID>()]);
|
||||||
}
|
}
|
||||||
return eid;
|
return createdEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
@ -290,6 +291,41 @@ namespace SHADE
|
||||||
SHResourceManager::FinaliseChanges();
|
SHResourceManager::FinaliseChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResolveSerializedEntityID(YAML::Emitter& out, YAML::iterator& it, YAML::Node const& entityNode, SHSerialization::CreatedEntitiesList const& createdEntities)
|
||||||
|
{
|
||||||
|
EntityID eid = entityNode[EIDNode].as<EntityID>();
|
||||||
|
YAML::Node resolvedNode = entityNode;
|
||||||
|
resolvedNode[EIDNode] = createdEntities.at(eid);
|
||||||
|
out << resolvedNode;
|
||||||
|
if (entityNode[NumberOfChildrenNode])
|
||||||
|
{
|
||||||
|
if (const int numOfChildren = entityNode[NumberOfChildrenNode].as<int>(); 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)
|
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
||||||
{
|
{
|
||||||
auto const componentsNode = entityNode[ComponentsNode];
|
auto const componentsNode = entityNode[ComponentsNode];
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
|
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
@ -26,8 +25,12 @@ namespace SHADE
|
||||||
constexpr const char* NumberOfChildrenNode = "NumberOfChildren";
|
constexpr const char* NumberOfChildrenNode = "NumberOfChildren";
|
||||||
constexpr const char* ScriptsNode = "Scripts";
|
constexpr const char* ScriptsNode = "Scripts";
|
||||||
|
|
||||||
struct SH_API SHSerialization
|
class SH_API SHSerialization
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
//Original EID : New EID
|
||||||
|
using CreatedEntitiesList = std::unordered_map<EntityID, EntityID>;
|
||||||
|
|
||||||
static bool SerializeSceneToFile(AssetID const& sceneAssetID);
|
static bool SerializeSceneToFile(AssetID const& sceneAssetID);
|
||||||
static std::string SerializeSceneToString();
|
static std::string SerializeSceneToString();
|
||||||
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
||||||
|
@ -38,15 +41,18 @@ namespace SHADE
|
||||||
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
||||||
|
|
||||||
static std::string SerializeEntitiesToString(std::vector<EntityID> const& entities) noexcept;
|
static std::string SerializeEntitiesToString(std::vector<EntityID> 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 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<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||||
|
|
||||||
static void LoadAssetsFromAssetQueue(std::unordered_map<AssetID, AssetType>& assetQueue);
|
static void LoadAssetsFromAssetQueue(std::unordered_map<AssetID, AssetType>& assetQueue);
|
||||||
|
|
||||||
|
static std::string ResolveSerializedEntityIndices(std::string serializedEntityData, CreatedEntitiesList const& createdEntities) noexcept;
|
||||||
private:
|
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 void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||||
|
|
||||||
static constexpr std::string_view NewSceneName = "New Scene";
|
static constexpr std::string_view NewSceneName = "New Scene";
|
||||||
|
|
Loading…
Reference in New Issue