Refactor editor window runtime ownership

This commit is contained in:
2026-04-26 20:40:32 +08:00
parent fa4fcbe95b
commit ee05558f86
18 changed files with 1056 additions and 398 deletions

View File

@@ -5,7 +5,6 @@
#include "Platform/Win32/Windowing/EditorFloatingWindowPlacement.h"
#include "Platform/Win32/Windowing/EditorWindow.h"
#include "Windowing/Host/EditorWindowHostCoordinator.h"
#include "Windowing/Runtime/EditorWindowRuntimeController.h"
#include <XCEditor/Foundation/UIEditorRuntimeTrace.h>
@@ -39,10 +38,11 @@ std::string DescribeHostWindows(
continue;
}
stream << window->GetWindowId()
stream << window->GetOwner().GetWindowId()
<< "{hwnd=" << DescribeHwnd(window->GetHwnd())
<< ",primary=" << (window->IsPrimary() ? '1' : '0')
<< ",state=" << GetEditorWindowLifecycleStateName(window->GetLifecycleState())
<< ",primary=" << (window->GetOwner().IsPrimary() ? '1' : '0')
<< ",state=" << GetEditorWindowLifecycleStateName(
window->GetOwner().GetLifecycleState())
<< '}';
}
stream << ']';
@@ -61,33 +61,21 @@ EditorWindowHostRuntime::EditorWindowHostRuntime(
EditorWindowHostRuntime::~EditorWindowHostRuntime() = default;
EditorWindow* EditorWindowHostRuntime::CreateHostWindow(
std::unique_ptr<EditorWindowRuntimeController> runtimeController,
bool EditorWindowHostRuntime::CreateHostWindow(
EditorHostWindow& window,
const EditorWindowCreateParams& params) {
if (runtimeController == nullptr) {
LogRuntimeTrace("window", "window creation failed: runtime controller is null");
return nullptr;
}
const EditorWindowContentCapabilities capabilities =
runtimeController->GetCapabilities();
if (params.category == EditorWindowCategory::Workspace && !capabilities.workspace) {
if (params.category == EditorWindowCategory::Workspace && !window.IsWorkspaceWindow()) {
LogRuntimeTrace("window", "workspace window creation rejected: content is not workspace");
return nullptr;
return false;
}
if (params.category == EditorWindowCategory::Utility && !capabilities.utilityPanel) {
if (params.category == EditorWindowCategory::Utility && !window.IsUtilityWindow()) {
LogRuntimeTrace("window", "utility window creation rejected: content is not utility");
return nullptr;
return false;
}
auto windowPtr = std::make_unique<EditorWindow>(
params.windowId,
params.title.empty() ? std::wstring(L"XCEngine Editor") : params.title,
params.category,
params.chromePolicy,
params.primary,
std::move(runtimeController));
auto windowPtr = std::make_unique<EditorWindow>(window);
EditorWindow* const rawWindow = windowPtr.get();
window.AttachNativePeer(*rawWindow);
m_windows.push_back(std::move(windowPtr));
const auto eraseRawWindow = [this, rawWindow]() {
@@ -119,7 +107,9 @@ EditorWindow* EditorWindowHostRuntime::CreateHostWindow(
const HWND hwnd = CreateWindowExW(
extendedWindowStyle,
m_hostConfig.windowClassName,
rawWindow->GetTitle().c_str(),
rawWindow->GetTitle().empty()
? L"XCEngine Editor"
: rawWindow->GetTitle().c_str(),
windowStyle,
initialX,
initialY,
@@ -131,8 +121,9 @@ EditorWindow* EditorWindowHostRuntime::CreateHostWindow(
m_hostConfig.windowUserData);
m_pendingCreateWindow = nullptr;
if (hwnd == nullptr) {
rawWindow->GetOwner().DetachNativePeer(*rawWindow);
eraseRawWindow();
return nullptr;
return false;
}
if (!rawWindow->HasHwnd()) {
@@ -142,11 +133,12 @@ EditorWindow* EditorWindowHostRuntime::CreateHostWindow(
auto failWindowInitialization = [&](std::string_view message) {
LogRuntimeTrace("window", std::string(message));
if (m_hostCoordinator != nullptr) {
m_hostCoordinator->AbortUnregisteredWindow(*rawWindow);
m_hostCoordinator->AbortUnregisteredWindow(window);
} else {
rawWindow->GetOwner().DetachNativePeer(*rawWindow);
eraseRawWindow();
}
return static_cast<EditorWindow*>(nullptr);
return false;
};
const HICON bigIcon = static_cast<HICON>(
@@ -177,7 +169,7 @@ EditorWindow* EditorWindowHostRuntime::CreateHostWindow(
}
if (!m_hostCoordinator->InitializeHostWindow(
*rawWindow,
window,
EditorHostWindowRuntimeInitializationParams{
.repoRoot = m_repoRoot,
.captureRoot = m_captureRoot,
@@ -188,7 +180,7 @@ EditorWindow* EditorWindowHostRuntime::CreateHostWindow(
ShowWindow(hwnd, params.showCommand);
UpdateWindow(hwnd);
return rawWindow;
return true;
}
void EditorWindowHostRuntime::BindHostCoordinator(
@@ -214,7 +206,7 @@ std::vector<EditorHostWindow*> EditorWindowHostRuntime::GetWindows() {
windows.reserve(m_windows.size());
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
if (window != nullptr) {
windows.push_back(window.get());
windows.push_back(&window->GetOwner());
}
}
return windows;
@@ -225,7 +217,7 @@ std::vector<const EditorHostWindow*> EditorWindowHostRuntime::GetWindows() const
windows.reserve(m_windows.size());
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
if (window != nullptr) {
windows.push_back(window.get());
windows.push_back(&window->GetOwner());
}
}
return windows;
@@ -279,7 +271,8 @@ EditorHostWindow* EditorWindowHostRuntime::FindWindowFromScreenPoint(
return nullptr;
}
return FindWindow(GetAncestor(hitWindow, GA_ROOT));
EditorWindow* const nativeWindow = FindWindow(GetAncestor(hitWindow, GA_ROOT));
return nativeWindow != nullptr ? &nativeWindow->GetOwner() : nullptr;
}
const EditorHostWindow* EditorWindowHostRuntime::FindWindowFromScreenPoint(
@@ -290,7 +283,7 @@ const EditorHostWindow* EditorWindowHostRuntime::FindWindowFromScreenPoint(
void EditorWindowHostRuntime::ReapDestroyedWindows() {
for (auto it = m_windows.begin(); it != m_windows.end();) {
EditorWindow* const window = it->get();
if (window == nullptr || !window->IsDestroyed()) {
if (window == nullptr || !window->GetOwner().IsDestroyed()) {
++it;
continue;
}
@@ -301,7 +294,8 @@ void EditorWindowHostRuntime::ReapDestroyedWindows() {
LogRuntimeTrace(
"window-close",
"ReapDestroyedWindows erase windowId='" + std::string(window->GetWindowId()) +
"ReapDestroyedWindows erase windowId='" +
std::string(window->GetOwner().GetWindowId()) +
"' hostBefore=" + DescribeHostWindows(m_windows));
it = m_windows.erase(it);
LogRuntimeTrace(
@@ -338,7 +332,7 @@ EditorWindow* EditorWindowHostRuntime::FindWindowByIdImpl(std::string_view windo
}
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
if (window != nullptr && window->GetWindowId() == windowId) {
if (window != nullptr && window->GetOwner().GetWindowId() == windowId) {
return window.get();
}
}
@@ -351,16 +345,18 @@ const EditorWindow* EditorWindowHostRuntime::FindWindowByIdImpl(std::string_view
}
EditorHostWindow* EditorWindowHostRuntime::FindWindowById(std::string_view windowId) {
return FindWindowByIdImpl(windowId);
EditorWindow* const window = FindWindowByIdImpl(windowId);
return window != nullptr ? &window->GetOwner() : nullptr;
}
const EditorHostWindow* EditorWindowHostRuntime::FindWindowById(std::string_view windowId) const {
return FindWindowByIdImpl(windowId);
const EditorWindow* const window = FindWindowByIdImpl(windowId);
return window != nullptr ? &window->GetOwner() : nullptr;
}
EditorWindow* EditorWindowHostRuntime::FindPrimaryWindow() {
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
if (window != nullptr && window->IsPrimary()) {
if (window != nullptr && window->GetOwner().IsPrimary()) {
return window.get();
}
}