Editor entity import, save, delete, component attach, component delete.
This commit is contained in:
@@ -29,12 +29,14 @@ public:
|
|||||||
typedef std::function<void(EntityWrapper)> OnEntitySelectedCallback_t;
|
typedef std::function<void(EntityWrapper)> OnEntitySelectedCallback_t;
|
||||||
void SetEntitySelectedCallback(OnEntitySelectedCallback_t f) { m_OnEntitySelected = f; }
|
void SetEntitySelectedCallback(OnEntitySelectedCallback_t f) { m_OnEntitySelected = f; }
|
||||||
// Called when the user means to import an entity file.
|
// Called when the user means to import an entity file.
|
||||||
// Expects an EntityWrapper of the newly created entity in return.
|
// @param EntityWrapper The entity to parent the imported entity to. The entity will be imported into the world of this entity.
|
||||||
typedef std::function<EntityWrapper(boost::filesystem::path)> OnEntityImport_t;
|
// @param boost::filesystem::path The path to the entity to import
|
||||||
|
// @return EntityWrapper The newly created entity
|
||||||
|
typedef std::function<EntityWrapper(EntityWrapper, boost::filesystem::path)> OnEntityImport_t;
|
||||||
void SetEntityImportCallback(OnEntityImport_t f) { m_OnEntityImport = f; }
|
void SetEntityImportCallback(OnEntityImport_t f) { m_OnEntityImport = f; }
|
||||||
// Called when the user means to save an entity to file.
|
// Called when the user means to save an entity to file.
|
||||||
// Expects a bool indicating whether the save was successful or not in return.
|
// Permitted to throw exceptions on save failure.
|
||||||
typedef std::function<bool(EntityWrapper, boost::filesystem::path)> OnEntitySave_t;
|
typedef std::function<void(EntityWrapper, boost::filesystem::path)> OnEntitySave_t;
|
||||||
void SetEntitySaveCallback(OnEntitySave_t f) { m_OnEntitySave = f; }
|
void SetEntitySaveCallback(OnEntitySave_t f) { m_OnEntitySave = f; }
|
||||||
// Called when the user means to create a new entity.
|
// Called when the user means to create a new entity.
|
||||||
// @param EntityWrapper The parent of the entity to be created
|
// @param EntityWrapper The parent of the entity to be created
|
||||||
@@ -47,13 +49,20 @@ public:
|
|||||||
// Called when the user means to attach a new component to an entity.
|
// Called when the user means to attach a new component to an entity.
|
||||||
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentAttach_t;
|
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentAttach_t;
|
||||||
void SetComponentAttachCallback(OnComponentAttach_t f) { m_OnComponentAttach = f; }
|
void SetComponentAttachCallback(OnComponentAttach_t f) { m_OnComponentAttach = f; }
|
||||||
|
// Called when the user means to delete a component off an entity.
|
||||||
|
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentDelete_t;
|
||||||
|
void SetComponentDeleteCallback(OnComponentDelete_t f) { m_OnComponentDelete = f; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
|
// Config variables
|
||||||
|
const boost::filesystem::path m_DefaultEntityPath = boost::filesystem::path("Schema") / boost::filesystem::path("Entities");
|
||||||
|
|
||||||
// State variables
|
// State variables
|
||||||
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
||||||
|
std::unordered_map<EntityWrapper, boost::filesystem::path> m_EntityFiles;
|
||||||
|
std::string m_LastErrorMessage;
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
|
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
|
||||||
@@ -62,7 +71,17 @@ private:
|
|||||||
OnEntityCreate_t m_OnEntityCreate = nullptr;
|
OnEntityCreate_t m_OnEntityCreate = nullptr;
|
||||||
OnEntityDelete_t m_OnEntityDelete = nullptr;
|
OnEntityDelete_t m_OnEntityDelete = nullptr;
|
||||||
OnComponentAttach_t m_OnComponentAttach = nullptr;
|
OnComponentAttach_t m_OnComponentAttach = nullptr;
|
||||||
|
OnComponentDelete_t m_OnComponentDelete = nullptr;
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
boost::filesystem::path fileOpenDialog();
|
||||||
|
boost::filesystem::path fileSaveDialog();
|
||||||
|
|
||||||
|
// Entity file handling methods
|
||||||
|
void entityImport(World* world);
|
||||||
|
void entitySave(EntityWrapper entity);
|
||||||
|
|
||||||
|
// UI drawing methods
|
||||||
void drawMenu();
|
void drawMenu();
|
||||||
void drawEntities(World* world);
|
void drawEntities(World* world);
|
||||||
void drawEntitiesRecursive(World* world, EntityID parent);
|
void drawEntitiesRecursive(World* world, EntityID parent);
|
||||||
@@ -78,6 +97,10 @@ private:
|
|||||||
void drawComponentField_double(ComponentWrapper &c, const ComponentInfo::Field_t &field);
|
void drawComponentField_double(ComponentWrapper &c, const ComponentInfo::Field_t &field);
|
||||||
void drawComponentField_bool(ComponentWrapper &c, const ComponentInfo::Field_t &field);
|
void drawComponentField_bool(ComponentWrapper &c, const ComponentInfo::Field_t &field);
|
||||||
void drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field);
|
void drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field);
|
||||||
|
void drawModals();
|
||||||
|
|
||||||
|
// Custom UI elements
|
||||||
|
bool createDeleteButton(const std::string& componentType);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "../Core/ResourceManager.h"
|
#include "../Core/ResourceManager.h"
|
||||||
#include "../Core/EntityFilePreprocessor.h"
|
#include "../Core/EntityFilePreprocessor.h"
|
||||||
#include "../Core/EntityFileParser.h"
|
#include "../Core/EntityFileParser.h"
|
||||||
|
#include "../Core/EntityFileWriter.h"
|
||||||
#include "EditorGUI.h"
|
#include "EditorGUI.h"
|
||||||
#include "EditorStats.h"
|
#include "EditorStats.h"
|
||||||
|
|
||||||
@@ -31,5 +32,12 @@ private:
|
|||||||
EditorGUI* m_EditorGUI;
|
EditorGUI* m_EditorGUI;
|
||||||
EditorStats* m_EditorStats;
|
EditorStats* m_EditorStats;
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath);
|
||||||
|
|
||||||
|
// GUI callbacks
|
||||||
void OnEntitySelected(EntityWrapper entity);
|
void OnEntitySelected(EntityWrapper entity);
|
||||||
|
void OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath);
|
||||||
|
void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
|
||||||
|
void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
|
||||||
};
|
};
|
||||||
+143
-17
@@ -28,9 +28,16 @@ void EditorGUI::drawEntities(World* world)
|
|||||||
}
|
}
|
||||||
|
|
||||||
float buttonWidth = (ImGui::GetContentRegionAvailWidth() - 10.f) / 3.f ;
|
float buttonWidth = (ImGui::GetContentRegionAvailWidth() - 10.f) / 3.f ;
|
||||||
ImGui::Button("Create", ImVec2(buttonWidth, 0));
|
if (ImGui::Button("Create", ImVec2(buttonWidth, 0))) {
|
||||||
|
if (m_OnEntityCreate != nullptr) {
|
||||||
|
EntityWrapper newEntity = m_OnEntityCreate(EntityWrapper(world, EntityID_Invalid));
|
||||||
|
SelectEntity(newEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::SameLine(0.f, 5.f);
|
ImGui::SameLine(0.f, 5.f);
|
||||||
ImGui::Button("Import", ImVec2(buttonWidth, 0));
|
if (ImGui::Button("Import", ImVec2(buttonWidth, 0))) {
|
||||||
|
entityImport(world);
|
||||||
|
}
|
||||||
ImGui::SameLine(0.f, 5.f);
|
ImGui::SameLine(0.f, 5.f);
|
||||||
ImGui::Button("Reference", ImVec2(buttonWidth, 0));
|
ImGui::Button("Reference", ImVec2(buttonWidth, 0));
|
||||||
|
|
||||||
@@ -38,6 +45,8 @@ void EditorGUI::drawEntities(World* world)
|
|||||||
|
|
||||||
drawEntitiesRecursive(world, EntityID_Invalid);
|
drawEntitiesRecursive(world, EntityID_Invalid);
|
||||||
|
|
||||||
|
// Draw any potential modals before ending this scope
|
||||||
|
drawModals();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,28 +92,29 @@ bool EditorGUI::drawEntityNode(EntityWrapper entity)
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once);
|
// Compose title
|
||||||
std::string nodeTitle;
|
std::stringstream nodeTitle;
|
||||||
const std::string& entityName = entity.World->GetName(entity);
|
const std::string& entityName = entity.World->GetName(entity);
|
||||||
if (!entityName.empty()) {
|
if (!entityName.empty()) {
|
||||||
nodeTitle = entityName;
|
nodeTitle << entityName;
|
||||||
} else {
|
} else {
|
||||||
nodeTitle = std::string("#") + std::to_string(entity.ID);
|
nodeTitle << "#" << entity.ID;
|
||||||
}
|
}
|
||||||
if (ImGui::TreeNode(nodeTitle.c_str())) {
|
if (m_EntityFiles.count(entity) == 1) {
|
||||||
|
nodeTitle << " (" << m_EntityFiles.at(entity).filename().string() << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once);
|
||||||
|
if (ImGui::TreeNode(nodeTitle.str().c_str())) {
|
||||||
//if (m_UIDraggingEntity != EntityID_Invalid && ImGui::IsItemHoveredRect() && ImGui::IsMouseReleased(0)) {
|
//if (m_UIDraggingEntity != EntityID_Invalid && ImGui::IsItemHoveredRect() && ImGui::IsMouseReleased(0)) {
|
||||||
// LOG_DEBUG("Changed parent of %i to %i", m_UIDraggingEntity, entity);
|
// LOG_DEBUG("Changed parent of %i to %i", m_UIDraggingEntity, entity);
|
||||||
// changeParent(m_UIDraggingEntity, entity);
|
// changeParent(m_UIDraggingEntity, entity);
|
||||||
// m_UIDraggingEntity = EntityID_Invalid;
|
// m_UIDraggingEntity = EntityID_Invalid;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (ImGui::BeginPopupContextItem("item context menu")) {
|
if (ImGui::BeginPopupContextItem("entity context menu")) {
|
||||||
if (ImGui::Button("Add")) {
|
if (ImGui::Button("Save")) {
|
||||||
if (m_OnEntityCreate != nullptr) {
|
entitySave(entity);
|
||||||
EntityWrapper newEntity = m_OnEntityCreate(EntityWrapper(entity.World, EntityID_Invalid));
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
SelectEntity(newEntity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Delete")) {
|
if (ImGui::Button("Delete")) {
|
||||||
@@ -116,6 +126,7 @@ bool EditorGUI::drawEntityNode(EntityWrapper entity)
|
|||||||
SelectEntity(EntityWrapper::Invalid);
|
SelectEntity(EntityWrapper::Invalid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
drawModals();
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -170,14 +181,21 @@ void EditorGUI::drawComponents(EntityWrapper entity)
|
|||||||
if (!entity.HasComponent(componentType)) {
|
if (!entity.HasComponent(componentType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO: Add delete button here
|
// Handle deletion with early out
|
||||||
drawComponent(entity, pool->ComponentInfo());
|
if (createDeleteButton(componentType)) {
|
||||||
|
if (m_OnComponentDelete != nullptr) {
|
||||||
|
m_OnComponentDelete(entity, componentType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Draw the actual component node
|
||||||
|
drawComponentNode(entity, pool->ComponentInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditorGUI::drawComponent(EntityWrapper entity, const ComponentInfo& ci)
|
bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci)
|
||||||
{
|
{
|
||||||
if (!ImGui::CollapsingHeader(ci.Name.c_str(), nullptr, true, true)) {
|
if (!ImGui::CollapsingHeader(ci.Name.c_str(), nullptr, true, true)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -330,3 +348,111 @@ void EditorGUI::drawComponentField_string(ComponentWrapper &c, const ComponentIn
|
|||||||
// TODO: Handle drag and drop of files
|
// TODO: Handle drag and drop of files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorGUI::drawModals()
|
||||||
|
{
|
||||||
|
if (ImGui::BeginPopupModal("Import failed", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::Text("Entity import failed. Check console for more information.\n\n");
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetContentRegionAvailWidth() - 120);
|
||||||
|
if (ImGui::Button("OK", ImVec2(120, 0))) {
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupModal("Save failed", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::Text("Entity save failed on an exception.\nMessage: %s\n\n", m_LastErrorMessage.c_str());
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetContentRegionAvailWidth() - 120);
|
||||||
|
if (ImGui::Button("OK", ImVec2(120, 0))) {
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorGUI::createDeleteButton(const std::string& componentType)
|
||||||
|
{
|
||||||
|
float width = ImGui::GetContentRegionAvailWidth();
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
auto pos = ImGui::GetCursorScreenPos() + ImVec2(width - 14.f, 1);
|
||||||
|
ImRect bb = ImRect(pos, pos + ImVec2(14.f, 14.f));
|
||||||
|
std::string idString = "#DELETE";
|
||||||
|
idString += componentType;
|
||||||
|
ImGuiID id = window->GetID(idString.c_str());
|
||||||
|
bool hovered;
|
||||||
|
bool held;
|
||||||
|
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held);
|
||||||
|
//ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton);
|
||||||
|
ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||||
|
window->DrawList->AddCircleFilled(bb.GetCenter(), 7.f, col, 16);
|
||||||
|
return pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::filesystem::path EditorGUI::fileOpenDialog()
|
||||||
|
{
|
||||||
|
namespace bfs = boost::filesystem;
|
||||||
|
nfdchar_t* outPath = nullptr;
|
||||||
|
nfdresult_t result = NFD_OpenDialog("xml", bfs::absolute(m_DefaultEntityPath).string().c_str(), &outPath);
|
||||||
|
|
||||||
|
if (result == NFD_ERROR) {
|
||||||
|
LOG_ERROR("NFD Error: %s", NFD_GetError());
|
||||||
|
return bfs::path();
|
||||||
|
} else if (result == NFD_CANCEL) {
|
||||||
|
return bfs::path();
|
||||||
|
} else {
|
||||||
|
return bfs::absolute(outPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::filesystem::path EditorGUI::fileSaveDialog()
|
||||||
|
{
|
||||||
|
namespace bfs = boost::filesystem;
|
||||||
|
nfdchar_t* outPath = nullptr;
|
||||||
|
nfdresult_t result = NFD_SaveDialog("xml", bfs::absolute(m_DefaultEntityPath).string().c_str(), &outPath);
|
||||||
|
|
||||||
|
if (result == NFD_ERROR) {
|
||||||
|
LOG_ERROR("NFD Error: %s", NFD_GetError());
|
||||||
|
return bfs::path();
|
||||||
|
} else if (result == NFD_CANCEL) {
|
||||||
|
return bfs::path();
|
||||||
|
} else {
|
||||||
|
return bfs::absolute(outPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorGUI::entityImport(World* world)
|
||||||
|
{
|
||||||
|
boost::filesystem::path filePath = fileOpenDialog();
|
||||||
|
if (filePath.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper entity = m_OnEntityImport(EntityWrapper(world, EntityID_Invalid), filePath);
|
||||||
|
if (entity.Valid()) {
|
||||||
|
m_EntityFiles[entity] = filePath;
|
||||||
|
SelectEntity(entity);
|
||||||
|
} else {
|
||||||
|
ImGui::OpenPopup("Import failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorGUI::entitySave(EntityWrapper entity)
|
||||||
|
{
|
||||||
|
boost::filesystem::path filePath;
|
||||||
|
if (m_EntityFiles.count(entity) == 1) {
|
||||||
|
filePath = m_EntityFiles.at(entity);
|
||||||
|
} else {
|
||||||
|
filePath = fileSaveDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePath.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_OnEntitySave(entity, filePath);
|
||||||
|
m_EntityFiles[entity] = filePath;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
m_LastErrorMessage = e.what();
|
||||||
|
ImGui::OpenPopup("Save failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,12 +12,7 @@ EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer, Render
|
|||||||
m_EditorWorldSystemPipeline->AddSystem<UniformScaleSystem>(0);
|
m_EditorWorldSystemPipeline->AddSystem<UniformScaleSystem>(0);
|
||||||
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
||||||
|
|
||||||
auto widgetEntityFile = ResourceManager::Load<EntityFile>("Schema/Entities/EditorWidget.xml");
|
m_Widget = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/EditorWidget.xml");
|
||||||
EntityFilePreprocessor fpp(widgetEntityFile);
|
|
||||||
fpp.RegisterComponents(m_EditorWorld);
|
|
||||||
EntityFileParser fp(widgetEntityFile);
|
|
||||||
EntityID widgetID = fp.MergeEntities(m_EditorWorld);
|
|
||||||
m_Widget = EntityWrapper(m_EditorWorld, widgetID);
|
|
||||||
|
|
||||||
m_Camera = EntityWrapper(m_EditorWorld, m_EditorWorld->CreateEntity());
|
m_Camera = EntityWrapper(m_EditorWorld, m_EditorWorld->CreateEntity());
|
||||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
|
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
|
||||||
@@ -26,6 +21,10 @@ EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer, Render
|
|||||||
|
|
||||||
m_EditorGUI = new EditorGUI(m_EventBroker);
|
m_EditorGUI = new EditorGUI(m_EventBroker);
|
||||||
m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1));
|
m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1));
|
||||||
|
m_EditorGUI->SetEntityImportCallback(std::bind(&EditorSystem::importEntity, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
m_EditorGUI->SetEntitySaveCallback(std::bind(&EditorSystem::OnEntitySave, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
|
||||||
m_EditorStats = new EditorStats();
|
m_EditorStats = new EditorStats();
|
||||||
|
|
||||||
@@ -59,3 +58,38 @@ void EditorSystem::OnEntitySelected(EntityWrapper entity)
|
|||||||
{
|
{
|
||||||
m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(entity.World, entity.ID);
|
m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(entity.World, entity.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath)
|
||||||
|
{
|
||||||
|
EntityFileWriter writer(filePath);
|
||||||
|
writer.WriteEntity(entity.World, entity.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSystem::OnComponentAttach(EntityWrapper entity, const std::string& componentType)
|
||||||
|
{
|
||||||
|
entity.World->AttachComponent(entity.ID, componentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSystem::OnComponentDelete(EntityWrapper entity, const std::string& componentType)
|
||||||
|
{
|
||||||
|
entity.World->DeleteComponent(entity.ID, componentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath)
|
||||||
|
{
|
||||||
|
if (parent.World == nullptr) {
|
||||||
|
LOG_ERROR("Tried to import entity \"%s\" into null world!", filePath.string().c_str());
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto entityFile = ResourceManager::Load<EntityFile>(filePath.string());
|
||||||
|
EntityFilePreprocessor fpp(entityFile);
|
||||||
|
fpp.RegisterComponents(parent.World);
|
||||||
|
EntityFileParser fp(entityFile);
|
||||||
|
EntityID newEntity = fp.MergeEntities(parent.World, parent.ID);
|
||||||
|
return EntityWrapper(parent.World, newEntity);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user