diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index c61942b1..1cb269fb 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -62,7 +62,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib - ${CMAKE_CURRENT_SOURCE_DIR}/../engine/build/Release/XCEngine.lib + ${CMAKE_CURRENT_SOURCE_DIR}/../build/engine/Release/XCEngine.lib ) set_target_properties(${PROJECT_NAME} PROPERTIES diff --git a/editor/src/Core/EditorContext.h b/editor/src/Core/EditorContext.h index 86281265..60692433 100644 --- a/editor/src/Core/EditorContext.h +++ b/editor/src/Core/EditorContext.h @@ -7,6 +7,7 @@ #include "ISceneManager.h" #include "Managers/SceneManager.h" #include "Managers/ProjectManager.h" +#include "EditorEvents.h" #include #include @@ -20,7 +21,16 @@ public: , m_selectionManager(std::make_unique(*m_eventBus)) , m_sceneManager(std::make_unique()) , m_projectManager(std::make_unique()) { - m_sceneManager->SetSelectionManager(m_selectionManager.get()); + + m_entityDeletedHandlerId = m_eventBus->Subscribe([this](const EntityDeletedEvent& event) { + if (m_selectionManager->GetSelectedEntity() == event.entityId) { + m_selectionManager->ClearSelection(); + } + }); + } + + ~EditorContext() { + m_eventBus->Unsubscribe(m_entityDeletedHandlerId); } EventBus& GetEventBus() override { @@ -53,7 +63,8 @@ private: std::unique_ptr m_sceneManager; std::unique_ptr m_projectManager; std::string m_projectPath; + uint64_t m_entityDeletedHandlerId; }; } -} \ No newline at end of file +} diff --git a/editor/src/Core/EventBus.h b/editor/src/Core/EventBus.h index 02f7efbf..2ffab2bf 100644 --- a/editor/src/Core/EventBus.h +++ b/editor/src/Core/EventBus.h @@ -6,11 +6,25 @@ #include #include #include -#include +#include +#include namespace XCEngine { namespace Editor { +template +struct EventTypeId { + static uint32_t Get() { + static const uint32_t id = s_nextId++; + return id; + } +private: + static uint32_t s_nextId; +}; + +template +uint32_t EventTypeId::s_nextId = 0; + class EventBus { public: using EventHandler = std::function; @@ -18,29 +32,35 @@ public: template uint64_t Subscribe(std::function handler) { static_assert(sizeof(T) > 0, "Event type must be defined"); - size_t typeId = typeid(T).hash_code(); - uint64_t handlerId = m_nextHandlerId++; + uint32_t typeId = EventTypeId::Get(); + uint64_t handlerId = 0; - auto it = m_handlers.find(typeId); - if (it == m_handlers.end()) { - m_handlers[typeId] = std::vector(); + { + std::lock_guard lock(m_mutex); + handlerId = m_nextHandlerId++; + + auto it = m_handlers.find(typeId); + if (it == m_handlers.end()) { + m_handlers[typeId] = std::vector(); + } + + HandlerEntry entry; + entry.id = handlerId; + entry.handler = [handler](const void* data) { + handler(*static_cast(data)); + }; + m_handlers[typeId].push_back(entry); } - HandlerEntry entry; - entry.id = handlerId; - entry.handler = [handler](const void* data) { - handler(*static_cast(data)); - }; - m_handlers[typeId].push_back(entry); - return handlerId; } template void Unsubscribe(uint64_t handlerId) { static_assert(sizeof(T) > 0, "Event type must be defined"); - size_t typeId = typeid(T).hash_code(); + uint32_t typeId = EventTypeId::Get(); + std::lock_guard lock(m_mutex); auto it = m_handlers.find(typeId); if (it != m_handlers.end()) { auto& handlers = it->second; @@ -55,8 +75,9 @@ public: template void Publish(const T& event) { static_assert(sizeof(T) > 0, "Event type must be defined"); - size_t typeId = typeid(T).hash_code(); + uint32_t typeId = EventTypeId::Get(); + std::shared_lock lock(m_mutex); auto it = m_handlers.find(typeId); if (it != m_handlers.end()) { for (const auto& entry : it->second) { @@ -66,6 +87,7 @@ public: } void Clear() { + std::lock_guard lock(m_mutex); m_handlers.clear(); } @@ -75,8 +97,9 @@ private: std::function handler; }; - std::unordered_map> m_handlers; + std::unordered_map> m_handlers; uint64_t m_nextHandlerId = 0; + std::shared_mutex m_mutex; }; } diff --git a/editor/src/Managers/SceneManager.cpp b/editor/src/Managers/SceneManager.cpp index d92c5f25..c8011e82 100644 --- a/editor/src/Managers/SceneManager.cpp +++ b/editor/src/Managers/SceneManager.cpp @@ -1,5 +1,4 @@ #include "SceneManager.h" -#include "SelectionManager.h" #include namespace XCEngine { @@ -7,10 +6,6 @@ namespace Editor { SceneManager::SceneManager() = default; -void SceneManager::SetSelectionManager(ISelectionManager* selectionManager) { - m_selectionManager = selectionManager; -} - ::XCEngine::Components::GameObject* SceneManager::CreateEntity(const std::string& name, ::XCEngine::Components::GameObject* parent) { if (!m_scene) { m_scene = new ::XCEngine::Components::Scene("EditorScene"); @@ -41,12 +36,8 @@ void SceneManager::DeleteEntity(::XCEngine::Components::GameObject::ID id) { m_rootEntities.erase(std::remove(m_rootEntities.begin(), m_rootEntities.end(), entity), m_rootEntities.end()); } - if (m_selectionManager && m_selectionManager->GetSelectedEntity() == entity->GetID()) { - m_selectionManager->ClearSelection(); - } - m_scene->DestroyGameObject(entity); - OnEntityDeleted.Invoke(id); + OnEntityDeleted.Invoke(entity->GetID()); } SceneManager::ClipboardData SceneManager::CopyEntityRecursive(const ::XCEngine::Components::GameObject* entity) { diff --git a/editor/src/Managers/SceneManager.h b/editor/src/Managers/SceneManager.h index 5f96c254..2c67b81a 100644 --- a/editor/src/Managers/SceneManager.h +++ b/editor/src/Managers/SceneManager.h @@ -13,14 +13,11 @@ #include #include -#include "Core/ISelectionManager.h" #include "Core/ISceneManager.h" namespace XCEngine { namespace Editor { -class ISelectionManager; - class SceneManager : public ISceneManager { public: SceneManager(); @@ -28,11 +25,11 @@ public: ::XCEngine::Components::GameObject* CreateEntity(const std::string& name, ::XCEngine::Components::GameObject* parent = nullptr); ::XCEngine::Components::GameObject* GetEntity(::XCEngine::Components::GameObject::ID id) { - return m_scene ? m_scene->Find(std::to_string(id)) : nullptr; + return m_scene ? m_scene->FindByID(id) : nullptr; } const ::XCEngine::Components::GameObject* GetEntity(::XCEngine::Components::GameObject::ID id) const { - return m_scene ? m_scene->Find(std::to_string(id)) : nullptr; + return m_scene ? m_scene->FindByID(id) : nullptr; } const std::vector<::XCEngine::Components::GameObject*>& GetRootEntities() const { @@ -51,8 +48,6 @@ public: void CreateDemoScene(); bool HasClipboardData() const { return m_clipboard.has_value(); } - - void SetSelectionManager(ISelectionManager* selectionManager); ::XCEngine::Core::Event<::XCEngine::Components::GameObject::ID> OnEntityCreated; ::XCEngine::Core::Event<::XCEngine::Components::GameObject::ID> OnEntityDeleted; @@ -74,7 +69,6 @@ private: ::XCEngine::Components::Scene* m_scene = nullptr; std::vector<::XCEngine::Components::GameObject*> m_rootEntities; std::optional m_clipboard; - ISelectionManager* m_selectionManager = nullptr; }; } diff --git a/editor/src/panels/Panel.h b/editor/src/panels/Panel.h index ee83a419..3d5f8975 100644 --- a/editor/src/panels/Panel.h +++ b/editor/src/panels/Panel.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include namespace XCEngine { namespace Editor { @@ -23,8 +25,16 @@ public: void SetOpen(bool open) { m_isOpen = open; } void Toggle() { m_isOpen = !m_isOpen; } - void SetContext(IEditorContext* context) { m_context = context; } - IEditorContext* GetContext() const { return m_context; } + void SetContext(IEditorContext* context) { + assert(!m_context && "Context already set!"); + m_context = context; + } + + IEditorContext* GetContext() const { + return m_context; + } + + bool HasContext() const { return m_context != nullptr; } protected: std::string m_name; diff --git a/engine/include/XCEngine/Scene/Scene.h b/engine/include/XCEngine/Scene/Scene.h index 60e3f2b2..5110ac4d 100644 --- a/engine/include/XCEngine/Scene/Scene.h +++ b/engine/include/XCEngine/Scene/Scene.h @@ -30,6 +30,7 @@ public: void DestroyGameObject(GameObject* gameObject); GameObject* Find(const std::string& name) const; + GameObject* FindByID(GameObjectID id) const; GameObject* FindGameObjectWithTag(const std::string& tag) const; template diff --git a/engine/src/Scene/Scene.cpp b/engine/src/Scene/Scene.cpp index 41f2cad9..95b77471 100644 --- a/engine/src/Scene/Scene.cpp +++ b/engine/src/Scene/Scene.cpp @@ -79,6 +79,14 @@ GameObject* Scene::Find(const std::string& name) const { return nullptr; } +GameObject* Scene::FindByID(GameObjectID id) const { + auto it = m_gameObjects.find(id); + if (it != m_gameObjects.end()) { + return it->second.get(); + } + return nullptr; +} + GameObject* Scene::FindInChildren(GameObject* parent, const std::string& name) const { for (size_t i = 0; i < parent->GetChildCount(); ++i) { GameObject* child = parent->GetChild(i);