Skip to content

Commit

Permalink
Update applyTemplate
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Oct 15, 2024
1 parent f204484 commit 0ae11ed
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 32 deletions.
30 changes: 3 additions & 27 deletions Projects/Editor/Source/Editor/Space/Assets/CTreeFSController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,38 +347,14 @@ namespace Skylicht

GUI::CTreeRowItem* row = node->getRowItem();
row->OnAcceptDragDrop = [node](GUI::SDragDropPackage* data)
{
if (data->Name == "HierarchyNode")
{
CHierachyNode* dragNode = (CHierachyNode*)data->UserData;
if (dragNode->isTagGameObject() &&
dragNode->getTagDataType() != CHierachyNode::Zone)
{
return true;
}
}
return false;
};
return false;
};

row->OnDrop = [node](GUI::SDragDropPackage* data, float mouseX, float mouseY)
{
if (data->Name == "HierarchyNode")
{
CHierachyNode* dragNode = (CHierachyNode*)data->UserData;
CGameObject* object = (CGameObject*)dragNode->getTagData();

std::string path = node->getTagString();
path += "/";
path += object->getNameA();
path += ".xml";

CSceneExporter::exportGameObject(object, path.c_str());

CAssetImporter importer;
importer.add(path.c_str());
importer.importAll();
}
};
};

GUI::SDragDropPackage* dragDrop = row->setDragDropPackage("TreeFSItem", row);
dragDrop->UserData = node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,31 @@ namespace Skylicht
obj->setTemplateID(id.c_str());
obj->setTemplateObjectID(obj->getID().c_str());

// sync template id to all childs
CContainerObject* container = dynamic_cast<CContainerObject*>(obj);
if (container)
{
std::stack<CContainerObject*> stack;
stack.push(container);

while (!stack.empty())
{
CContainerObject* container = stack.top();
stack.pop();

ArrayGameObject* childs = container->getChilds();
for (CGameObject* child : *childs)
{
child->setTemplateID(id.c_str());
child->setTemplateObjectID(child->getID().c_str());

CContainerObject* c = dynamic_cast<CContainerObject*>(obj);
if (c)
stack.push(c);
}
}
}

// save .template
CObjectSerializable* data = CSceneExporter::exportGameObject(obj);
data->save(fullPath.c_str());
Expand Down
9 changes: 9 additions & 0 deletions Projects/Skylicht/Engine/Components/CDependentComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ namespace Skylicht
return true;
}

bool CDependentComponent::isDependentComponent(const char* componentName)
{
std::map<std::string, std::vector<std::string>>::iterator it = m_dependent.find(componentName);
if (it != m_dependent.end())
return false;

return true;
}

void CDependentComponent::createDependentComponent(CComponentSystem* component)
{
std::map<std::string, std::vector<std::string>>::iterator it = m_dependent.find(component->getTypeName().c_str());
Expand Down
2 changes: 2 additions & 0 deletions Projects/Skylicht/Engine/Components/CDependentComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,7 @@ namespace Skylicht
bool registerDependent(const char* componentName, const char* dependentComponent);

void createDependentComponent(CComponentSystem* componentName);

bool isDependentComponent(const char* componentName);
};
}
37 changes: 37 additions & 0 deletions Projects/Skylicht/Engine/GameObject/CGameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,43 @@ namespace Skylicht
}
}

void CGameObject::sortComponent(std::vector<std::string>& templateOrder)
{
auto getOrder = [](const char* name, std::vector<std::string>& templateOrder)
{
int i = 0;
for (auto value : templateOrder)
{
if (value == name)
return i;
i++;
}
return 0;
};

int numComponent = (int)m_components.size();
for (int i = 0; i < numComponent - 1; i++)
{
for (int j = i + 1; j < numComponent; j++)
{
CComponentSystem* a = m_components[i];
CComponentSystem* b = m_components[j];

if (a && b && a->isSerializable() && b->isSerializable())
{
std::string nameA = a->getTypeName();
std::string nameB = b->getTypeName();

if (getOrder(nameA.c_str(), templateOrder) > getOrder(nameB.c_str(), templateOrder))
{
m_components[i] = b;
m_components[j] = a;
}
}
}
}
}

int CGameObject::getComponentPosition(CComponentSystem* comp)
{
int pos = 0;
Expand Down
7 changes: 7 additions & 0 deletions Projects/Skylicht/Engine/GameObject/CGameObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,11 @@ namespace Skylicht
return (int)m_components.size();
}

inline CComponentSystem* getComponentByPos(int i)
{
return m_components[i];
}

void moveComponentUp(CComponentSystem* comp);

void moveComponentDown(CComponentSystem* comp);
Expand All @@ -357,6 +362,8 @@ namespace Skylicht

void moveSerializableComponentDown(CComponentSystem* comp);

void sortComponent(std::vector<std::string>& templateOrder);

inline void enableEditorChange(bool b)
{
m_enableEditorChange = b;
Expand Down
79 changes: 74 additions & 5 deletions Projects/Skylicht/Engine/Scene/CSceneImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This file is part of the "Skylicht Engine".
#include "CSceneImporter.h"
#include "CSceneExporter.h"
#include "Utils/CStringImp.h"
#include "Components/CDependentComponent.h"

namespace Skylicht
{
Expand Down Expand Up @@ -252,11 +253,7 @@ namespace Skylicht

// use new id, that generated
if (g_generateId)
{
if (gameobject->isTemplateAsset())
gameobject->setTemplateObjectID(gameobject->getID().c_str());
gameobject->setID(id.c_str());
}
}
}
}
Expand Down Expand Up @@ -354,8 +351,80 @@ namespace Skylicht

void CSceneImporter::reloadTemplate(CGameObject* obj, CObjectSerializable* templateData)
{
CObjectSerializable* srcTemplate = obj->createSerializable();
if (obj->getTypeName() != templateData->Name)
return;

std::vector<std::string> componentOrder;
CDependentComponent* depComp = CDependentComponent::getInstance();

CObjectSerializable* components = templateData->getProperty<CObjectSerializable>("Components");
if (components)
{
// remove the components, hat is not exist in template
std::vector<CComponentSystem*> remove;
for (int i = 0, n = obj->getComponentCount(); i < n; i++)
{
CComponentSystem* comp = obj->getComponentByPos(i);
CObjectSerializable* compProperty = components->getProperty<CObjectSerializable>(comp->getTypeName().c_str());
if (compProperty == NULL)
{
if (!depComp->isDependentComponent(comp->getTypeName().c_str()))
remove.push_back(comp);
}
}

while (remove.size() > 0)
{
obj->removeComponent(remove[remove.size() - 1]);
remove.erase(--remove.end());
}

// add new components, that is not exist in gameobject
for (int i = 0, n = components->getNumProperty(); i < n; i++)
{
CValueProperty* p = components->getPropertyID(i);

const char* componentName = p->Name.c_str();
componentOrder.push_back(componentName);

if (p->getType() == Skylicht::Object)
{
if (obj->getComponentByTypeName(componentName) == NULL)
obj->addComponentByTypeName(componentName);
}

}
}
else
{
obj->releaseAllComponent();
}

// sync data
obj->sortComponent(componentOrder);

// get id generated
std::string id = obj->getID();

// load data
obj->loadSerializable(templateData);
obj->startComponent();

if (obj->isTemplateAsset())
obj->setTemplateObjectID(obj->getID().c_str());

// revert id
obj->setID(id.c_str());

// sync in childs object
CContainerObject* container = dynamic_cast<CContainerObject*>(obj);
if (container)
{
CObjectSerializable* childs = templateData->getProperty<CObjectSerializable>("Childs");
if (childs)
{
// ... not yet
}
}
}
}

0 comments on commit 0ae11ed

Please sign in to comment.