Migrate ProjectManager to dependency injection

- Created IProjectManager interface
- ProjectManager now implements IProjectManager
- Removed ProjectManager::Get() singleton
- Added IEditorContext::GetProjectManager()
- ProjectPanel now uses m_context->GetProjectManager() instead of singleton
- EditorContext owns ProjectManager instance
This commit is contained in:
2026-03-25 16:25:55 +08:00
parent 56116b62c3
commit d4c94907ba
7 changed files with 98 additions and 35 deletions

View File

@@ -3,7 +3,9 @@
#include "IEditorContext.h" #include "IEditorContext.h"
#include "EventBus.h" #include "EventBus.h"
#include "SelectionManager.h" #include "SelectionManager.h"
#include "IProjectManager.h"
#include "Managers/SceneManager.h" #include "Managers/SceneManager.h"
#include "Managers/ProjectManager.h"
#include <string> #include <string>
#include <memory> #include <memory>
@@ -15,7 +17,8 @@ public:
EditorContext() EditorContext()
: m_eventBus(std::make_unique<EventBus>()) : m_eventBus(std::make_unique<EventBus>())
, m_selectionManager(std::make_unique<SelectionManager>(*m_eventBus)) , m_selectionManager(std::make_unique<SelectionManager>(*m_eventBus))
, m_sceneManager(std::make_unique<SceneManager>()) { , m_sceneManager(std::make_unique<SceneManager>())
, m_projectManager(std::make_unique<ProjectManager>()) {
m_sceneManager->SetSelectionManager(m_selectionManager.get()); m_sceneManager->SetSelectionManager(m_selectionManager.get());
} }
@@ -35,6 +38,10 @@ public:
return *m_sceneManager; return *m_sceneManager;
} }
IProjectManager& GetProjectManager() override {
return *m_projectManager;
}
void SetProjectPath(const std::string& path) override { void SetProjectPath(const std::string& path) override {
m_projectPath = path; m_projectPath = path;
} }
@@ -47,6 +54,7 @@ private:
std::unique_ptr<EventBus> m_eventBus; std::unique_ptr<EventBus> m_eventBus;
std::unique_ptr<SelectionManager> m_selectionManager; std::unique_ptr<SelectionManager> m_selectionManager;
std::unique_ptr<SceneManager> m_sceneManager; std::unique_ptr<SceneManager> m_sceneManager;
std::unique_ptr<ProjectManager> m_projectManager;
std::string m_projectPath; std::string m_projectPath;
}; };

View File

@@ -8,6 +8,7 @@ namespace Editor {
class EventBus; class EventBus;
class ISelectionManager; class ISelectionManager;
class IProjectManager;
class IEditorContext { class IEditorContext {
public: public:
@@ -16,6 +17,7 @@ public:
virtual EventBus& GetEventBus() = 0; virtual EventBus& GetEventBus() = 0;
virtual ISelectionManager& GetSelectionManager() = 0; virtual ISelectionManager& GetSelectionManager() = 0;
virtual void* GetSceneManager() = 0; virtual void* GetSceneManager() = 0;
virtual IProjectManager& GetProjectManager() = 0;
virtual void SetProjectPath(const std::string& path) = 0; virtual void SetProjectPath(const std::string& path) = 0;
virtual const std::string& GetProjectPath() const = 0; virtual const std::string& GetProjectPath() const = 0;

View File

@@ -0,0 +1,39 @@
#pragma once
#include <string>
#include <vector>
#include <memory>
#include "Core/AssetItem.h"
namespace XCEngine {
namespace Editor {
class IProjectManager {
public:
virtual ~IProjectManager() = default;
virtual std::vector<AssetItemPtr>& GetCurrentItems() = 0;
virtual int GetSelectedIndex() const = 0;
virtual void SetSelectedIndex(int index) = 0;
virtual void NavigateToFolder(const AssetItemPtr& folder) = 0;
virtual void NavigateBack() = 0;
virtual void NavigateToIndex(size_t index) = 0;
virtual bool CanNavigateBack() const = 0;
virtual std::string GetCurrentPath() const = 0;
virtual size_t GetPathDepth() const = 0;
virtual std::string GetPathName(size_t index) const = 0;
virtual void Initialize(const std::string& projectPath) = 0;
virtual void RefreshCurrentFolder() = 0;
virtual void CreateFolder(const std::string& name) = 0;
virtual void DeleteItem(int index) = 0;
virtual bool MoveItem(const std::string& sourceFullPath, const std::string& destFolderFullPath) = 0;
virtual const std::string& GetProjectPath() const = 0;
};
} // namespace Editor
} // namespace XCEngine

View File

@@ -9,11 +9,6 @@ namespace fs = std::filesystem;
namespace XCEngine { namespace XCEngine {
namespace Editor { namespace Editor {
ProjectManager& ProjectManager::Get() {
static ProjectManager instance;
return instance;
}
std::vector<AssetItemPtr>& ProjectManager::GetCurrentItems() { std::vector<AssetItemPtr>& ProjectManager::GetCurrentItems() {
if (m_path.empty()) { if (m_path.empty()) {
static std::vector<AssetItemPtr> empty; static std::vector<AssetItemPtr> empty;

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Core/AssetItem.h" #include "Core/AssetItem.h"
#include "Core/IProjectManager.h"
#include <vector> #include <vector>
#include <string> #include <string>
#include <memory> #include <memory>
@@ -8,35 +9,31 @@
namespace XCEngine { namespace XCEngine {
namespace Editor { namespace Editor {
class ProjectManager { class ProjectManager : public IProjectManager {
public: public:
static ProjectManager& Get(); std::vector<AssetItemPtr>& GetCurrentItems() override;
int GetSelectedIndex() const override { return m_selectedIndex; }
void SetSelectedIndex(int index) override { m_selectedIndex = index; }
std::vector<AssetItemPtr>& GetCurrentItems(); void NavigateToFolder(const AssetItemPtr& folder) override;
int GetSelectedIndex() const { return m_selectedIndex; } void NavigateBack() override;
void SetSelectedIndex(int index) { m_selectedIndex = index; } void NavigateToIndex(size_t index) override;
bool CanNavigateBack() const override { return m_path.size() > 1; }
void NavigateToFolder(const AssetItemPtr& folder); std::string GetCurrentPath() const override;
void NavigateBack(); size_t GetPathDepth() const override { return m_path.size(); }
void NavigateToIndex(size_t index); std::string GetPathName(size_t index) const override;
bool CanNavigateBack() const { return m_path.size() > 1; }
std::string GetCurrentPath() const; void Initialize(const std::string& projectPath) override;
size_t GetPathDepth() const { return m_path.size(); } void RefreshCurrentFolder() override;
std::string GetPathName(size_t index) const;
void Initialize(const std::string& projectPath); void CreateFolder(const std::string& name) override;
void RefreshCurrentFolder(); void DeleteItem(int index) override;
bool MoveItem(const std::string& sourceFullPath, const std::string& destFolderFullPath) override;
void CreateFolder(const std::string& name); const std::string& GetProjectPath() const override { return m_projectPath; }
void DeleteItem(int index);
bool MoveItem(const std::string& sourceFullPath, const std::string& destFolderFullPath);
const std::string& GetProjectPath() const { return m_projectPath; }
private: private:
ProjectManager() = default;
AssetItemPtr ScanDirectory(const std::wstring& path); AssetItemPtr ScanDirectory(const std::wstring& path);
AssetItemPtr CreateAssetItem(const std::wstring& path, const std::wstring& nameW, bool isFolder); AssetItemPtr CreateAssetItem(const std::wstring& path, const std::wstring& nameW, bool isFolder);
std::wstring GetCurrentFullPathW() const; std::wstring GetCurrentFullPathW() const;

View File

@@ -1,5 +1,6 @@
#include "ProjectPanel.h" #include "ProjectPanel.h"
#include "Managers/ProjectManager.h" #include "Core/IEditorContext.h"
#include "Core/IProjectManager.h"
#include "Core/AssetItem.h" #include "Core/AssetItem.h"
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
@@ -13,7 +14,7 @@ ProjectPanel::ProjectPanel() : Panel("Project") {
} }
void ProjectPanel::Initialize(const std::string& projectPath) { void ProjectPanel::Initialize(const std::string& projectPath) {
ProjectManager::Get().Initialize(projectPath); m_context->GetProjectManager().Initialize(projectPath);
} }
void ProjectPanel::Render() { void ProjectPanel::Render() {
@@ -26,7 +27,7 @@ void ProjectPanel::Render() {
ImGui::Begin(m_name.c_str(), nullptr, ImGuiWindowFlags_None); ImGui::Begin(m_name.c_str(), nullptr, ImGuiWindowFlags_None);
auto& manager = ProjectManager::Get(); auto& manager = m_context->GetProjectManager();
bool canGoBack = manager.CanNavigateBack(); bool canGoBack = manager.CanNavigateBack();
ImGui::BeginDisabled(!canGoBack); ImGui::BeginDisabled(!canGoBack);
@@ -160,7 +161,7 @@ void ProjectPanel::Render() {
} }
void ProjectPanel::RenderAssetItem(const AssetItemPtr& item, int index) { void ProjectPanel::RenderAssetItem(const AssetItemPtr& item, int index) {
auto& manager = ProjectManager::Get(); auto& manager = m_context->GetProjectManager();
bool isSelected = (manager.GetSelectedIndex() == index); bool isSelected = (manager.GetSelectedIndex() == index);
ImGui::PushID(index); ImGui::PushID(index);
@@ -287,7 +288,7 @@ void ProjectPanel::RenderAssetItem(const AssetItemPtr& item, int index) {
} }
void ProjectPanel::CreateNewFolder(const std::string& name) { void ProjectPanel::CreateNewFolder(const std::string& name) {
auto& manager = ProjectManager::Get(); auto& manager = m_context->GetProjectManager();
manager.CreateFolder(name); manager.CreateFolder(name);
} }

View File

@@ -492,6 +492,11 @@ RHIResourceView* D3D12Device::CreateRenderTargetView(RHITexture* texture, const
rtvDesc.Format = static_cast<DXGI_FORMAT>(desc.format); rtvDesc.Format = static_cast<DXGI_FORMAT>(desc.format);
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
{
FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f2) { fprintf(f2, "[CreateRenderTargetView] Creating RTV heap...\n"); fclose(f2); }
}
auto heap = std::make_unique<D3D12DescriptorHeap>(); auto heap = std::make_unique<D3D12DescriptorHeap>();
if (!heap->Initialize(m_device.Get(), DescriptorHeapType::RTV, 1, false)) { if (!heap->Initialize(m_device.Get(), DescriptorHeapType::RTV, 1, false)) {
FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a"); FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
@@ -500,10 +505,18 @@ RHIResourceView* D3D12Device::CreateRenderTargetView(RHITexture* texture, const
return nullptr; return nullptr;
} }
{
FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f2) { fprintf(f2, "[CreateRenderTargetView] RTV heap created, calling CreateRenderTargetView...\n"); fclose(f2); }
}
view->InitializeAsRenderTarget(m_device.Get(), resource, &rtvDesc, heap.get(), 0); view->InitializeAsRenderTarget(m_device.Get(), resource, &rtvDesc, heap.get(), 0);
view->SetOwnedHeap(std::move(heap)); view->SetOwnedHeap(std::move(heap));
FILE* f3 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f3) { fprintf(f3, "[CreateRenderTargetView] Success\n"); fclose(f3); } {
FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f2) { fprintf(f2, "[CreateRenderTargetView] Success\n"); fclose(f2); }
}
return view; return view;
} }
@@ -528,6 +541,9 @@ RHIResourceView* D3D12Device::CreateDepthStencilView(RHITexture* texture, const
} }
RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) { RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) {
FILE* f = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f) { fprintf(f, "[CreateShaderResourceView] Start\n"); fclose(f); }
auto* view = new D3D12ResourceView(); auto* view = new D3D12ResourceView();
auto* d3d12Texture = static_cast<D3D12Texture*>(texture); auto* d3d12Texture = static_cast<D3D12Texture*>(texture);
ID3D12Resource* resource = d3d12Texture->GetResource(); ID3D12Resource* resource = d3d12Texture->GetResource();
@@ -541,12 +557,17 @@ RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, cons
auto heap = std::make_unique<D3D12DescriptorHeap>(); auto heap = std::make_unique<D3D12DescriptorHeap>();
if (!heap->Initialize(m_device.Get(), DescriptorHeapType::CBV_SRV_UAV, 1, true)) { if (!heap->Initialize(m_device.Get(), DescriptorHeapType::CBV_SRV_UAV, 1, true)) {
FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f2) { fprintf(f2, "[CreateShaderResourceView] heap Initialize failed\n"); fclose(f2); }
delete view; delete view;
return nullptr; return nullptr;
} }
view->InitializeAsShaderResource(m_device.Get(), resource, &srvDesc, heap.get(), 0); view->InitializeAsShaderResource(m_device.Get(), resource, &srvDesc, heap.get(), 0);
view->SetOwnedHeap(std::move(heap)); view->SetOwnedHeap(std::move(heap));
FILE* f3 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f3) { fprintf(f3, "[CreateShaderResourceView] Success\n"); fclose(f3); }
return view; return view;
} }