Added Copy/Paste of component values, scene name display, editor config #300

Merged
srishamharan merged 5 commits from SP3-4-Editor into main 2023-01-04 01:01:35 +08:00
9 changed files with 197 additions and 68 deletions
Showing only changes of commit 16d34c6478 - Show all commits

4
.gitignore vendored
View File

@ -364,3 +364,7 @@ MigrationBackup/
*.filters
Assets/Editor/Layouts/UserLayout.ini
JSON/Schemas/Catalog/
Assets/Editor/Editor.SHConfig

View File

@ -18,11 +18,17 @@ namespace SHADE
SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack);
SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack);
bool SHCommandManager::failedExecution(false);
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
{
*pCurrRedoStack = CommandStack(defaultStackSize);
commandPtr->Execute();
if(failedExecution)
{
failedExecution = false;
return;
}
*pCurrRedoStack = CommandStack(defaultStackSize);
if (overrideValue && !pCurrUndoStack->Empty())
{
pCurrUndoStack->Top()->Merge(commandPtr);
@ -68,12 +74,14 @@ namespace SHADE
void SHCommandManager::PopLatestCommandFromRedoStack()
{
pCurrRedoStack->Pop();
if(!pCurrRedoStack->Empty())
pCurrRedoStack->Pop();
}
void SHCommandManager::PopLatestCommandFromUndoStack()
{
pCurrUndoStack->Pop();
if(!pCurrUndoStack->Empty())
pCurrUndoStack->Pop();
}
void SHCommandManager::SwapStacks()

View File

@ -38,7 +38,8 @@ namespace SHADE
static void SwapStacks();
static void ClearAll();
static bool failedExecution;
static constexpr CommandStack::SizeType defaultStackSize = 100;
private:
static CommandStackPtr pCurrUndoStack;

View File

@ -19,6 +19,9 @@
#include "Reflection/SHReflectionMetadata.h"
#include "Resource/SHResourceManager.h"
#include "Physics/Collision/SHCollisionTagMatrix.h"
#include "Serialization/SHSerializationHelper.hpp"
#include "Tools/Utilities/SHClipboardUtilities.h"
#include "SHInspectorCommands.h"
namespace SHADE
{
template<typename T>
@ -46,11 +49,12 @@ namespace SHADE
if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data()))
{
//SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component));
SHClipboardUtilities::WriteToClipboard(SHSerializationHelper::SerializeComponentToString<T>(component->GetEID()));
}
if (ImGui::Selectable(std::format("{} Paste {}", ICON_MD_CONTENT_PASTE, componentName.data()).data()))
{
//SHStringToComponent(component, SHClipboardUtil::ReadStringFromClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT));
//SHSerializationHelper::DeserializeComponentFromString<T>(SHClipboardUtilities::GetDataFromClipboard(), component->GetEID());
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>( std::make_shared<SHPasteComponentCommand<T>>(component->GetEID(), SHClipboardUtilities::GetDataFromClipboard())));
}
if (ImGui::Selectable(std::format("{} Delete {}", ICON_MD_DELETE, componentName.data()).data()))
{

View File

@ -0,0 +1,27 @@
#pragma once
#include "Editor/Command/SHCommand.hpp"
namespace SHADE
{
template<typename T>
class SHPasteComponentCommand final : SHBaseCommand
{
public:
struct Data
{
EntityID eid;
std::string oldComponentData;
std::string newComponentData;
};
SHPasteComponentCommand(EntityID eid, std::string const& newComponentData);
void Execute() override;
void Undo() override;
private:
Data data;
};
}
#include "SHInspectorCommands.hpp"

View File

@ -0,0 +1,26 @@
#pragma once
#include "SHInspectorCommands.h"
namespace SHADE
{
template<typename T>
SHPasteComponentCommand<T>::SHPasteComponentCommand(EntityID eid, std::string const& newComponentData)
:data(eid, {}, newComponentData)
{
data.oldComponentData = SHSerializationHelper::SerializeComponentToString<T>(eid);
}
template<typename T>
void SHPasteComponentCommand<T>::Execute()
{
bool result = SHSerializationHelper::DeserializeComponentFromString<T>(data.newComponentData, data.eid);
if(!result)
SHCommandManager::failedExecution = true;
}
template<typename T>
void SHPasteComponentCommand<T>::Undo()
{
SHSerializationHelper::DeserializeComponentFromString<T>(data.oldComponentData, data.eid);
}
}

View File

@ -169,25 +169,15 @@ namespace SHADE
//}
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)
{
if (const ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
{
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(component);
}
}
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void AddConvComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
{
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
{
auto componentNode = YAML::convert<ComponentType>::encode(*component);
componentNode[IsActive.data()] = component->isActive;
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = componentNode;
}
}
static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
{
YAML::Node node{};
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
{
node = SHSerializationHelper::SerializeComponentToNode(component);
}
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = node;
}
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
{
@ -211,15 +201,15 @@ namespace SHADE
AddComponentToComponentNode<SHTransformComponent>(components, eid);
AddComponentToComponentNode<SHCameraComponent>(components, eid);
AddComponentToComponentNode<SHCameraArmComponent>(components, eid);
AddConvComponentToComponentNode<SHRenderable>(components, eid);
AddComponentToComponentNode<SHRenderable>(components, eid);
AddComponentToComponentNode<SHLightComponent>(components, eid);
AddComponentToComponentNode<SHRigidBodyComponent>(components, eid);
AddConvComponentToComponentNode<SHColliderComponent>(components, eid);
AddComponentToComponentNode<SHColliderComponent>(components, eid);
AddComponentToComponentNode<SHCanvasComponent>(components, eid);
AddComponentToComponentNode<SHButtonComponent>(components, eid);
AddConvComponentToComponentNode<SHTextRenderableComponent>(components, eid);
AddComponentToComponentNode<SHTextRenderableComponent>(components, eid);
node[ComponentsNode] = components;
@ -351,12 +341,12 @@ namespace SHADE
SHSerializationHelper::InitializeComponentFromNode<SHCameraComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHCameraArmComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHColliderComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHRenderable>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHColliderComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHCanvasComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHButtonComponent>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHTextRenderableComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHTextRenderableComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
}
}

View File

@ -103,12 +103,6 @@ namespace SHADE
return node;
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static std::string SerializeComponentToString(ComponentType* component)
{
return std::string();
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
{
@ -117,14 +111,29 @@ namespace SHADE
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static YAML::Node SerializeComponentToNode(ComponentType* component)
{
YAML::Node node{};
if (!component)
return node;
auto componentType = rttr::type::get<ComponentType>();
node = RTTRToNode(*component);
node[IsActive.data()] = component->isActive;
if constexpr (YAML::HasYAMLConv<ComponentType>())
{
if (component)
{
auto componentNode = YAML::convert<ComponentType>::encode(*component);
componentNode[IsActive.data()] = component->isActive;
return componentNode;
}
}
else
{
if (component)
{
YAML::Node compNode{};
if (!component)
return compNode;
auto componentType = rttr::type::get<ComponentType>();
compNode = RTTRToNode(*component);
compNode[IsActive.data()] = component->isActive;
return compNode;
return node;
}
}
}
template <typename Type>
@ -191,26 +200,43 @@ namespace SHADE
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
static bool InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
{
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
if (componentsNode.IsNull() && !component)
return;
auto rttrType = rttr::type::get<ComponentType>();
auto componentNode = componentsNode[rttrType.get_name().data()];
if (!componentNode.IsDefined())
return;
if(componentNode[IsActive.data()].IsDefined())
component->isActive = componentNode[IsActive.data()].as<bool>();
auto properties = rttrType.get_properties();
for (auto const& prop : properties)
if constexpr (YAML::HasYAMLConv<ComponentType>())
{
if (componentNode[prop.get_name().data()].IsDefined())
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
if (componentsNode.IsNull() || !component)
return false;
auto componentNode = GetComponentNode<ComponentType>(componentsNode, eid);
if (componentNode.IsNull() || !componentNode.IsDefined())
return false;
if (componentNode[IsActive.data()].IsDefined())
component->isActive = componentNode[IsActive.data()].as<bool>();
YAML::convert<ComponentType>::decode(componentNode, *component);
return true;
}
else
{
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
if (componentsNode.IsNull() && !component)
return false;
auto rttrType = rttr::type::get<ComponentType>();
auto componentNode = componentsNode[rttrType.get_name().data()];
if (!componentNode.IsDefined())
return false;
if (componentNode[IsActive.data()].IsDefined())
component->isActive = componentNode[IsActive.data()].as<bool>();
auto properties = rttrType.get_properties();
for (auto const& prop : properties)
{
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
if (componentNode[prop.get_name().data()].IsDefined())
{
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
}
}
}
return true;
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
@ -226,16 +252,49 @@ namespace SHADE
return componentNode;
}
//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)
//{
// if constexpr (YAML::HasYAMLConv<ComponentType>())
// {
// if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
// {
// auto componentNode = YAML::convert<ComponentType>::encode(*component);
// componentNode[IsActive.data()] = component->isActive;
// componentsNode[rttr::type::get<ComponentType>().get_name().data()] = componentNode;
// }
// }
// else
// {
// if (const ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
// {
// componentsNode[rttr::type::get<ComponentType>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(component);
// }
// }
//}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void ConvertNodeToComponent(YAML::Node const& componentsNode, EntityID const& eid)
static std::string SerializeComponentToString(EntityID const& eid)
{
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
if (componentsNode.IsNull() && !component)
return;
auto componentNode = GetComponentNode<ComponentType>(componentsNode, eid);
if (componentNode[IsActive.data()].IsDefined())
component->isActive = componentNode[IsActive.data()].as<bool>();
YAML::convert<ComponentType>::decode(componentNode, *component);
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
{
YAML::Emitter out;
YAML::Node node{};
node[rttr::type::get<ComponentType>().get_name().data()] = SerializeComponentToNode(component);
out << node;
return out.c_str();
}
return std::string();
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static bool DeserializeComponentFromString(std::string data, EntityID const& eid)
{
YAML::Node node = YAML::Load(data);
return InitializeComponentFromNode<ComponentType>(node, eid);
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>

View File

@ -20,6 +20,16 @@ namespace YAML
{
using namespace SHADE;
template<typename T>
struct HasYAMLConv : std::false_type{};
template<>
struct HasYAMLConv<SHColliderComponent> : std::true_type {};
template<>
struct HasYAMLConv<SHRenderable> : std::true_type {};
template<>
struct HasYAMLConv<SHTextRenderableComponent> : std::true_type {};
template<>
struct convert<SHVec4>
{