From a40544344b817a1bf707155f191ce9cc696f68a6 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Fri, 20 Mar 2026 17:28:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84ui=5Feditor=EF=BC=9A=E5=90=91?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E6=A0=B8=E5=BF=83=E7=B1=BB=E5=9E=8B=E5=AF=B9?= =?UTF-8?q?=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除UI::Event,使用XCEngine::Core::Event替代 - GameObject.h重构,Component添加friend class Entity - LogEntry使用XCEngine::Debug::LogLevel - SceneManager/SelectionManager使用XCEngine::Core::Event - LogSystem使用XCEngine::Debug::LogLevel - CMakeLists.txt添加engine/include路径 --- ui_editor/CMakeLists.txt | 1 + ui_editor/src/Core/Event.h | 48 ----------------------- ui_editor/src/Core/GameObject.h | 40 ++++++++++++++++--- ui_editor/src/Core/LogEntry.h | 7 ++-- ui_editor/src/Managers/LogSystem.cpp | 2 +- ui_editor/src/Managers/LogSystem.h | 4 +- ui_editor/src/Managers/SceneManager.cpp | 13 +++--- ui_editor/src/Managers/SceneManager.h | 17 ++++---- ui_editor/src/Managers/SelectionManager.h | 11 +++--- ui_editor/src/panels/ConsolePanel.cpp | 22 +++++------ ui_editor/src/panels/HierarchyPanel.cpp | 32 +++++++-------- ui_editor/src/panels/HierarchyPanel.h | 7 ++-- ui_editor/src/panels/InspectorPanel.h | 3 +- 13 files changed, 96 insertions(+), 111 deletions(-) delete mode 100644 ui_editor/src/Core/Event.h diff --git a/ui_editor/CMakeLists.txt b/ui_editor/CMakeLists.txt index 4fdcecdb..7d8a90aa 100644 --- a/ui_editor/CMakeLists.txt +++ b/ui_editor/CMakeLists.txt @@ -50,6 +50,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends + ${CMAKE_CURRENT_SOURCE_DIR}/../engine/include ) target_compile_definitions(${PROJECT_NAME} PRIVATE UNICODE _UNICODE) diff --git a/ui_editor/src/Core/Event.h b/ui_editor/src/Core/Event.h deleted file mode 100644 index 2ab193b5..00000000 --- a/ui_editor/src/Core/Event.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace UI { - -template -class Event { -public: - using HandlerID = size_t; - using Handler = std::function; - - HandlerID Subscribe(Handler handler) { - HandlerID id = m_nextId++; - m_handlers.emplace_back(id, std::move(handler)); - return id; - } - - void Unsubscribe(HandlerID id) { - m_handlers.erase( - std::remove_if(m_handlers.begin(), m_handlers.end(), - [id](const auto& pair) { return pair.first == id; }), - m_handlers.end() - ); - } - - void Invoke(Args... args) { - for (const auto& pair : m_handlers) { - pair.second(args...); - } - } - - void operator()(Args... args) { - Invoke(args...); - } - - void Clear() { - m_handlers.clear(); - } - -private: - HandlerID m_nextId = 0; - std::vector> m_handlers; -}; - -} \ No newline at end of file diff --git a/ui_editor/src/Core/GameObject.h b/ui_editor/src/Core/GameObject.h index f376a040..064b3c9d 100644 --- a/ui_editor/src/Core/GameObject.h +++ b/ui_editor/src/Core/GameObject.h @@ -7,15 +7,32 @@ #include #include +#include + namespace UI { using EntityID = uint64_t; -constexpr EntityID INVALID_ENTITY = 0; +constexpr EntityID INVALID_ENTITY_ID = 0; class Component { public: virtual ~Component() = default; virtual std::string GetName() const = 0; + + virtual void Awake() {} + virtual void Start() {} + virtual void Update(float deltaTime) {} + virtual void OnDestroy() {} + + class Entity* GetEntity() const { return m_entity; } + bool IsEnabled() const { return m_enabled; } + void SetEnabled(bool enabled) { m_enabled = enabled; } + +protected: + class Entity* m_entity = nullptr; + bool m_enabled = true; + + friend class Entity; }; class TransformComponent : public Component { @@ -35,10 +52,11 @@ public: std::string GetName() const override { return "Mesh Renderer"; } }; -struct Entity { - EntityID id = INVALID_ENTITY; +class Entity { +public: + EntityID id = INVALID_ENTITY_ID; std::string name; - EntityID parent = INVALID_ENTITY; + EntityID parent = INVALID_ENTITY_ID; std::vector children; std::vector> components; bool selected = false; @@ -46,6 +64,7 @@ struct Entity { template T* AddComponent(Args&&... args) { auto comp = std::make_unique(std::forward(args)...); + comp->m_entity = this; T* ptr = comp.get(); components.push_back(std::move(comp)); return ptr; @@ -60,6 +79,17 @@ struct Entity { } return nullptr; } + + template + std::vector GetComponents() { + std::vector result; + for (auto& comp : components) { + if (auto casted = dynamic_cast(comp.get())) { + result.push_back(casted); + } + } + return result; + } }; using ComponentInspectorFn = std::function; @@ -98,4 +128,4 @@ private: std::unordered_map()>> m_factories; }; -} \ No newline at end of file +} diff --git a/ui_editor/src/Core/LogEntry.h b/ui_editor/src/Core/LogEntry.h index e4218f09..4f8e847a 100644 --- a/ui_editor/src/Core/LogEntry.h +++ b/ui_editor/src/Core/LogEntry.h @@ -2,12 +2,13 @@ #include +#include + namespace UI { struct LogEntry { - enum class Level { Info, Warning, Error }; - Level level; + XCEngine::Debug::LogLevel level; std::string message; }; -} \ No newline at end of file +} diff --git a/ui_editor/src/Managers/LogSystem.cpp b/ui_editor/src/Managers/LogSystem.cpp index a0e06dcc..3a757c1f 100644 --- a/ui_editor/src/Managers/LogSystem.cpp +++ b/ui_editor/src/Managers/LogSystem.cpp @@ -7,7 +7,7 @@ LogSystem& LogSystem::Get() { return instance; } -void LogSystem::AddLog(LogEntry::Level level, const std::string& message) { +void LogSystem::AddLog(XCEngine::Debug::LogLevel level, const std::string& message) { m_logs.push_back({level, message}); if (m_callback) m_callback(); } diff --git a/ui_editor/src/Managers/LogSystem.h b/ui_editor/src/Managers/LogSystem.h index b480e907..966cd85c 100644 --- a/ui_editor/src/Managers/LogSystem.h +++ b/ui_editor/src/Managers/LogSystem.h @@ -10,7 +10,7 @@ class LogSystem { public: static LogSystem& Get(); - void AddLog(LogEntry::Level level, const std::string& message); + void AddLog(XCEngine::Debug::LogLevel level, const std::string& message); void Clear(); const std::vector& GetLogs() const { return m_logs; } @@ -23,4 +23,4 @@ private: std::function m_callback; }; -} \ No newline at end of file +} diff --git a/ui_editor/src/Managers/SceneManager.cpp b/ui_editor/src/Managers/SceneManager.cpp index ba9d419d..9cd480d5 100644 --- a/ui_editor/src/Managers/SceneManager.cpp +++ b/ui_editor/src/Managers/SceneManager.cpp @@ -1,4 +1,5 @@ #include "SceneManager.h" +#include "SelectionManager.h" #include namespace UI { @@ -11,7 +12,7 @@ EntityID SceneManager::CreateEntity(const std::string& name, EntityID parent) { entity.parent = parent; m_entities[id] = std::move(entity); - if (parent != INVALID_ENTITY) { + if (parent != INVALID_ENTITY_ID) { m_entities[parent].children.push_back(id); } else { m_rootEntities.push_back(id); @@ -32,7 +33,7 @@ void SceneManager::DeleteEntity(EntityID id) { DeleteEntity(childId); } - if (entity.parent != INVALID_ENTITY) { + if (entity.parent != INVALID_ENTITY_ID) { auto* parent = GetEntity(entity.parent); if (parent) { auto& siblings = parent->children; @@ -118,14 +119,14 @@ EntityID SceneManager::PasteEntityRecursive(const ClipboardData& data, EntityID } EntityID SceneManager::PasteEntity(EntityID parent) { - if (!m_clipboard) return INVALID_ENTITY; + if (!m_clipboard) return INVALID_ENTITY_ID; return PasteEntityRecursive(*m_clipboard, parent); } EntityID SceneManager::DuplicateEntity(EntityID id) { CopyEntity(id); const Entity* entity = GetEntity(id); - if (!entity) return INVALID_ENTITY; + if (!entity) return INVALID_ENTITY_ID; return PasteEntity(entity->parent); } @@ -133,7 +134,7 @@ void SceneManager::MoveEntity(EntityID id, EntityID newParent) { Entity* entity = GetEntity(id); if (!entity || id == newParent) return; - if (entity->parent != INVALID_ENTITY) { + if (entity->parent != INVALID_ENTITY_ID) { Entity* oldParent = GetEntity(entity->parent); if (oldParent) { auto& siblings = oldParent->children; @@ -145,7 +146,7 @@ void SceneManager::MoveEntity(EntityID id, EntityID newParent) { entity->parent = newParent; - if (newParent != INVALID_ENTITY) { + if (newParent != INVALID_ENTITY_ID) { Entity* newParentEntity = GetEntity(newParent); if (newParentEntity) { newParentEntity->children.push_back(id); diff --git a/ui_editor/src/Managers/SceneManager.h b/ui_editor/src/Managers/SceneManager.h index 49986e59..d76a067b 100644 --- a/ui_editor/src/Managers/SceneManager.h +++ b/ui_editor/src/Managers/SceneManager.h @@ -1,12 +1,13 @@ #pragma once #include "Core/GameObject.h" -#include "SelectionManager.h" #include #include #include #include +#include + namespace UI { struct ClipboardData { @@ -22,7 +23,7 @@ public: return instance; } - EntityID CreateEntity(const std::string& name, EntityID parent = INVALID_ENTITY); + EntityID CreateEntity(const std::string& name, EntityID parent = INVALID_ENTITY_ID); Entity* GetEntity(EntityID id) { auto it = m_entities.find(id); @@ -56,7 +57,7 @@ public: void CopyEntity(EntityID id); - EntityID PasteEntity(EntityID parent = INVALID_ENTITY); + EntityID PasteEntity(EntityID parent = INVALID_ENTITY_ID); EntityID DuplicateEntity(EntityID id); @@ -66,10 +67,10 @@ public: bool HasClipboardData() const { return m_clipboard.has_value(); } - Event OnEntityCreated; - Event OnEntityDeleted; - Event OnEntityChanged; - Event<> OnSceneChanged; + XCEngine::Core::Event OnEntityCreated; + XCEngine::Core::Event OnEntityDeleted; + XCEngine::Core::Event OnEntityChanged; + XCEngine::Core::Event<> OnSceneChanged; private: SceneManager() = default; @@ -83,4 +84,4 @@ private: std::optional m_clipboard; }; -} \ No newline at end of file +} diff --git a/ui_editor/src/Managers/SelectionManager.h b/ui_editor/src/Managers/SelectionManager.h index fe17e7b0..07ccf805 100644 --- a/ui_editor/src/Managers/SelectionManager.h +++ b/ui_editor/src/Managers/SelectionManager.h @@ -1,9 +1,10 @@ #pragma once #include "Core/GameObject.h" -#include "Core/Event.h" #include +#include + namespace UI { class SelectionManager { @@ -21,18 +22,18 @@ public: } void ClearSelection() { - SetSelectedEntity(INVALID_ENTITY); + SetSelectedEntity(INVALID_ENTITY_ID); } bool IsSelected(EntityID id) const { return m_selectedEntity == id; } - Event OnSelectionChanged; + XCEngine::Core::Event OnSelectionChanged; private: SelectionManager() = default; - EntityID m_selectedEntity = INVALID_ENTITY; + EntityID m_selectedEntity = INVALID_ENTITY_ID; }; -} \ No newline at end of file +} diff --git a/ui_editor/src/panels/ConsolePanel.cpp b/ui_editor/src/panels/ConsolePanel.cpp index f7df0193..124a46f9 100644 --- a/ui_editor/src/panels/ConsolePanel.cpp +++ b/ui_editor/src/panels/ConsolePanel.cpp @@ -6,11 +6,11 @@ namespace UI { ConsolePanel::ConsolePanel() : Panel("Console") { - LogSystem::Get().AddLog(LogEntry::Level::Info, "Engine initialized successfully"); - LogSystem::Get().AddLog(LogEntry::Level::Info, "Loading default scene..."); - LogSystem::Get().AddLog(LogEntry::Level::Warning, "Missing material on object 'Cube'"); - LogSystem::Get().AddLog(LogEntry::Level::Error, "Failed to load texture: 'Assets/Textures/missing.png'"); - LogSystem::Get().AddLog(LogEntry::Level::Info, "Scene loaded successfully"); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Engine initialized successfully"); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Loading default scene..."); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Warning, "Missing material on object 'Cube'"); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Error, "Failed to load texture: 'Assets/Textures/missing.png'"); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Scene loaded successfully"); } void ConsolePanel::Render() { @@ -21,15 +21,15 @@ void ConsolePanel::Render() { } ImGui::SameLine(); if (ImGui::Button("Info")) { - LogSystem::Get().AddLog(LogEntry::Level::Info, "Test info message"); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Test info message"); } ImGui::SameLine(); if (ImGui::Button("Warn")) { - LogSystem::Get().AddLog(LogEntry::Level::Warning, "Test warning message"); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Warning, "Test warning message"); } ImGui::SameLine(); if (ImGui::Button("Error")) { - LogSystem::Get().AddLog(LogEntry::Level::Error, "Test error message"); + LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Error, "Test error message"); } ImGui::Separator(); @@ -41,15 +41,15 @@ void ConsolePanel::Render() { const char* prefix; switch (log.level) { - case LogEntry::Level::Info: + case XCEngine::Debug::LogLevel::Info: color = ImVec4(0.7f, 0.7f, 0.7f, 1.0f); prefix = "[Info] "; break; - case LogEntry::Level::Warning: + case XCEngine::Debug::LogLevel::Warning: color = ImVec4(1.0f, 0.8f, 0.0f, 1.0f); prefix = "[Warn] "; break; - case LogEntry::Level::Error: + case XCEngine::Debug::LogLevel::Error: color = ImVec4(1.0f, 0.3f, 0.3f, 1.0f); prefix = "[Error]"; break; diff --git a/ui_editor/src/panels/HierarchyPanel.cpp b/ui_editor/src/panels/HierarchyPanel.cpp index 1be32dcc..e3bb8f80 100644 --- a/ui_editor/src/panels/HierarchyPanel.cpp +++ b/ui_editor/src/panels/HierarchyPanel.cpp @@ -41,7 +41,7 @@ void HierarchyPanel::Render() { } if (ImGui::BeginPopupContextWindow("HierarchyContextMenu", ImGuiPopupFlags_MouseButtonRight)) { - RenderCreateMenu(INVALID_ENTITY); + RenderCreateMenu(INVALID_ENTITY_ID); ImGui::EndPopup(); } @@ -49,10 +49,10 @@ void HierarchyPanel::Render() { if (ImGui::BeginDragDropTarget()) { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY_ID")) { EntityID sourceId = *(const EntityID*)payload->Data; - if (sourceId != INVALID_ENTITY) { + if (sourceId != INVALID_ENTITY_ID) { const Entity* sourceEntity = SceneManager::Get().GetEntity(sourceId); - if (sourceEntity && sourceEntity->parent != INVALID_ENTITY) { - SceneManager::Get().MoveEntity(sourceId, INVALID_ENTITY); + if (sourceEntity && sourceEntity->parent != INVALID_ENTITY_ID) { + SceneManager::Get().MoveEntity(sourceId, INVALID_ENTITY_ID); } } } @@ -102,7 +102,7 @@ void HierarchyPanel::RenderEntity(EntityID id, const std::string& filter) { sceneManager.RenameEntity(id, m_renameBuffer); } m_renaming = false; - m_renamingEntity = INVALID_ENTITY; + m_renamingEntity = INVALID_ENTITY_ID; } if (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)) { @@ -110,7 +110,7 @@ void HierarchyPanel::RenderEntity(EntityID id, const std::string& filter) { sceneManager.RenameEntity(id, m_renameBuffer); } m_renaming = false; - m_renamingEntity = INVALID_ENTITY; + m_renamingEntity = INVALID_ENTITY_ID; } } else { bool isOpen = ImGui::TreeNodeEx(entity->name.c_str(), flags); @@ -181,7 +181,7 @@ void HierarchyPanel::RenderContextMenu(EntityID id) { if (ImGui::MenuItem("Duplicate", "Ctrl+D")) { EntityID newId = sceneManager.DuplicateEntity(id); - if (newId != INVALID_ENTITY) { + if (newId != INVALID_ENTITY_ID) { selectionManager.SetSelectedEntity(newId); } } @@ -249,19 +249,19 @@ void HierarchyPanel::HandleDragDrop(EntityID id) { if (ImGui::BeginDragDropTarget()) { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY_ID")) { EntityID sourceId = *(const EntityID*)payload->Data; - if (sourceId != id && sourceId != INVALID_ENTITY) { + if (sourceId != id && sourceId != INVALID_ENTITY_ID) { const Entity* targetEntity = sceneManager.GetEntity(id); const Entity* sourceEntity = sceneManager.GetEntity(sourceId); bool isValidMove = true; - EntityID checkParent = targetEntity ? targetEntity->parent : INVALID_ENTITY; - while (checkParent != INVALID_ENTITY) { + EntityID checkParent = targetEntity ? targetEntity->parent : INVALID_ENTITY_ID; + while (checkParent != INVALID_ENTITY_ID) { if (checkParent == sourceId) { isValidMove = false; break; } const Entity* parentEntity = sceneManager.GetEntity(checkParent); - checkParent = parentEntity ? parentEntity->parent : INVALID_ENTITY; + checkParent = parentEntity ? parentEntity->parent : INVALID_ENTITY_ID; } if (isValidMove && sourceEntity && sourceEntity->parent != id) { @@ -281,13 +281,13 @@ void HierarchyPanel::HandleKeyboardShortcuts() { if (ImGui::IsWindowFocused()) { if (ImGui::IsKeyPressed(ImGuiKey_Delete)) { - if (selectedId != INVALID_ENTITY) { + if (selectedId != INVALID_ENTITY_ID) { sceneManager.DeleteEntity(selectedId); } } if (ImGui::IsKeyPressed(ImGuiKey_F2)) { - if (selectedId != INVALID_ENTITY) { + if (selectedId != INVALID_ENTITY_ID) { const Entity* entity = sceneManager.GetEntity(selectedId); if (entity) { m_renaming = true; @@ -301,7 +301,7 @@ void HierarchyPanel::HandleKeyboardShortcuts() { ImGuiIO& io = ImGui::GetIO(); if (io.KeyCtrl) { if (ImGui::IsKeyPressed(ImGuiKey_C)) { - if (selectedId != INVALID_ENTITY) { + if (selectedId != INVALID_ENTITY_ID) { sceneManager.CopyEntity(selectedId); } } @@ -313,9 +313,9 @@ void HierarchyPanel::HandleKeyboardShortcuts() { } if (ImGui::IsKeyPressed(ImGuiKey_D)) { - if (selectedId != INVALID_ENTITY) { + if (selectedId != INVALID_ENTITY_ID) { EntityID newId = sceneManager.DuplicateEntity(selectedId); - if (newId != INVALID_ENTITY) { + if (newId != INVALID_ENTITY_ID) { selectionManager.SetSelectedEntity(newId); } } diff --git a/ui_editor/src/panels/HierarchyPanel.h b/ui_editor/src/panels/HierarchyPanel.h index 2b1ab3ed..a4afa6f6 100644 --- a/ui_editor/src/panels/HierarchyPanel.h +++ b/ui_editor/src/panels/HierarchyPanel.h @@ -1,7 +1,6 @@ #pragma once #include "Panel.h" -#include "Core/Event.h" #include "Core/GameObject.h" namespace UI { @@ -22,14 +21,14 @@ private: void HandleKeyboardShortcuts(); bool PassesFilter(EntityID id, const std::string& filter); - Event::HandlerID m_selectionHandlerId = 0; + uint64_t m_selectionHandlerId = 0; char m_searchBuffer[256] = ""; bool m_renaming = false; - EntityID m_renamingEntity = INVALID_ENTITY; + EntityID m_renamingEntity = INVALID_ENTITY_ID; char m_renameBuffer[256] = ""; bool m_renameJustStarted = false; - EntityID m_dragSource = INVALID_ENTITY; + EntityID m_dragSource = INVALID_ENTITY_ID; }; } \ No newline at end of file diff --git a/ui_editor/src/panels/InspectorPanel.h b/ui_editor/src/panels/InspectorPanel.h index 74945608..c3c234f5 100644 --- a/ui_editor/src/panels/InspectorPanel.h +++ b/ui_editor/src/panels/InspectorPanel.h @@ -1,7 +1,6 @@ #pragma once #include "Panel.h" -#include "Core/Event.h" #include "Core/GameObject.h" namespace UI { @@ -17,7 +16,7 @@ private: void RenderEntity(Entity* entity); void RenderComponent(Component* component); - Event::HandlerID m_selectionHandlerId = 0; + uint64_t m_selectionHandlerId = 0; }; } \ No newline at end of file