Merge pull request #96 from SHADE-DP/SP3-8-serialization
Added Serialization/Deserialization Added serialization and deserialization of scenes, entities and components with the exception of collider component and renderable component
This commit is contained in:
commit
7e3ca4c45f
|
@ -21,6 +21,8 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include "Serialization/SHSerialization.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -171,6 +173,10 @@ namespace SHADE
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
}
|
}
|
||||||
|
if(ImGui::Selectable("Copy"))
|
||||||
|
{
|
||||||
|
SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities))
|
||||||
|
}
|
||||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
{
|
{
|
||||||
SHEntityManager::DestroyEntity(eid);
|
SHEntityManager::DestroyEntity(eid);
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
#include <rttr/type>
|
#include <rttr/type>
|
||||||
|
|
||||||
|
#include "Serialization/SHSerialization.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
|
@ -73,7 +75,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("File"))
|
if (ImGui::BeginMenu("File"))
|
||||||
{
|
{
|
||||||
|
if(ImGui::Selectable("Save"))
|
||||||
|
{
|
||||||
|
SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE");
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable("Load"))
|
||||||
|
{
|
||||||
|
SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE");
|
||||||
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if(ImGui::BeginMenu("Edit"))
|
if(ImGui::BeginMenu("Edit"))
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSerializationHelper.hpp"
|
||||||
|
#include "SHSerialization.h"
|
||||||
|
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Tools/SHException.h"
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
SerializeSceneToEmitter(out);
|
||||||
|
std::ofstream file(path.c_str());
|
||||||
|
if (file.good())
|
||||||
|
{
|
||||||
|
file << out.c_str();
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHSerialization::SerializeSceneToString()
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
SerializeSceneToEmitter(out);
|
||||||
|
return std::basic_string<char>(out.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::SerializeSceneToEmitter(YAML::Emitter& out)
|
||||||
|
{
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
auto root = sceneGraph.GetRoot();
|
||||||
|
|
||||||
|
SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node.");
|
||||||
|
|
||||||
|
auto const& children = root->GetChildren();
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
|
||||||
|
auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
|
||||||
|
sceneGraph.Traverse(pred);
|
||||||
|
//out << SerializeEntityToNode(child);
|
||||||
|
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
|
||||||
|
{
|
||||||
|
if (!node[EIDNode])
|
||||||
|
return;
|
||||||
|
EntityID eid = node[EIDNode].as<EntityID>();
|
||||||
|
std::string name = "Default";
|
||||||
|
if (node[EntityNameNode])
|
||||||
|
name = node[EntityNameNode].as<std::string>();
|
||||||
|
//Compile component IDs
|
||||||
|
const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]);
|
||||||
|
eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID);
|
||||||
|
createdEntities.push_back(eid);
|
||||||
|
if (node[NumberOfChildrenNode])
|
||||||
|
{
|
||||||
|
if(const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
for (int i = 0; i < numOfChildren; ++i)
|
||||||
|
{
|
||||||
|
DeserializeEntity(it, (*it), createdEntities, eid);
|
||||||
|
if((i + 1) < numOfChildren)
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
//TODO:Shift to using XQ's FileIO
|
||||||
|
std::ifstream iFile;
|
||||||
|
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
std::string fileContent = "";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Open file
|
||||||
|
// Read file's buffer contents into streams
|
||||||
|
iFile.open(path);
|
||||||
|
std::stringstream fileStream;
|
||||||
|
fileStream << iFile.rdbuf();
|
||||||
|
|
||||||
|
fileContent = fileStream.str();
|
||||||
|
|
||||||
|
// Close file handler
|
||||||
|
iFile.close();
|
||||||
|
}
|
||||||
|
catch (std::ifstream::failure e)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Could not read file");
|
||||||
|
}
|
||||||
|
YAML::Node entities = YAML::Load(fileContent);
|
||||||
|
std::vector<EntityID> createdEntities{};
|
||||||
|
|
||||||
|
//Create Entities
|
||||||
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
{
|
||||||
|
DeserializeEntity(it, (*it), createdEntities);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Initialize Entity
|
||||||
|
auto entityVecIt = createdEntities.begin();
|
||||||
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
{
|
||||||
|
InitializeEntity(*it, *entityVecIt++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
|
||||||
|
{
|
||||||
|
out << SerializeEntityToNode(entityNode);
|
||||||
|
auto const& children = entityNode->GetChildren();
|
||||||
|
for(auto const& child : children)
|
||||||
|
{
|
||||||
|
EmitEntity(child, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities)
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
YAML::Node node;
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
for (auto const& eid : entities)
|
||||||
|
{
|
||||||
|
auto entityNode = sceneGraph.GetNode(eid);
|
||||||
|
EmitEntity(entityNode, out);
|
||||||
|
}
|
||||||
|
return std::basic_string<char>(out.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
|
||||||
|
{
|
||||||
|
YAML::Node node;
|
||||||
|
auto eid = sceneNode->GetEntityID();
|
||||||
|
auto entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
if (!sceneNode || !entity)
|
||||||
|
{
|
||||||
|
node = YAML::Null;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Block);
|
||||||
|
node[EIDNode] = eid;
|
||||||
|
node[EntityNameNode] = entity->name;
|
||||||
|
node[IsActiveNode] = sceneNode->IsActive();
|
||||||
|
auto const& children = sceneNode->GetChildren();
|
||||||
|
node[NumberOfChildrenNode] = children.size();
|
||||||
|
|
||||||
|
YAML::Node components;
|
||||||
|
|
||||||
|
if (const auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
components[rttr::type::get<SHTransformComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform);
|
||||||
|
}
|
||||||
|
if (const auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(eid))
|
||||||
|
{
|
||||||
|
components[rttr::type::get<SHRenderable>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(renderable);
|
||||||
|
}
|
||||||
|
if (const auto rigidbody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
|
||||||
|
{
|
||||||
|
components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody);
|
||||||
|
}
|
||||||
|
node[ComponentsNode] = components;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
|
||||||
|
{
|
||||||
|
if (componentNode[rttr::type::get<ComponentType>().get_name().data()])
|
||||||
|
return { SHFamilyID<SHComponent>::GetID<ComponentType>() };
|
||||||
|
else
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ComponentTypeID> SHSerialization::GetComponentIDList(YAML::Node const& componentsNode)
|
||||||
|
{
|
||||||
|
std::vector<ComponentTypeID> componentIDList;
|
||||||
|
|
||||||
|
auto id = GetComponentID<SHTransformComponent>(componentsNode);
|
||||||
|
if (id.has_value())
|
||||||
|
componentIDList.push_back(id.value());
|
||||||
|
|
||||||
|
id = GetComponentID<SHRenderable>(componentsNode);
|
||||||
|
if (id.has_value())
|
||||||
|
componentIDList.push_back(id.value());
|
||||||
|
|
||||||
|
id = GetComponentID<SHRigidBodyComponent>(componentsNode);
|
||||||
|
if (id.has_value())
|
||||||
|
componentIDList.push_back(id.value());
|
||||||
|
|
||||||
|
return componentIDList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
||||||
|
{
|
||||||
|
auto const componentsNode = entityNode[ComponentsNode];
|
||||||
|
if (!componentsNode)
|
||||||
|
return;
|
||||||
|
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <ECS_Base/Components/SHComponent.h>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
class Emitter;
|
||||||
|
class Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHSceneNode;
|
||||||
|
|
||||||
|
constexpr const char* ComponentsNode = "Components";
|
||||||
|
constexpr const char* EntityNameNode = "Name";
|
||||||
|
constexpr const char* EIDNode = "EID";
|
||||||
|
constexpr const char* IsActiveNode = "IsActive";
|
||||||
|
constexpr const char* NumberOfChildrenNode = "NumberOfChildren";
|
||||||
|
|
||||||
|
struct SH_API SHSerialization
|
||||||
|
{
|
||||||
|
//TODO: change paths to resource ID
|
||||||
|
static void SerializeSceneToFile(std::filesystem::path const& path);
|
||||||
|
static std::string SerializeSceneToString();
|
||||||
|
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
||||||
|
static void DeserializeSceneFromFile(std::filesystem::path const& path);
|
||||||
|
|
||||||
|
|
||||||
|
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
||||||
|
static std::string SerializeEntitiesToString(std::vector<EntityID> const& entities);
|
||||||
|
static void SerializeEntityToFile(std::filesystem::path const& path);
|
||||||
|
static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode);
|
||||||
|
|
||||||
|
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||||
|
private:
|
||||||
|
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHSerializationHelper
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static YAML::Node RTTRToNode(const rttr::variant& var)
|
||||||
|
{
|
||||||
|
YAML::Node node;
|
||||||
|
auto varType = var.get_type();
|
||||||
|
if (varType == rttr::type::get<SHVec4>())
|
||||||
|
{
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
node["X"] = var.convert<SHVec4>().x;
|
||||||
|
node["Y"] = var.convert<SHVec4>().y;
|
||||||
|
node["Z"] = var.convert<SHVec4>().z;
|
||||||
|
node["W"] = var.convert<SHVec4>().w;
|
||||||
|
}
|
||||||
|
else if (varType == rttr::type::get<SHVec3>())
|
||||||
|
{
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
node["X"] = var.convert<SHVec3>().x;
|
||||||
|
node["Y"] = var.convert<SHVec3>().y;
|
||||||
|
node["Z"] = var.convert<SHVec3>().z;
|
||||||
|
}
|
||||||
|
else if (varType == rttr::type::get<SHVec2>())
|
||||||
|
{
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
node["X"] = var.convert<SHVec3>().x;
|
||||||
|
node["Y"] = var.convert<SHVec3>().y;
|
||||||
|
}
|
||||||
|
else if (varType.is_arithmetic())
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
if (varType == rttr::type::get<bool>())
|
||||||
|
node = var.to_bool();
|
||||||
|
else if (varType == rttr::type::get<int8_t>())
|
||||||
|
node = var.to_int8(&ok);
|
||||||
|
else if (varType == rttr::type::get<int16_t>())
|
||||||
|
node = var.to_int16(&ok);
|
||||||
|
else if (varType == rttr::type::get<int32_t>())
|
||||||
|
node = var.to_int32(&ok);
|
||||||
|
else if (varType == rttr::type::get<int64_t>())
|
||||||
|
node = var.to_int64(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint8_t>())
|
||||||
|
node = var.to_uint8(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint16_t>())
|
||||||
|
node = var.to_uint16(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint32_t>())
|
||||||
|
node = var.to_uint32(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint64_t>())
|
||||||
|
node = var.to_uint64(&ok);
|
||||||
|
else if (varType == rttr::type::get<float>())
|
||||||
|
node = var.to_float(&ok);
|
||||||
|
else if (varType == rttr::type::get<double>())
|
||||||
|
node = var.to_double(&ok);
|
||||||
|
//else if (varType == rttr::type::get<char>()) //same as uint8_t
|
||||||
|
// node = var.to_uint8();
|
||||||
|
}
|
||||||
|
else if (varType.is_enumeration())
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
auto result = var.to_string(&ok);
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
node = var.to_string();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
auto value = var.to_uint64(&ok);
|
||||||
|
if (ok)
|
||||||
|
node = value;
|
||||||
|
else
|
||||||
|
node = YAML::Null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto properties = var.get_type().get_properties();
|
||||||
|
for (auto property : properties)
|
||||||
|
{
|
||||||
|
node[property.get_name().data()] = RTTRToNode(property.get_value(var));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode)
|
||||||
|
{
|
||||||
|
auto propType = prop.get_type();
|
||||||
|
if (propType == rttr::type::get<SHVec4>())
|
||||||
|
{
|
||||||
|
SHVec4 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>(), propertyNode["W"].as<float>() };
|
||||||
|
prop.set_value(component, vec);
|
||||||
|
}
|
||||||
|
else if (propType == rttr::type::get<SHVec3>())
|
||||||
|
{
|
||||||
|
SHVec3 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>() };
|
||||||
|
prop.set_value(component, vec);
|
||||||
|
}
|
||||||
|
else if (propType == rttr::type::get<SHVec2>())
|
||||||
|
{
|
||||||
|
SHVec2 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>() };
|
||||||
|
prop.set_value(component, vec);
|
||||||
|
}
|
||||||
|
else if (propType.is_arithmetic())
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
if (propType == rttr::type::get<bool>())
|
||||||
|
prop.set_value(component, propertyNode.as<bool>());
|
||||||
|
else if (propType == rttr::type::get<int8_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int8_t>());
|
||||||
|
else if (propType == rttr::type::get<int16_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int16_t>());
|
||||||
|
else if (propType == rttr::type::get<int32_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int32_t>());
|
||||||
|
else if (propType == rttr::type::get<int64_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int64_t>());
|
||||||
|
else if (propType == rttr::type::get<uint8_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint8_t>());
|
||||||
|
else if (propType == rttr::type::get<uint16_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint16_t>());
|
||||||
|
else if (propType == rttr::type::get<uint32_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint32_t>());
|
||||||
|
else if (propType == rttr::type::get<uint64_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint64_t>());
|
||||||
|
else if (propType == rttr::type::get<float>())
|
||||||
|
prop.set_value(component, propertyNode.as<float>());
|
||||||
|
else if (propType == rttr::type::get<double>())
|
||||||
|
prop.set_value(component, propertyNode.as<double>());
|
||||||
|
}
|
||||||
|
else if (propType.is_enumeration())
|
||||||
|
{
|
||||||
|
auto enumAlign = prop.get_enumeration();
|
||||||
|
prop.set_value(component, enumAlign.name_to_value(propertyNode.as<std::string>()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto properties = propType.get_properties();
|
||||||
|
for (auto property : properties)
|
||||||
|
{
|
||||||
|
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
auto 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 (componentsNode.IsNull())
|
||||||
|
return;
|
||||||
|
auto properties = rttrType.get_properties();
|
||||||
|
for (auto const& prop : properties)
|
||||||
|
{
|
||||||
|
if (componentNode[prop.get_name().data()])
|
||||||
|
{
|
||||||
|
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue