SHADE_Y3/SHADE_Engine/src/Serialization/SHSerialization.cpp

344 lines
12 KiB
C++
Raw Normal View History

2022-09-26 21:08:59 +08:00
#include "SHpch.h"
#include <yaml-cpp/yaml.h>
#include "SHSerialization.h"
#include "SHSerializationHelper.hpp"
2022-09-26 21:08:59 +08:00
2022-09-27 21:06:25 +08:00
#include "ECS_Base/Managers/SHEntityManager.h"
2022-09-26 21:08:59 +08:00
#include "Scene/SHSceneManager.h"
#include "Tools/SHException.h"
2022-10-01 23:43:00 +08:00
#include "Assets/SHAssetManager.h"
#include <fstream>
2022-09-26 21:08:59 +08:00
2022-11-04 14:44:18 +08:00
#include "Assets/Asset Types/SHSceneAsset.h"
#include "Camera/SHCameraComponent.h"
2022-10-01 23:43:00 +08:00
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
2022-09-26 21:08:59 +08:00
#include "Math/Transform/SHTransformComponent.h"
2022-11-12 16:56:58 +08:00
#include "Physics/Interface/SHRigidBodyComponent.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Scripting/SHScriptEngine.h"
2022-11-04 14:44:18 +08:00
#include "Tools/FileIO/SHFileIO.h"
2022-09-26 21:08:59 +08:00
namespace SHADE
{
2022-11-04 14:44:18 +08:00
bool SHSerialization::SerializeSceneToFile(AssetID const& sceneAssetID)
2022-09-26 21:08:59 +08:00
{
2022-11-04 14:44:18 +08:00
auto assetData = SHAssetManager::GetData<SHSceneAsset>(sceneAssetID);
if(!assetData)
2022-10-01 23:43:00 +08:00
{
2022-11-04 14:44:18 +08:00
SHLOG_ERROR("Asset does not exist: {}", sceneAssetID);
return false;
2022-10-01 23:43:00 +08:00
}
2022-11-04 14:44:18 +08:00
YAML::Emitter out;
SerializeSceneToEmitter(out);
assetData->data = out.c_str();
return SHAssetManager::SaveAsset(sceneAssetID);
2022-09-26 23:51:20 +08:00
}
2022-09-26 21:08:59 +08:00
2022-09-26 23:51:20 +08:00
std::string SHSerialization::SerializeSceneToString()
{
YAML::Emitter out;
SerializeSceneToEmitter(out);
2022-10-01 23:43:00 +08:00
return std::basic_string<char>(out.c_str());
2022-09-26 23:51:20 +08:00
}
2022-09-26 21:08:59 +08:00
2022-09-26 23:51:20 +08:00
void SHSerialization::SerializeSceneToEmitter(YAML::Emitter& out)
{
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
auto root = sceneGraph.GetRoot();
2022-09-26 21:08:59 +08:00
2022-09-26 23:51:20 +08:00
SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node.");
2022-10-01 23:43:00 +08:00
2022-09-26 23:51:20 +08:00
auto const& children = root->GetChildren();
2022-10-01 23:43:00 +08:00
out << YAML::BeginSeq;
2022-09-27 21:06:25 +08:00
2022-10-01 23:43:00 +08:00
auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
2022-09-27 21:06:25 +08:00
sceneGraph.Traverse(pred);
2022-10-01 23:43:00 +08:00
//out << SerializeEntityToNode(child);
out << YAML::EndSeq;
2022-09-27 21:06:25 +08:00
}
static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, SHSerialization::CreatedEntitiesList& createdEntities, EntityID parentEID = MAX_EID)
2022-09-27 21:06:25 +08:00
{
EntityID eid{MAX_EID}, oldEID{MAX_EID};
if (!node)
2022-10-19 17:23:25 +08:00
return eid;
if (node[EIDNode])
oldEID = eid = node[EIDNode].as<EntityID>();
std::string name = "UnnamedEntitiy";
2022-10-01 23:43:00 +08:00
if (node[EntityNameNode])
2022-09-27 21:06:25 +08:00
name = node[EntityNameNode].as<std::string>();
//Compile component IDs
const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]);
eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID);
createdEntities[oldEID] = eid;
//createdEntities.push_back(eid);
2022-10-01 23:43:00 +08:00
if (node[NumberOfChildrenNode])
{
if (const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
2022-09-27 21:06:25 +08:00
{
++it;
2022-10-01 23:43:00 +08:00
for (int i = 0; i < numOfChildren; ++i)
{
DeserializeEntity(it, (*it), createdEntities, eid);
if ((i + 1) < numOfChildren)
2022-10-01 23:43:00 +08:00
++it;
}
2022-09-27 21:06:25 +08:00
}
}
2022-10-20 11:08:20 +08:00
// Deserialise scripts
if (node[ScriptsNode])
SHSystemManager::GetSystem<SHScriptEngine>()->DeserialiseScripts(eid, node[ScriptsNode]);
return eid;
2022-09-27 21:06:25 +08:00
}
2022-11-04 14:44:18 +08:00
std::string SHSerialization::DeserializeSceneFromFile(AssetID const& sceneAssetID) noexcept
2022-09-27 21:06:25 +08:00
{
2022-11-04 14:44:18 +08:00
auto assetData = SHAssetManager::GetData<SHSceneAsset>(sceneAssetID);
if(!assetData)
2022-10-01 23:43:00 +08:00
{
2022-11-04 14:44:18 +08:00
SHLOG_ERROR("Attempted to load scene that doesn't exist {}", sceneAssetID)
SHSceneManager::SetCurrentSceneAssetID(0);
return NewSceneName.data();
2022-10-01 23:43:00 +08:00
}
2022-11-04 14:44:18 +08:00
YAML::Node entities = YAML::Load(assetData->data);
CreatedEntitiesList createdEntities{};
2022-09-27 21:06:25 +08:00
//Create Entities
2022-10-01 23:43:00 +08:00
for (auto it = entities.begin(); it != entities.end(); ++it)
2022-09-26 21:08:59 +08:00
{
2022-09-27 21:06:25 +08:00
DeserializeEntity(it, (*it), createdEntities);
}
if (createdEntities.empty())
2022-10-19 17:23:25 +08:00
{
SHLOG_ERROR("Failed to create entities from deserializaiton")
2022-11-04 14:44:18 +08:00
return NewSceneName.data();
2022-10-19 17:23:25 +08:00
}
2022-10-01 23:43:00 +08:00
auto entityVecIt = createdEntities.begin();
AssetQueue assetQueue;
for (auto it = entities.begin(); it != entities.end(); ++it)
{
SHSerializationHelper::FetchAssetsFromComponent<SHRenderable>((*it)[ComponentsNode], createdEntities[(*it)[EIDNode].as<EntityID>()], assetQueue);
}
LoadAssetsFromAssetQueue(assetQueue);
//Initialize Entity
entityVecIt = createdEntities.begin();
2022-10-01 23:43:00 +08:00
for (auto it = entities.begin(); it != entities.end(); ++it)
2022-09-27 21:06:25 +08:00
{
InitializeEntity(*it, createdEntities[(*it)[EIDNode].as<EntityID>()]);
2022-09-26 21:08:59 +08:00
}
2022-11-04 14:44:18 +08:00
return assetData->name;
}
2022-09-26 21:08:59 +08:00
2022-10-19 01:03:32 +08:00
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
{
out << SerializeEntityToNode(entityNode);
auto const& children = entityNode->GetChildren();
for (auto const& child : children)
2022-10-19 01:03:32 +08:00
{
EmitEntity(child, out);
}
}
2022-09-27 21:06:25 +08:00
2022-10-19 17:23:25 +08:00
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities) noexcept
2022-09-26 23:51:20 +08:00
{
2022-10-19 01:03:32 +08:00
YAML::Emitter out;
YAML::Node node;
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
2022-10-19 17:23:25 +08:00
out << YAML::BeginSeq;
2022-10-19 01:03:32 +08:00
for (auto const& eid : entities)
{
auto entityNode = sceneGraph.GetNode(eid);
EmitEntity(entityNode, out);
}
2022-10-19 17:23:25 +08:00
out << YAML::EndSeq;
return std::string(out.c_str());
2022-09-26 23:51:20 +08:00
}
2022-09-26 21:08:59 +08:00
//void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
//{
//}
2022-09-26 23:51:20 +08:00
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;
}
}
2022-09-26 23:51:20 +08:00
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
{
YAML::Node node;
2022-09-27 21:06:25 +08:00
auto eid = sceneNode->GetEntityID();
auto entity = SHEntityManager::GetEntityByID(eid);
if (!sceneNode && !entity)
2022-09-26 21:08:59 +08:00
{
2022-09-26 23:51:20 +08:00
node = YAML::Null;
return node;
}
node.SetStyle(YAML::EmitterStyle::Block);
2022-09-27 21:06:25 +08:00
node[EIDNode] = eid;
node[EntityNameNode] = entity->name;
node[IsActiveNode] = sceneNode->IsActive();
2022-09-26 23:51:20 +08:00
auto const& children = sceneNode->GetChildren();
2022-09-27 21:06:25 +08:00
node[NumberOfChildrenNode] = children.size();
2022-09-26 21:08:59 +08:00
2022-09-26 23:51:20 +08:00
YAML::Node components;
2022-09-26 21:08:59 +08:00
AddComponentToComponentNode<SHTransformComponent>(components, eid);
AddComponentToComponentNode<SHCameraComponent>(components, eid);
AddConvComponentToComponentNode<SHRenderable>(components, eid);
AddComponentToComponentNode<SHLightComponent>(components, eid);
AddComponentToComponentNode<SHRigidBodyComponent>(components, eid);
AddConvComponentToComponentNode<SHColliderComponent>(components, eid);
2022-09-27 21:06:25 +08:00
node[ComponentsNode] = components;
YAML::Node scripts;
SHSystemManager::GetSystem<SHScriptEngine>()->SerialiseScripts(eid, scripts);
node[ScriptsNode] = scripts;
2022-09-26 23:51:20 +08:00
return node;
2022-09-26 21:08:59 +08:00
}
2022-09-27 21:06:25 +08:00
SHSerialization::CreatedEntitiesList SHSerialization::DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID) noexcept
2022-10-19 17:23:25 +08:00
{
if (data.empty())
return {};
2022-10-19 17:23:25 +08:00
YAML::Node entities = YAML::Load(data.c_str());
EntityID eid{ MAX_EID };
CreatedEntitiesList createdEntities{};
for (auto it = entities.begin(); it != entities.end(); ++it)
2022-10-19 17:23:25 +08:00
{
eid = DeserializeEntity(it, *it, createdEntities, parentEID);
}
if (createdEntities.empty())
2022-10-19 17:23:25 +08:00
{
SHLOG_ERROR("Failed to create entities from deserializaiton")
return createdEntities;
2022-10-19 17:23:25 +08:00
}
//auto entityVecIt = createdEntities.begin();
for (auto it = entities.begin(); it != entities.end(); ++it)
2022-10-19 17:23:25 +08:00
{
InitializeEntity(*it, createdEntities[(*it)[EIDNode].as<EntityID>()]);
2022-10-19 17:23:25 +08:00
}
return createdEntities;
2022-10-19 17:23:25 +08:00
}
2022-09-27 21:06:25 +08:00
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void AddComponentID(std::vector<ComponentTypeID>& idList, YAML::Node const& componentNode)
2022-09-27 21:06:25 +08:00
{
2022-10-01 23:43:00 +08:00
if (componentNode[rttr::type::get<ComponentType>().get_name().data()])
idList.push_back(SHFamilyID<SHComponent>::GetID<ComponentType>());
2022-09-27 21:06:25 +08:00
}
std::vector<ComponentTypeID> SHSerialization::GetComponentIDList(YAML::Node const& componentsNode)
{
std::vector<ComponentTypeID> componentIDList;
AddComponentID<SHTransformComponent>(componentIDList, componentsNode);
AddComponentID<SHCameraComponent>(componentIDList, componentsNode);
AddComponentID<SHRenderable>(componentIDList, componentsNode);
AddComponentID<SHRigidBodyComponent>(componentIDList, componentsNode);
AddComponentID<SHLightComponent>(componentIDList, componentsNode);
AddComponentID<SHColliderComponent>(componentIDList, componentsNode);
2022-09-27 21:06:25 +08:00
return componentIDList;
}
2022-10-01 23:43:00 +08:00
void SHSerialization::LoadAssetsFromAssetQueue(AssetQueue& assetQueue)
{
for (auto& [assetId, assetType] : assetQueue)
{
switch(assetType)
{
case AssetType::INVALID: break;
case AssetType::SHADER: break;
case AssetType::SHADER_BUILT_IN: break;
case AssetType::TEXTURE:
SHResourceManager::LoadOrGet<SHTexture>(assetId);
break;
case AssetType::MESH:
SHResourceManager::LoadOrGet<SHMesh>(assetId);
break;
case AssetType::SCENE: break;
case AssetType::PREFAB: break;
case AssetType::MATERIAL:
SHResourceManager::LoadOrGet<SHMaterial>(assetId);
break;
case AssetType::MAX_COUNT: break;
default: ;
}
}
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();
}
2022-10-01 23:43:00 +08:00
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
{
2022-10-19 01:03:32 +08:00
auto const componentsNode = entityNode[ComponentsNode];
if (!componentsNode)
2022-10-01 23:43:00 +08:00
return;
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHCameraComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHColliderComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
2022-10-01 23:43:00 +08:00
}
2022-09-26 21:08:59 +08:00
}