editor: refactor workspace window synchronization
This commit is contained in:
@@ -11,6 +11,16 @@ namespace XCEngine::UI::Editor::App {
|
||||
|
||||
namespace {
|
||||
|
||||
UIEditorWindowWorkspaceState BuildWindowStateFromController(
|
||||
std::string_view windowId,
|
||||
const UIEditorWorkspaceController& workspaceController) {
|
||||
UIEditorWindowWorkspaceState windowState = {};
|
||||
windowState.windowId = std::string(windowId);
|
||||
windowState.workspace = workspaceController.GetWorkspace();
|
||||
windowState.session = workspaceController.GetSession();
|
||||
return windowState;
|
||||
}
|
||||
|
||||
EditorWindowContentCursorKind ToContentCursorKind(ProjectPanel::CursorKind cursorKind) {
|
||||
switch (cursorKind) {
|
||||
case ProjectPanel::CursorKind::ResizeEW:
|
||||
@@ -35,12 +45,8 @@ EditorWindowContentCursorKind ToContentCursorKind(
|
||||
}
|
||||
|
||||
EditorWorkspaceWindowProjection BuildWorkspaceProjectionFromController(
|
||||
const UIEditorWorkspaceController& workspaceController,
|
||||
std::string_view windowId) {
|
||||
const UIEditorWorkspaceController& workspaceController) {
|
||||
EditorWorkspaceWindowProjection projection = {};
|
||||
projection.windowState.windowId = std::string(windowId);
|
||||
projection.windowState.workspace = workspaceController.GetWorkspace();
|
||||
projection.windowState.session = workspaceController.GetSession();
|
||||
projection.minimumOuterSize = ResolveUIEditorDetachedWorkspaceMinimumOuterSize(
|
||||
workspaceController);
|
||||
projection.useDetachedTitleBarTabStrip = HasUIEditorSingleVisibleRootTab(workspaceController);
|
||||
@@ -56,9 +62,8 @@ EditorWorkspaceWindowContentController::EditorWorkspaceWindowContentController(
|
||||
UIEditorWorkspaceController workspaceController,
|
||||
EditorWindowSystem& windowSystem)
|
||||
: m_windowId(std::move(windowId)),
|
||||
m_workspaceController(std::move(workspaceController)),
|
||||
m_windowSystem(windowSystem) {
|
||||
RefreshProjectionFromWorkspaceController();
|
||||
RefreshProjectionFromWorkspaceController(workspaceController);
|
||||
}
|
||||
|
||||
EditorWorkspaceWindowContentController::~EditorWorkspaceWindowContentController() = default;
|
||||
@@ -103,11 +108,6 @@ EditorWorkspaceWindowContentController::TryGetTitleBarBinding() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
const UIEditorWorkspaceController*
|
||||
EditorWorkspaceWindowContentController::TryGetWorkspaceController() const {
|
||||
return &m_workspaceController;
|
||||
}
|
||||
|
||||
const EditorWorkspaceWindowProjection*
|
||||
EditorWorkspaceWindowContentController::TryGetWorkspaceProjection() const {
|
||||
return &m_projection;
|
||||
@@ -115,43 +115,39 @@ EditorWorkspaceWindowContentController::TryGetWorkspaceProjection() const {
|
||||
|
||||
void EditorWorkspaceWindowContentController::RefreshWorkspaceProjection(
|
||||
EditorWorkspaceWindowProjection projection) {
|
||||
projection.windowState.windowId = m_windowId;
|
||||
const auto currentSnapshot = BuildUIEditorWorkspaceLayoutSnapshot(
|
||||
m_workspaceController.GetWorkspace(),
|
||||
m_workspaceController.GetSession());
|
||||
const auto nextSnapshot = BuildUIEditorWorkspaceLayoutSnapshot(
|
||||
projection.windowState.workspace,
|
||||
projection.windowState.session);
|
||||
if (!AreUIEditorWorkspaceLayoutSnapshotsEquivalent(currentSnapshot, nextSnapshot)) {
|
||||
m_workspaceController = UIEditorWorkspaceController(
|
||||
m_workspaceController.GetPanelRegistry(),
|
||||
projection.windowState.workspace,
|
||||
projection.windowState.session);
|
||||
}
|
||||
m_projection = std::move(projection);
|
||||
}
|
||||
|
||||
void EditorWorkspaceWindowContentController::RefreshProjectionFromWorkspaceController(bool primary) {
|
||||
bool EditorWorkspaceWindowContentController::TryBuildAuthoritativeWorkspaceController(
|
||||
UIEditorWorkspaceController& outController) const {
|
||||
const UIEditorWindowWorkspaceState* windowState =
|
||||
m_windowSystem.FindWindowState(m_windowId);
|
||||
if (windowState == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outController = BuildWorkspaceControllerForWindowState(
|
||||
m_windowSystem.GetPanelRegistry(),
|
||||
*windowState);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorWorkspaceWindowContentController::RefreshProjectionFromWorkspaceController(
|
||||
const UIEditorWorkspaceController& workspaceController,
|
||||
bool primary) {
|
||||
const std::wstring preservedWindowTitle = m_projection.windowTitle;
|
||||
m_projection = BuildWorkspaceProjectionFromController(m_workspaceController, m_windowId);
|
||||
m_projection = BuildWorkspaceProjectionFromController(workspaceController);
|
||||
if (!primary) {
|
||||
m_projection.windowTitle = ResolveEditorWindowPresentationTitle(
|
||||
std::wstring_view{},
|
||||
m_workspaceController.GetPanelRegistry(),
|
||||
m_projection.windowState,
|
||||
workspaceController.GetPanelRegistry(),
|
||||
BuildWindowStateFromController(m_windowId, workspaceController),
|
||||
false);
|
||||
} else if (!preservedWindowTitle.empty()) {
|
||||
m_projection.windowTitle = preservedWindowTitle;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorWorkspaceWindowContentController::RestoreWorkspaceControllerFromProjection() {
|
||||
m_workspaceController = UIEditorWorkspaceController(
|
||||
m_workspaceController.GetPanelRegistry(),
|
||||
m_projection.windowState.workspace,
|
||||
m_projection.windowState.session);
|
||||
}
|
||||
|
||||
void EditorWorkspaceWindowContentController::Initialize(
|
||||
const EditorWindowContentInitializationContext& context) {
|
||||
m_shellRuntime.Initialize(context.repoRoot, context.textureHost, context.textMeasurer);
|
||||
@@ -173,12 +169,21 @@ void EditorWorkspaceWindowContentController::SetViewportSurfacePresentationEnabl
|
||||
EditorWindowFrameTransferRequests EditorWorkspaceWindowContentController::UpdateAndAppend(
|
||||
const EditorWindowContentFrameContext& context,
|
||||
::XCEngine::UI::UIDrawData& drawData) {
|
||||
UIEditorWorkspaceController workspaceController = {};
|
||||
if (!TryBuildAuthoritativeWorkspaceController(workspaceController)) {
|
||||
AppendUIEditorRuntimeTrace(
|
||||
"window",
|
||||
"workspace frame skipped: authoritative state missing for window '" +
|
||||
m_windowId + "'");
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto beforeSnapshot = BuildUIEditorWorkspaceLayoutSnapshot(
|
||||
m_workspaceController.GetWorkspace(),
|
||||
m_workspaceController.GetSession());
|
||||
workspaceController.GetWorkspace(),
|
||||
workspaceController.GetSession());
|
||||
EditorWindowFrameTransferRequests transferRequests = m_frameOrchestrator.UpdateAndAppend(
|
||||
context.editorContext,
|
||||
m_workspaceController,
|
||||
workspaceController,
|
||||
m_shellRuntime,
|
||||
context.bounds,
|
||||
context.inputEvents,
|
||||
@@ -189,21 +194,20 @@ EditorWindowFrameTransferRequests EditorWorkspaceWindowContentController::Update
|
||||
context.useDetachedTitleBarTabStrip,
|
||||
drawData);
|
||||
const auto afterSnapshot = BuildUIEditorWorkspaceLayoutSnapshot(
|
||||
m_workspaceController.GetWorkspace(),
|
||||
m_workspaceController.GetSession());
|
||||
workspaceController.GetWorkspace(),
|
||||
workspaceController.GetSession());
|
||||
if (!AreUIEditorWorkspaceLayoutSnapshotsEquivalent(beforeSnapshot, afterSnapshot)) {
|
||||
std::string error = {};
|
||||
if (!m_windowSystem.CommitLiveWindowMutation(
|
||||
m_windowId,
|
||||
m_workspaceController,
|
||||
workspaceController,
|
||||
error)) {
|
||||
AppendUIEditorRuntimeTrace(
|
||||
"window",
|
||||
"workspace direct commit rejected for window '" +
|
||||
m_windowId + "': " + error);
|
||||
RestoreWorkspaceControllerFromProjection();
|
||||
} else {
|
||||
RefreshProjectionFromWorkspaceController(context.primary);
|
||||
RefreshProjectionFromWorkspaceController(workspaceController, context.primary);
|
||||
}
|
||||
}
|
||||
return transferRequests;
|
||||
|
||||
Reference in New Issue
Block a user