add node merge
This commit is contained in:
parent
f27dbb92b3
commit
a833de2c91
|
@ -23,6 +23,7 @@
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
#include <Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h>
|
#include <Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h>
|
||||||
#include "Serialization/Prefab/SHPrefabManager.h"
|
#include "Serialization/Prefab/SHPrefabManager.h"
|
||||||
|
#include <Scene/SHSceneManager.h>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -415,7 +416,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
auto createdEntitiesList = SHSerialization::DeserializeEntitiesFromString(SHAssetManager::GetData<SHPrefabAsset>(asset->id)->data);
|
auto createdEntitiesList = SHSerialization::DeserializeEntitiesFromString(SHAssetManager::GetData<SHPrefabAsset>(asset->id)->data);
|
||||||
SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>()->SetScrollTo(createdEntitiesList.begin()->second);
|
SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>()->SetScrollTo(createdEntitiesList.begin()->second);
|
||||||
SHPrefabManager::AddEntity(asset->id, createdEntitiesList.begin()->second);
|
std::vector<EntityID> eidList;
|
||||||
|
SHPrefabManager::RecursivelyFlattenEntityHierarchy(SHSceneManager::GetCurrentSceneGraph().GetNode(createdEntitiesList.begin()->second), eidList);
|
||||||
|
SHPrefabManager::AddPrefabInstance(asset->id, eidList);
|
||||||
|
//SHPrefabManager::AddEntity(asset->id, createdEntitiesList.begin()->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -390,7 +390,8 @@ namespace SHADE
|
||||||
std::ranges::transform(createdEntitiesList, std::back_inserter(eidList), [](std::pair<EntityID, EntityID> pair){return pair.second;} );
|
std::ranges::transform(createdEntitiesList, std::back_inserter(eidList), [](std::pair<EntityID, EntityID> pair){return pair.second;} );
|
||||||
ParentSelectedEntities(eid, eidList);
|
ParentSelectedEntities(eid, eidList);
|
||||||
SetScrollTo(createdEntitiesList.begin()->second);
|
SetScrollTo(createdEntitiesList.begin()->second);
|
||||||
SHPrefabManager::AddEntity(assetId, createdEntitiesList.begin()->second);
|
SHPrefabManager::AddPrefabInstance(assetId, eidList);
|
||||||
|
//SHPrefabManager::AddEntity(assetId, createdEntitiesList.begin()->second);
|
||||||
skipFrame = true;
|
skipFrame = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,13 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHPrefabManager::PrefabMap SHPrefabManager::prefabMap{};
|
SHPrefabManager::PrefabMap SHPrefabManager::prefabMap{};
|
||||||
|
SHPrefabManager::PrefabEntityDatabase SHPrefabManager::prefabEntityDatabase{};
|
||||||
|
|
||||||
AssetID SHPrefabManager::GetPrefabAssetID(EntityID eid) noexcept
|
AssetID SHPrefabManager::GetPrefabAssetID(EntityID eid) noexcept
|
||||||
{
|
{
|
||||||
for(auto const& [assetId, entityList] : prefabMap)
|
for (auto const& [assetId, entityList] : prefabMap)
|
||||||
{
|
{
|
||||||
if(std::ranges::find(entityList, eid) != entityList.end())
|
if (std::ranges::find(entityList, eid) != entityList.end())
|
||||||
{
|
{
|
||||||
return assetId;
|
return assetId;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +24,10 @@ namespace SHADE
|
||||||
|
|
||||||
void SHPrefabManager::AddPrefab(AssetID const& prefabAssetID) noexcept
|
void SHPrefabManager::AddPrefab(AssetID const& prefabAssetID) noexcept
|
||||||
{
|
{
|
||||||
prefabMap[prefabAssetID] = {};
|
//if (prefabMap.contains(prefabAssetID))
|
||||||
|
//{
|
||||||
|
// prefabMap.insert(prefabAssetID, {});
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPrefabManager::RemovePrefab(AssetID const& prefabAssetID) noexcept
|
void SHPrefabManager::RemovePrefab(AssetID const& prefabAssetID) noexcept
|
||||||
|
@ -35,35 +39,59 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (prefabMap.contains(prefabAssetID))
|
if (prefabMap.contains(prefabAssetID))
|
||||||
{
|
{
|
||||||
prefabMap[prefabAssetID].clear();
|
prefabMap.erase(prefabAssetID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPrefabManager::UpdateAllPrefabEntities(AssetID const& prefabAssetID) noexcept
|
void SHPrefabManager::UpdateAllPrefabEntities(AssetID const& prefabAssetID) noexcept
|
||||||
{
|
{
|
||||||
//Loop through all entities and deserialize new data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPrefabManager::AddEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept
|
void SHPrefabManager::AddPrefabInstance(AssetID prefabAssetID, std::vector<EntityID> eidList)
|
||||||
{
|
{
|
||||||
|
prefabMap.insert({ prefabAssetID, eidList });
|
||||||
prefabMap[prefabAssetID].push_back(eid);
|
std::size_t size = eidList.size();
|
||||||
|
for (std::size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
prefabEntityDatabase[eidList[i]] = { prefabAssetID, i };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPrefabManager::RemoveEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept
|
void SHPrefabManager::RemovePrefabInstance(AssetID prefabAssetID, EntityID rootEid)
|
||||||
{
|
{
|
||||||
if (prefabMap.contains(prefabAssetID))
|
if (auto iter = prefabMap.find(prefabAssetID); iter != prefabMap.end())
|
||||||
{
|
{
|
||||||
(void)std::ranges::remove(prefabMap[prefabAssetID], eid);
|
while (iter != prefabMap.upper_bound(prefabAssetID))
|
||||||
|
{
|
||||||
|
if (std::ranges::find(iter->second, rootEid) != iter->second.end())
|
||||||
|
{
|
||||||
|
prefabMap.erase(iter);
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPrefabManager::RecursivelyFlattenEntityHierarchy(SHSceneNode* node, std::vector<EntityID>& eidList)
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
eidList.push_back(node->GetEntityID());
|
||||||
|
auto const& children = node->GetChildren();
|
||||||
|
for (auto childNode : children)
|
||||||
|
{
|
||||||
|
RecursivelyFlattenEntityHierarchy(childNode, eidList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPrefabManager::SaveEntityAsPrefab(EntityID const& eid) noexcept
|
void SHPrefabManager::SaveEntityAsPrefab(EntityID const& eid) noexcept
|
||||||
{
|
{
|
||||||
SHEntity* const entity = SHEntityManager::GetEntityByID(eid);
|
SHEntity* const entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid);
|
||||||
AssetID const assetID = SHAssetManager::CreateNewAsset(AssetType::PREFAB, entity->name);
|
AssetID const assetID = SHAssetManager::CreateNewAsset(AssetType::PREFAB, entity->name);
|
||||||
AddEntity(assetID, eid);
|
std::vector<EntityID> eidList;
|
||||||
|
RecursivelyFlattenEntityHierarchy(entityNode, eidList);
|
||||||
|
AddPrefabInstance(assetID, eidList);
|
||||||
auto assetData = SHAssetManager::GetData<SHPrefabAsset>(assetID);
|
auto assetData = SHAssetManager::GetData<SHPrefabAsset>(assetID);
|
||||||
assetData->data = SHSerialization::SerializeEntityToString(eid, assetID);
|
assetData->data = SHSerialization::SerializeEntityToString(eid, assetID);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "ECS_Base/General/SHFamily.h"
|
#include "ECS_Base/General/SHFamily.h"
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <>
|
#include <Scene/SHSceneNode.h>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -20,24 +20,26 @@ namespace SHADE
|
||||||
PES_ADDED
|
PES_ADDED
|
||||||
};
|
};
|
||||||
|
|
||||||
using PrefabMap = std::unordered_map<AssetID, std::vector<EntityID>>;
|
using PrefabMap = std::unordered_multimap<AssetID, std::vector<EntityID>>;
|
||||||
//using PrefabDatabase = std::unordered_multimap<AssetID,
|
using PrefabEntityDatabase = std::unordered_map<EntityID, std::pair<AssetID, EntityID>>;
|
||||||
using PrefabEntitiesComponentStatusData = std::unordered_map<EntityID, std::unordered_map<SHFamilyID<SHComponent>,PrefabEntityComponentStatus>>;
|
|
||||||
|
|
||||||
static AssetID GetPrefabAssetID(EntityID eid) noexcept;
|
static AssetID GetPrefabAssetID(EntityID eid) noexcept;
|
||||||
static void AddPrefab(AssetID const& prefabAssetID) noexcept;
|
static void AddPrefab(AssetID const& prefabAssetID) noexcept;
|
||||||
static void RemovePrefab(AssetID const& prefabAssetID) noexcept;
|
static void RemovePrefab(AssetID const& prefabAssetID) noexcept;
|
||||||
static void ClearPrefab(AssetID const& prefabAssetID) noexcept;
|
static void ClearPrefab(AssetID const& prefabAssetID) noexcept;
|
||||||
static void UpdateAllPrefabEntities(AssetID const& prefabAssetID) noexcept;
|
static void UpdateAllPrefabEntities(AssetID const& prefabAssetID) noexcept;
|
||||||
static void AddEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept;
|
static void AddPrefabInstance(AssetID prefabAssetID, std::vector<EntityID> eidList);
|
||||||
static void RemoveEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept;
|
static void RemovePrefabInstance(AssetID prefabAssetID, EntityID rootEid);
|
||||||
|
static void RecursivelyFlattenEntityHierarchy(SHSceneNode* node, std::vector<EntityID>& eidList);
|
||||||
|
//static void AddEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept;
|
||||||
|
//static void RemoveEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept;
|
||||||
static void SaveEntityAsPrefab(EntityID const& eid) noexcept;
|
static void SaveEntityAsPrefab(EntityID const& eid) noexcept;
|
||||||
static void Clear() noexcept;
|
static void Clear() noexcept;
|
||||||
static bool Empty() noexcept;
|
static bool Empty() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static PrefabMap prefabMap;
|
static PrefabMap prefabMap;
|
||||||
static PrefabEntitiesComponentStatusData prefabEntitiesComponentStatusData;
|
static PrefabEntityDatabase prefabEntityDatabase;
|
||||||
|
|
||||||
friend class SHSerialization;
|
friend class SHSerialization;
|
||||||
friend struct SHSerializationHelper;
|
friend struct SHSerializationHelper;
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace SHADE
|
||||||
auto const& children = root->GetChildren();
|
auto const& children = root->GetChildren();
|
||||||
out << YAML::BeginSeq;
|
out << YAML::BeginSeq;
|
||||||
|
|
||||||
|
//auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
|
||||||
auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
|
auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
|
||||||
sceneGraph.Traverse(pred);
|
sceneGraph.Traverse(pred);
|
||||||
//out << SerializeEntityToNode(child);
|
//out << SerializeEntityToNode(child);
|
||||||
|
@ -97,6 +98,14 @@ namespace SHADE
|
||||||
std::string name = "UnnamedEntitiy";
|
std::string name = "UnnamedEntitiy";
|
||||||
if (node[EntityNameNode])
|
if (node[EntityNameNode])
|
||||||
name = node[EntityNameNode].as<std::string>();
|
name = node[EntityNameNode].as<std::string>();
|
||||||
|
|
||||||
|
//if(node[PrefabID].IsDefined())
|
||||||
|
//{
|
||||||
|
// AssetID prefabAssetID = node[PrefabID].as<AssetID>();
|
||||||
|
// YAML::Node prefabNode = YAML::Load(SHAssetManager::GetData<SHPrefabAsset>(prefabAssetID)->data);
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
//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);
|
||||||
|
@ -462,6 +471,44 @@ namespace SHADE
|
||||||
SHSystemManager::GetSystem<SHScriptEngine>()->DeserialiseScripts(eid, entityNode[ScriptsNode]);
|
SHSystemManager::GetSystem<SHScriptEngine>()->DeserialiseScripts(eid, entityNode[ScriptsNode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const YAML::Node& cnode(const YAML::Node& n) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
YAML::Node SHSerialization::MergeNodes(YAML::Node a, YAML::Node b)
|
||||||
|
{
|
||||||
|
if (!b.IsMap()) {
|
||||||
|
|
||||||
|
return b.IsNull() ? a : b;
|
||||||
|
}
|
||||||
|
if (!a.IsMap()) {
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
if (!b.size()) {
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto c = YAML::Node(YAML::NodeType::Map);
|
||||||
|
for (auto n : a) {
|
||||||
|
if (n.first.IsScalar()) {
|
||||||
|
const std::string& key = n.first.Scalar();
|
||||||
|
auto t = YAML::Node(cnode(b)[key]);
|
||||||
|
if (t) {
|
||||||
|
c[n.first] = MergeNodes(n.second, t);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c[n.first] = n.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto n : b) {
|
||||||
|
if (!n.first.IsScalar() || !cnode(c)[n.first.Scalar()]) {
|
||||||
|
c[n.first] = n.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace SHADE
|
||||||
private:
|
private:
|
||||||
//static void ResolveSerializedEntityID(YAML::Emitter& out, YAML::iterator& it, YAML::Node const& entityNode, CreatedEntitiesList const& createdEntities);
|
//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 YAML::Node MergeNodes(YAML::Node lhsNode, YAML::Node rhsNode);
|
||||||
static constexpr std::string_view NewSceneName = "New Scene";
|
static constexpr std::string_view NewSceneName = "New Scene";
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue