diff --git a/SHADE_Engine/src/Serialization/Prefab/SHPrefabManager.h b/SHADE_Engine/src/Serialization/Prefab/SHPrefabManager.h index 6222a736..0c56ce4d 100644 --- a/SHADE_Engine/src/Serialization/Prefab/SHPrefabManager.h +++ b/SHADE_Engine/src/Serialization/Prefab/SHPrefabManager.h @@ -5,7 +5,7 @@ #include "ECS_Base/General/SHFamily.h" #include "ECS_Base/Components/SHComponent.h" #include - +#include <> namespace SHADE { @@ -21,6 +21,7 @@ namespace SHADE }; using PrefabMap = std::unordered_map>; + //using PrefabDatabase = std::unordered_multimap,PrefabEntityComponentStatus>>; static AssetID GetPrefabAssetID(EntityID eid) noexcept; diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index aae82503..4e2036d3 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -16,6 +16,7 @@ #include "Scripting/SHScriptEngine.h" #include "Tools/FileIO/SHFileIO.h" #include "Prefab/SHPrefabManager.h" +#include "Assets/Asset Types/SHPrefabAsset.h" namespace SHADE { @@ -418,15 +419,34 @@ namespace SHADE void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid) { - auto const componentsNode = entityNode[ComponentsNode]; - if (!componentsNode) + auto componentsNode = entityNode[ComponentsNode]; + if (!componentsNode.IsDefined()) return; + SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); + SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); + + bool isPrefab = entityNode[PrefabID].IsDefined(); + if(isPrefab) + { + auto prefabAssetID = entityNode[PrefabID].as(); + if(auto prefabAsset = SHAssetManager::GetData(prefabAssetID)) + { + auto prefabNode = YAML::Load(prefabAsset->data); + if(prefabNode[ComponentsNode].IsDefined()) + { + componentsNode = prefabNode[ComponentsNode]; + } + + if (prefabNode[ScriptsNode].IsDefined()) + SHSystemManager::GetSystem()->DeserialiseScripts(eid, prefabNode[ScriptsNode]); + } + } + SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); - SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); @@ -437,7 +457,8 @@ namespace SHADE SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); - if (entityNode[ScriptsNode].IsDefined()) + + if (!isPrefab && entityNode[ScriptsNode].IsDefined()) SHSystemManager::GetSystem()->DeserialiseScripts(eid, entityNode[ScriptsNode]); } diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index a4936528..645b3927 100644 --- a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -209,7 +209,7 @@ namespace SHADE auto component = SHComponentManager::GetComponent_s(eid); if (componentsNode.IsNull() || !component) return false; - auto componentNode = GetComponentNode(componentsNode, eid); + auto componentNode = GetComponentNode(componentsNode, component); if (componentNode.IsNull() || !componentNode.IsDefined()) return false; if (componentNode[IsActive.data()].IsDefined()) @@ -242,9 +242,46 @@ namespace SHADE } template , bool> = true> - static YAML::Node GetComponentNode(YAML::Node const& componentsNode, EntityID const& eid) + static bool InitializeComponentFromNode(YAML::Node const& componentsNode, ComponentType* component) + { + if constexpr (YAML::HasYAMLConv()) + { + if (componentsNode.IsNull() || !component) + return false; + auto componentNode = GetComponentNode(componentsNode, component); + if (componentNode.IsNull() || !componentNode.IsDefined()) + return false; + if (componentNode[IsActive.data()].IsDefined()) + component->isActive = componentNode[IsActive.data()].as(); + YAML::convert::decode(componentNode, *component); + return true; + } + else + { + if (componentsNode.IsNull() && !component) + return false; + auto rttrType = rttr::type::get(); + auto componentNode = componentsNode[rttrType.get_name().data()]; + if (!componentNode.IsDefined()) + return false; + if (componentNode[IsActive.data()].IsDefined()) + component->isActive = componentNode[IsActive.data()].as(); + + auto properties = rttrType.get_properties(); + for (auto const& prop : properties) + { + if (componentNode[prop.get_name().data()].IsDefined()) + { + InitializeProperty(component, prop, componentNode[prop.get_name().data()]); + } + } + } + return true; + } + + template , bool> = true> + static YAML::Node GetComponentNode(YAML::Node const& componentsNode, ComponentType* component) { - auto component = SHComponentManager::GetComponent_s(eid); if (componentsNode.IsNull() && !component) return {}; auto rttrType = rttr::type::get(); @@ -307,7 +344,8 @@ namespace SHADE template<> static void FetchAssetsFromComponent(YAML::Node const& componentsNode, EntityID const& eid, AssetQueue& assetQueue) { - auto node = GetComponentNode(componentsNode, eid); + SHRenderable* renderableComponent = SHComponentManager::GetComponent_s(eid); + auto node = GetComponentNode(componentsNode, renderableComponent); if(!node.IsDefined()) return; if (auto const& meshNode = node[YAML::convert::MESH_YAML_TAG.data()]; meshNode.IsDefined())