From 7e41b4d259ec0386275f90b4c6147981782dec2d Mon Sep 17 00:00:00 2001 From: Joey Pollack Date: Thu, 13 Oct 2022 14:58:31 -0400 Subject: [PATCH] Entity remove working --- src/run_modes/editor/editor.cpp | 6 ++ src/run_modes/editor/editor.h | 1 + src/run_modes/editor/panels/world_tree.cpp | 81 +++++++++++++++++++++- src/world/world.cpp | 19 +++++ src/world/world.h | 1 + 5 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/run_modes/editor/editor.cpp b/src/run_modes/editor/editor.cpp index 8be040e..2a01bdb 100644 --- a/src/run_modes/editor/editor.cpp +++ b/src/run_modes/editor/editor.cpp @@ -494,5 +494,11 @@ namespace editor if (mpMapEditor) mpMapEditor->ReloadTileSets(); } } + + + void Editor::OnEntityDelete(Entity* pEnt) + { + ((PropertiesView*)mPanelManager.GetPanel(mPanels.PropertiesView))->SetSelection((Entity*)nullptr); + } } } \ No newline at end of file diff --git a/src/run_modes/editor/editor.h b/src/run_modes/editor/editor.h index 29f7c81..6013644 100644 --- a/src/run_modes/editor/editor.h +++ b/src/run_modes/editor/editor.h @@ -61,6 +61,7 @@ namespace lunarium { namespace editor void OnAssetSelected(EditorAsset* pAsset); void OnNewAsset(EditorAsset* pAsset); void OnAssetUpdate(EditorAsset* pAsset); + void OnEntityDelete(Entity* pEnt); private: Editor(const Editor&) = delete; diff --git a/src/run_modes/editor/panels/world_tree.cpp b/src/run_modes/editor/panels/world_tree.cpp index 1470374..5c46983 100644 --- a/src/run_modes/editor/panels/world_tree.cpp +++ b/src/run_modes/editor/panels/world_tree.cpp @@ -87,8 +87,6 @@ namespace lunarium { namespace editor if (ImGui::TreeNode("World Root")) { // List all world entities - // This will fail if we end up implementing child entities - // In that case this needs to become recursive int idx = 0; for (auto iter = mpWorld->EntitiesBegin(); !mpWorld->EntitiesIsEnd(iter); iter++, idx++) { @@ -117,6 +115,35 @@ namespace lunarium { namespace editor bool was_right_clicked = false; if (ImGui::TreeNode(pEnt->GetName().c_str())) { + if (ImGui::BeginDragDropSource()) + { + // Need to pass a pointer to the payload data. This means we need to pass a + // pointer to the Entity pointer (Entity**) which &(*pEnt) becomes + ImGui::SetDragDropPayload("Entity", (void *)&(*pEnt), sizeof(Entity *)); + ImGui::Text("%s", pEnt->GetName().c_str()); + ImGui::EndDragDropSource(); + } + + + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("Entity")) + { + Entity* pDroppedEnt = *((Entity**) payload->Data); + + // Can't drop and entity on itself + if (pDroppedEnt != pEnt) + { + // If the dropped ent is the parent of pEnt then we need to swap the relationship + + // If the dropped ent is already a child of pEnt then we do nothing + + // Else add dropped ent as a child of pEnt + } + } + ImGui::EndDragDropTarget(); + } + was_clicked = ImGui::IsItemClicked(ImGuiMouseButton_Left); was_right_clicked = ImGui::IsItemClicked(ImGuiMouseButton_Right); @@ -166,6 +193,56 @@ namespace lunarium { namespace editor OpenPopup(PopUp::NEW_ENTITY).LogIfFailed(Editor::LogCat); } } + + if (mNewChild) + { + if (ImGui::Button("Delete Entity")) + { + // mParentEnt is the entity that was right-clicked on + // Lets give it a less confusing name for this context + Entity* ToRemove = mParentEnt; + + // Give the editor a chance to clean up any refs to this entity + mpEditor->OnEntityDelete(ToRemove); + + // If this entity has a parent we need to patch some relationships + bool has_parent = false; + LUUID parent_id = 0; + if (ToRemove->HasComponent()) + { + // These will be used to patch the children to the grandparent - now the parent + parent_id = ToRemove->GetComponent().Parent; + has_parent = true; + + // Tell the parent this child does not exist anymore + mpWorld->GetEntity(parent_id)->RemoveChild(ToRemove->GetUUID()); + } + + if (ToRemove->HasChildren()) + { + auto children = ToRemove->GetChildren(); + for (LUUID child : children) + { + // Clear the parent for each child + mpWorld->GetEntity(child)->ClearParent(); + + if (has_parent) + { + // Make the grandparent the new parent (if there is a grandparent) + mpWorld->GetEntity(parent_id)->AddChild(child); + } + } + } + + // Relationships are all patched so finally remove the entity + mpWorld->RemoveEntity(ToRemove->GetUUID()); + } + + if (ImGui::Button("Delete Hierarchy")) + { + + } + } ImGui::EndPopup(); } } diff --git a/src/world/world.cpp b/src/world/world.cpp index 2c9e245..f406b3b 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -151,6 +151,25 @@ namespace lunarium } + void World::RemoveEntity(LUUID id) + { + Entity* temp = mEntitiesByUUID[id]; + mEntitiesByUUID.erase(id); + + for (auto iter = mEntities.begin(); iter != mEntities.end(); iter++) + { + if ((*iter)->GetUUID() == id) + { + mEntities.erase(iter); + break; + } + } + + mECSRegistry.destroy(temp->GetEnttHandle()); + delete temp; + } + + Entity* World::GetEntity(LUUID id) { if (mEntitiesByUUID.find(id) == mEntitiesByUUID.end()) diff --git a/src/world/world.h b/src/world/world.h index ab35674..c6d4ac4 100644 --- a/src/world/world.h +++ b/src/world/world.h @@ -77,6 +77,7 @@ namespace lunarium entt::registry* GetEntityRegistry(); LUUID CreateEntity(); + void RemoveEntity(LUUID id); Entity* GetEntity(LUUID id); unsigned int GetNumEntities() const; std::vector::iterator EntitiesBegin();