Files
XCEngine/editor/app/Bootstrap/EditorCompositionRoot.cpp

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