Refactor new editor boundaries and test ownership
This commit is contained in:
169
new_editor/app/Composition/EditorWindowWorkspaceStore.cpp
Normal file
169
new_editor/app/Composition/EditorWindowWorkspaceStore.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#include "Composition/EditorWindowWorkspaceStore.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine::UI::Editor::App::Internal {
|
||||
|
||||
namespace {
|
||||
|
||||
UIEditorWindowWorkspaceState BuildWindowState(
|
||||
std::string_view windowId,
|
||||
const UIEditorWorkspaceController& workspaceController) {
|
||||
UIEditorWindowWorkspaceState state = {};
|
||||
state.windowId = std::string(windowId);
|
||||
state.workspace = workspaceController.GetWorkspace();
|
||||
state.session = workspaceController.GetSession();
|
||||
return state;
|
||||
}
|
||||
|
||||
std::string ResolveFallbackWindowId(const UIEditorWindowWorkspaceSet& windowSet) {
|
||||
if (!windowSet.primaryWindowId.empty() &&
|
||||
FindUIEditorWindowWorkspaceState(windowSet, windowSet.primaryWindowId) != nullptr) {
|
||||
return windowSet.primaryWindowId;
|
||||
}
|
||||
|
||||
return windowSet.windows.empty() ? std::string() : windowSet.windows.front().windowId;
|
||||
}
|
||||
|
||||
void UpsertWindowState(
|
||||
UIEditorWindowWorkspaceSet& windowSet,
|
||||
UIEditorWindowWorkspaceState windowState) {
|
||||
if (UIEditorWindowWorkspaceState* existing =
|
||||
FindMutableUIEditorWindowWorkspaceState(windowSet, windowState.windowId);
|
||||
existing != nullptr) {
|
||||
*existing = std::move(windowState);
|
||||
return;
|
||||
}
|
||||
|
||||
windowSet.windows.push_back(std::move(windowState));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EditorWindowWorkspaceStore::EditorWindowWorkspaceStore(UIEditorPanelRegistry panelRegistry)
|
||||
: m_panelRegistry(std::move(panelRegistry)) {}
|
||||
|
||||
UIEditorWindowWorkspaceController EditorWindowWorkspaceStore::BuildMutationController() const {
|
||||
return UIEditorWindowWorkspaceController(m_panelRegistry, m_windowSet);
|
||||
}
|
||||
|
||||
bool EditorWindowWorkspaceStore::RegisterWindowProjection(
|
||||
std::string_view windowId,
|
||||
bool primary,
|
||||
const UIEditorWorkspaceController& workspaceController,
|
||||
std::string& outError) {
|
||||
UIEditorWindowWorkspaceSet nextWindowSet = m_windowSet;
|
||||
UpsertWindowState(nextWindowSet, BuildWindowState(windowId, workspaceController));
|
||||
|
||||
if (primary) {
|
||||
if (!nextWindowSet.primaryWindowId.empty() && nextWindowSet.primaryWindowId != windowId) {
|
||||
outError =
|
||||
"Cannot register a second primary window '" + std::string(windowId) +
|
||||
"' while '" + nextWindowSet.primaryWindowId + "' is still primary.";
|
||||
return false;
|
||||
}
|
||||
nextWindowSet.primaryWindowId = std::string(windowId);
|
||||
} else if (nextWindowSet.primaryWindowId.empty()) {
|
||||
outError =
|
||||
"Cannot register detached window '" + std::string(windowId) +
|
||||
"' before the primary window exists.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nextWindowSet.activeWindowId.empty() ||
|
||||
FindUIEditorWindowWorkspaceState(nextWindowSet, nextWindowSet.activeWindowId) == nullptr) {
|
||||
nextWindowSet.activeWindowId = ResolveFallbackWindowId(nextWindowSet);
|
||||
}
|
||||
|
||||
if (!ValidateWindowSet(nextWindowSet, outError)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReplaceWindowSet(std::move(nextWindowSet));
|
||||
outError.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorWindowWorkspaceStore::CommitWindowProjection(
|
||||
std::string_view windowId,
|
||||
const UIEditorWorkspaceController& workspaceController,
|
||||
std::string& outError) {
|
||||
UIEditorWindowWorkspaceSet nextWindowSet = m_windowSet;
|
||||
UIEditorWindowWorkspaceState* existingWindow =
|
||||
FindMutableUIEditorWindowWorkspaceState(nextWindowSet, windowId);
|
||||
if (existingWindow == nullptr) {
|
||||
outError = "Window '" + std::string(windowId) + "' is not registered in the workspace store.";
|
||||
return false;
|
||||
}
|
||||
|
||||
existingWindow->workspace = workspaceController.GetWorkspace();
|
||||
existingWindow->session = workspaceController.GetSession();
|
||||
|
||||
if (nextWindowSet.activeWindowId.empty() ||
|
||||
FindUIEditorWindowWorkspaceState(nextWindowSet, nextWindowSet.activeWindowId) == nullptr) {
|
||||
nextWindowSet.activeWindowId = ResolveFallbackWindowId(nextWindowSet);
|
||||
}
|
||||
|
||||
if (!ValidateWindowSet(nextWindowSet, outError)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReplaceWindowSet(std::move(nextWindowSet));
|
||||
outError.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorWindowWorkspaceStore::ValidateWindowSet(
|
||||
const UIEditorWindowWorkspaceSet& windowSet,
|
||||
std::string& outError) const {
|
||||
const UIEditorWindowWorkspaceValidationResult validation =
|
||||
ValidateUIEditorWindowWorkspaceSet(m_panelRegistry, windowSet);
|
||||
if (!validation.IsValid()) {
|
||||
outError = validation.message;
|
||||
return false;
|
||||
}
|
||||
|
||||
outError.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorWindowWorkspaceStore::ReplaceWindowSet(UIEditorWindowWorkspaceSet windowSet) {
|
||||
m_windowSet = std::move(windowSet);
|
||||
}
|
||||
|
||||
void EditorWindowWorkspaceStore::RemoveWindow(std::string_view windowId, bool primary) {
|
||||
if (m_windowSet.windows.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (primary || m_windowSet.primaryWindowId == windowId) {
|
||||
m_windowSet = {};
|
||||
return;
|
||||
}
|
||||
|
||||
m_windowSet.windows.erase(
|
||||
std::remove_if(
|
||||
m_windowSet.windows.begin(),
|
||||
m_windowSet.windows.end(),
|
||||
[windowId](const UIEditorWindowWorkspaceState& state) {
|
||||
return state.windowId == windowId;
|
||||
}),
|
||||
m_windowSet.windows.end());
|
||||
|
||||
if (m_windowSet.windows.empty()) {
|
||||
m_windowSet = {};
|
||||
return;
|
||||
}
|
||||
|
||||
if (FindUIEditorWindowWorkspaceState(m_windowSet, m_windowSet.primaryWindowId) == nullptr) {
|
||||
m_windowSet.primaryWindowId = ResolveFallbackWindowId(m_windowSet);
|
||||
}
|
||||
|
||||
if (m_windowSet.activeWindowId == windowId ||
|
||||
FindUIEditorWindowWorkspaceState(m_windowSet, m_windowSet.activeWindowId) == nullptr) {
|
||||
m_windowSet.activeWindowId = ResolveFallbackWindowId(m_windowSet);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App::Internal
|
||||
Reference in New Issue
Block a user