232 lines
8.0 KiB
C++
232 lines
8.0 KiB
C++
#include "EditorCompositionRoot.h"
|
|
|
|
#include "Product/Framework/Resources/EditorHostResourceService.h"
|
|
#include "Product/Framework/System/SystemInteractionService.h"
|
|
#include "Product/Runtime/EditorProductRuntime.h"
|
|
#include "Product/Runtime/Features/EditorFeatureComposition.h"
|
|
#include "Product/Rendering/Assets/EditorIconServiceFactory.h"
|
|
#include "Product/Rendering/Viewport/EditorViewportRuntimeServicesFactory.h"
|
|
#include "Product/Runtime/Shell/EditorShellRuntime.h"
|
|
#include "Product/Runtime/Windowing/EditorWindowManager.h"
|
|
#include "Product/Services/Engine/EngineEditorServices.h"
|
|
#include "Product/Support/EnvironmentFlags.h"
|
|
#include "System/Win32SystemInteractionHost.h"
|
|
#include "Windowing/EditorWindow.h"
|
|
#include "Windowing/EditorWindowHostConfig.h"
|
|
#include "Windowing/EditorWindowHostRuntime.h"
|
|
#include "Windowing/EditorWindowMessageDispatcher.h"
|
|
#include "D3D12EditorWindowRenderRuntime.h"
|
|
|
|
#include <XCEditor/Shell/UIEditorShellAsset.h>
|
|
#include <XCEditor/Windowing/System/EditorWindowSystem.h>
|
|
#include <XCEditor/Workspace/UIEditorWindowWorkspaceModel.h>
|
|
|
|
#include <optional>
|
|
#include <utility>
|
|
|
|
namespace XCEngine::UI::Editor::App {
|
|
|
|
EditorCompositionRoot::EditorCompositionRoot() = default;
|
|
|
|
EditorCompositionRoot::~EditorCompositionRoot() {
|
|
Shutdown();
|
|
}
|
|
|
|
bool EditorCompositionRoot::Initialize(EditorCompositionRootInitializeParams params) {
|
|
Shutdown();
|
|
m_validationMessage.clear();
|
|
|
|
m_resourceService = std::move(params.resourceService);
|
|
if (m_resourceService == nullptr) {
|
|
m_validationMessage = "resource service was not provided";
|
|
return false;
|
|
}
|
|
|
|
m_engineComposition = CreateEngineEditorComposition();
|
|
if (m_engineComposition == nullptr) {
|
|
m_validationMessage = "engine services initialization failed";
|
|
return false;
|
|
}
|
|
|
|
m_productRuntime = std::make_unique<EditorProductRuntime>();
|
|
if (!m_productRuntime->Initialize(
|
|
params.runtimePaths,
|
|
m_engineComposition->GetSceneBackendFactory())) {
|
|
m_validationMessage = "editor product runtime initialization failed: " +
|
|
m_productRuntime->GetValidationMessage();
|
|
return false;
|
|
}
|
|
|
|
m_systemInteractionHost = std::make_unique<Host::Win32SystemInteractionHost>();
|
|
m_windowSystem = std::make_unique<EditorWindowSystem>(
|
|
m_productRuntime->GetPanelRegistry());
|
|
|
|
EditorWindowHostConfig hostConfig = {};
|
|
hostConfig.hInstance = params.hInstance;
|
|
hostConfig.windowClassName = params.windowClassName;
|
|
hostConfig.windowStyle = params.windowStyle;
|
|
hostConfig.primaryWindowTitle = params.primaryWindowTitle;
|
|
hostConfig.windowUserData = params.windowUserData;
|
|
m_windowHostRuntime = std::make_unique<EditorWindowHostRuntime>(
|
|
std::move(hostConfig),
|
|
params.runtimePaths);
|
|
m_renderRuntimeFactory =
|
|
std::make_unique<Host::D3D12EditorWindowRenderRuntimeFactory>();
|
|
EditorWorkspaceShellRuntimeFactory workspaceShellRuntimeFactory = [this]() {
|
|
return CreateEditorWorkspaceShellRuntime(
|
|
CreateEditorWorkspaceFeatureContentSet(
|
|
m_productRuntime->GetConsoleEntries(),
|
|
m_productRuntime->GetProjectRuntime(),
|
|
m_productRuntime->GetSceneRuntime(),
|
|
m_productRuntime->GetColorPickerToolState(),
|
|
m_systemInteractionHost.get(),
|
|
[this](EditorUtilityWindowKind kind) {
|
|
m_productRuntime->RequestOpenUtilityWindow(kind);
|
|
},
|
|
[this](const std::filesystem::path& scenePath) {
|
|
return m_productRuntime->RequestOpenSceneAsset(scenePath);
|
|
}),
|
|
CreateEditorIconService(),
|
|
CreateEditorViewportRuntimeServices(),
|
|
::XCEngine::UI::Editor::BuildEditorShellShortcutManager(
|
|
m_productRuntime->GetShellAsset()),
|
|
m_productRuntime->GetShellDefinitionService(),
|
|
m_productRuntime->GetFrameStatusController(),
|
|
m_productRuntime->GetRuntimeCommandService(),
|
|
[this]() {
|
|
if (m_windowManager != nullptr) {
|
|
m_windowManager->RequestPrimaryWindowClose();
|
|
}
|
|
});
|
|
};
|
|
m_windowManager = std::make_unique<EditorWindowManager>(
|
|
*m_productRuntime,
|
|
[this]() {
|
|
return m_productRuntime != nullptr
|
|
? m_productRuntime->ConsumeOpenUtilityWindowRequest()
|
|
: std::optional<EditorUtilityWindowKind>{};
|
|
},
|
|
m_engineComposition->GetSceneViewportBridge(),
|
|
m_engineComposition->GetGameViewportBridge(),
|
|
m_engineComposition->GetShaderProvider(),
|
|
*m_windowSystem,
|
|
*m_renderRuntimeFactory,
|
|
*m_resourceService,
|
|
*m_windowHostRuntime,
|
|
std::move(workspaceShellRuntimeFactory),
|
|
[this](EditorUtilityWindowKind kind) {
|
|
return CreateEditorUtilityFeatureContent(
|
|
kind,
|
|
m_productRuntime->GetColorPickerToolState(),
|
|
m_productRuntime->GetSceneRuntime());
|
|
});
|
|
|
|
m_productRuntime->GetFrameStatusController().SetReadyStatus();
|
|
|
|
EditorWindowCreateParams createParams = {};
|
|
createParams.windowId = "main";
|
|
createParams.title = params.primaryWindowTitle;
|
|
createParams.category = EditorWindowCategory::Workspace;
|
|
createParams.showCommand = params.showCommand;
|
|
createParams.primary = true;
|
|
createParams.autoCaptureOnStartup =
|
|
IsEnvironmentFlagEnabled("XCUI_AUTO_CAPTURE_ON_STARTUP");
|
|
|
|
const UIEditorWindowWorkspaceState* primaryWindowState =
|
|
m_productRuntime->FindWindowWorkspaceState(createParams.windowId);
|
|
if (primaryWindowState == nullptr) {
|
|
m_validationMessage = "primary window state is missing from authoritative store";
|
|
return false;
|
|
}
|
|
if (m_windowManager->CreateWorkspaceWindow(
|
|
*primaryWindowState,
|
|
createParams) == nullptr) {
|
|
m_validationMessage = "primary window creation failed";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void EditorCompositionRoot::Shutdown() {
|
|
if (m_windowManager != nullptr) {
|
|
m_windowManager->Shutdown();
|
|
m_windowManager.reset();
|
|
}
|
|
|
|
m_renderRuntimeFactory.reset();
|
|
m_windowHostRuntime.reset();
|
|
m_windowSystem.reset();
|
|
m_systemInteractionHost.reset();
|
|
m_resourceService.reset();
|
|
|
|
if (m_engineComposition != nullptr) {
|
|
m_engineComposition->GetLifecycle().Shutdown();
|
|
m_engineComposition.reset();
|
|
}
|
|
|
|
m_productRuntime.reset();
|
|
}
|
|
|
|
const std::string& EditorCompositionRoot::GetValidationMessage() const {
|
|
return m_validationMessage;
|
|
}
|
|
|
|
void EditorCompositionRoot::HandlePendingNativeWindowCreated(HWND hwnd) {
|
|
if (m_windowHostRuntime != nullptr) {
|
|
m_windowHostRuntime->HandlePendingNativeWindowCreated(hwnd);
|
|
}
|
|
}
|
|
|
|
bool EditorCompositionRoot::TryDispatchWindowMessage(
|
|
HWND hwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
LRESULT& outResult) {
|
|
if (m_windowHostRuntime == nullptr || m_windowManager == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
if (EditorWindow* const window = m_windowHostRuntime->FindWindow(hwnd);
|
|
window != nullptr) {
|
|
return EditorWindowMessageDispatcher::TryDispatch(
|
|
hwnd,
|
|
*m_windowManager,
|
|
*window,
|
|
message,
|
|
wParam,
|
|
lParam,
|
|
outResult);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool EditorCompositionRoot::TickFrame() {
|
|
if (m_windowManager == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
if (m_engineComposition != nullptr) {
|
|
m_engineComposition->GetLifecycle().UpdateAsyncLoads();
|
|
}
|
|
m_windowManager->DestroyClosedWindows();
|
|
if (!m_windowManager->HasWindows()) {
|
|
return false;
|
|
}
|
|
|
|
if (m_productRuntime != nullptr) {
|
|
m_productRuntime->TickEditorRuntime();
|
|
}
|
|
m_windowManager->RenderAllWindows();
|
|
return m_windowManager->HasWindows();
|
|
}
|
|
|
|
bool EditorCompositionRoot::RequestPrimaryWindowClose() {
|
|
return m_windowManager != nullptr &&
|
|
m_windowManager->RequestPrimaryWindowClose();
|
|
}
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|