Internalize editor shell asset definition contract
This commit is contained in:
@@ -10,6 +10,10 @@
|
||||
|
||||
#include "Core/EditorShellAsset.h"
|
||||
|
||||
#include <XCEditor/Core/UIEditorShellInteraction.h>
|
||||
#include <XCEditor/Core/UIEditorShortcutManager.h>
|
||||
#include <XCEditor/Core/UIEditorWorkspaceController.h>
|
||||
|
||||
#include <XCEngine/UI/Runtime/UIScreenDocumentHost.h>
|
||||
#include <XCEngine/UI/Runtime/UIScreenPlayer.h>
|
||||
|
||||
@@ -24,6 +28,46 @@
|
||||
|
||||
namespace XCEngine::UI::Editor {
|
||||
|
||||
struct StructuredEditorShellBinding {
|
||||
::XCEngine::UI::Runtime::UIScreenAsset screenAsset = {};
|
||||
UIEditorWorkspaceController workspaceController = {};
|
||||
UIEditorShellInteractionDefinition shellDefinition = {};
|
||||
UIEditorShortcutManager shortcutManager = {};
|
||||
EditorShellAssetValidationResult assetValidation = {};
|
||||
|
||||
[[nodiscard]] bool IsValid() const {
|
||||
return assetValidation.IsValid();
|
||||
}
|
||||
};
|
||||
|
||||
inline UIEditorShortcutManager BuildStructuredEditorShortcutManager(
|
||||
const EditorShellAsset& asset) {
|
||||
(void)asset;
|
||||
return UIEditorShortcutManager(UIEditorCommandRegistry{});
|
||||
}
|
||||
|
||||
inline StructuredEditorShellBinding BuildStructuredEditorShellBinding(
|
||||
const EditorShellAsset& asset) {
|
||||
StructuredEditorShellBinding binding = {};
|
||||
binding.screenAsset.screenId = asset.screenId;
|
||||
binding.screenAsset.documentPath = asset.documentPath.string();
|
||||
binding.screenAsset.themePath = asset.themePath.string();
|
||||
binding.workspaceController =
|
||||
UIEditorWorkspaceController(asset.panelRegistry, asset.workspace, asset.workspaceSession);
|
||||
binding.shellDefinition = asset.shellDefinition;
|
||||
binding.shortcutManager = BuildStructuredEditorShortcutManager(asset);
|
||||
binding.assetValidation = ValidateEditorShellAsset(asset);
|
||||
return binding;
|
||||
}
|
||||
|
||||
inline UIEditorShellInteractionServices BuildStructuredEditorShellServices(
|
||||
const StructuredEditorShellBinding& binding) {
|
||||
UIEditorShellInteractionServices services = {};
|
||||
services.commandDispatcher = &binding.shortcutManager.GetCommandDispatcher();
|
||||
services.shortcutManager = &binding.shortcutManager;
|
||||
return services;
|
||||
}
|
||||
|
||||
class Application {
|
||||
public:
|
||||
Application();
|
||||
@@ -65,6 +109,8 @@ private:
|
||||
::XCEngine::UI::Runtime::UIScreenPlayer m_screenPlayer;
|
||||
::XCEngine::UI::Runtime::UIScreenAsset m_screenAsset = {};
|
||||
EditorShellAsset m_shellAssetDefinition = {};
|
||||
StructuredEditorShellBinding m_structuredShell = {};
|
||||
UIEditorShellInteractionServices m_shellServices = {};
|
||||
std::vector<TrackedFileState> m_trackedFiles = {};
|
||||
std::chrono::steady_clock::time_point m_startTime = {};
|
||||
std::chrono::steady_clock::time_point m_lastFrameTime = {};
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
#include "EditorShellAsset.h"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine::UI::Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
Widgets::UIEditorStatusBarSegment BuildDefaultShellModeSegment() {
|
||||
Widgets::UIEditorStatusBarSegment segment = {};
|
||||
segment.segmentId = "mode";
|
||||
segment.label = "Editor Shell";
|
||||
segment.slot = Widgets::UIEditorStatusBarSlot::Leading;
|
||||
segment.tone = Widgets::UIEditorStatusBarTextTone::Primary;
|
||||
segment.interactive = false;
|
||||
segment.showSeparator = true;
|
||||
segment.desiredWidth = 112.0f;
|
||||
return segment;
|
||||
}
|
||||
|
||||
EditorShellAssetValidationResult MakeValidationError(
|
||||
EditorShellAssetValidationCode code,
|
||||
std::string message) {
|
||||
@@ -53,6 +66,74 @@ EditorShellAssetValidationResult ValidateWorkspacePanelsAgainstRegistry(
|
||||
return {};
|
||||
}
|
||||
|
||||
EditorShellAssetValidationResult ValidateShellDefinitionAgainstRegistry(
|
||||
const UIEditorShellInteractionDefinition& definition,
|
||||
const UIEditorPanelRegistry& panelRegistry) {
|
||||
std::unordered_set<std::string> panelIds = {};
|
||||
for (const UIEditorWorkspacePanelPresentationModel& presentation :
|
||||
definition.workspacePresentations) {
|
||||
if (!panelIds.insert(presentation.panelId).second) {
|
||||
return MakeValidationError(
|
||||
EditorShellAssetValidationCode::DuplicateShellPresentationPanelId,
|
||||
"Shell definition presentation panel '" + presentation.panelId +
|
||||
"' is duplicated.");
|
||||
}
|
||||
|
||||
const UIEditorPanelDescriptor* descriptor =
|
||||
FindUIEditorPanelDescriptor(panelRegistry, presentation.panelId);
|
||||
if (descriptor == nullptr) {
|
||||
return MakeValidationError(
|
||||
EditorShellAssetValidationCode::MissingShellPresentationPanelDescriptor,
|
||||
"Shell definition presentation panel '" + presentation.panelId +
|
||||
"' is missing from the panel registry.");
|
||||
}
|
||||
|
||||
if (presentation.kind != descriptor->presentationKind) {
|
||||
return MakeValidationError(
|
||||
EditorShellAssetValidationCode::ShellPresentationKindMismatch,
|
||||
"Shell definition presentation panel '" + presentation.panelId +
|
||||
"' kind does not match the panel registry.");
|
||||
}
|
||||
}
|
||||
|
||||
for (const UIEditorPanelDescriptor& descriptor : panelRegistry.panels) {
|
||||
if (panelIds.find(descriptor.panelId) == panelIds.end()) {
|
||||
return MakeValidationError(
|
||||
EditorShellAssetValidationCode::MissingRequiredShellPresentation,
|
||||
"Shell definition is missing presentation panel '" + descriptor.panelId +
|
||||
"' required by the panel registry.");
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
UIEditorWorkspacePanelPresentationModel BuildShellPresentation(
|
||||
const UIEditorPanelDescriptor& descriptor) {
|
||||
UIEditorWorkspacePanelPresentationModel presentation = {};
|
||||
presentation.panelId = descriptor.panelId;
|
||||
presentation.kind = descriptor.presentationKind;
|
||||
if (descriptor.presentationKind == UIEditorPanelPresentationKind::ViewportShell) {
|
||||
presentation.viewportShellModel.spec.chrome.title = descriptor.defaultTitle;
|
||||
presentation.viewportShellModel.spec.chrome.subtitle = "Editor Shell";
|
||||
presentation.viewportShellModel.spec.chrome.showTopBar = true;
|
||||
presentation.viewportShellModel.spec.chrome.showBottomBar = true;
|
||||
presentation.viewportShellModel.frame.statusText = descriptor.defaultTitle;
|
||||
}
|
||||
return presentation;
|
||||
}
|
||||
|
||||
UIEditorShellInteractionDefinition BuildDefaultShellDefinition(
|
||||
const UIEditorPanelRegistry& panelRegistry) {
|
||||
UIEditorShellInteractionDefinition definition = {};
|
||||
definition.statusSegments = { BuildDefaultShellModeSegment() };
|
||||
definition.workspacePresentations.reserve(panelRegistry.panels.size());
|
||||
for (const UIEditorPanelDescriptor& descriptor : panelRegistry.panels) {
|
||||
definition.workspacePresentations.push_back(BuildShellPresentation(descriptor));
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EditorShellAsset BuildDefaultEditorShellAsset(const std::filesystem::path& repoRoot) {
|
||||
@@ -63,6 +144,7 @@ EditorShellAsset BuildDefaultEditorShellAsset(const std::filesystem::path& repoR
|
||||
asset.panelRegistry = BuildDefaultEditorShellPanelRegistry();
|
||||
asset.workspace = BuildDefaultEditorShellWorkspaceModel();
|
||||
asset.workspaceSession = BuildDefaultUIEditorWorkspaceSession(asset.panelRegistry, asset.workspace);
|
||||
asset.shellDefinition = BuildDefaultShellDefinition(asset.panelRegistry);
|
||||
return asset;
|
||||
}
|
||||
|
||||
@@ -100,6 +182,12 @@ EditorShellAssetValidationResult ValidateEditorShellAsset(const EditorShellAsset
|
||||
workspaceSessionValidation.message);
|
||||
}
|
||||
|
||||
const EditorShellAssetValidationResult shellDefinitionValidation =
|
||||
ValidateShellDefinitionAgainstRegistry(asset.shellDefinition, asset.panelRegistry);
|
||||
if (!shellDefinitionValidation.IsValid()) {
|
||||
return shellDefinitionValidation;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEditor/Core/UIEditorShellInteraction.h>
|
||||
#include <XCEditor/Core/UIEditorPanelRegistry.h>
|
||||
#include <XCEditor/Core/UIEditorWorkspaceModel.h>
|
||||
#include <XCEditor/Core/UIEditorWorkspaceSession.h>
|
||||
@@ -18,6 +19,7 @@ struct EditorShellAsset {
|
||||
UIEditorPanelRegistry panelRegistry = {};
|
||||
UIEditorWorkspaceModel workspace = {};
|
||||
UIEditorWorkspaceSession workspaceSession = {};
|
||||
UIEditorShellInteractionDefinition shellDefinition = {};
|
||||
};
|
||||
|
||||
enum class EditorShellAssetValidationCode : std::uint8_t {
|
||||
@@ -27,7 +29,11 @@ enum class EditorShellAssetValidationCode : std::uint8_t {
|
||||
InvalidWorkspaceSession,
|
||||
MissingPanelDescriptor,
|
||||
PanelTitleMismatch,
|
||||
PanelPlaceholderMismatch
|
||||
PanelPlaceholderMismatch,
|
||||
DuplicateShellPresentationPanelId,
|
||||
MissingShellPresentationPanelDescriptor,
|
||||
MissingRequiredShellPresentation,
|
||||
ShellPresentationKindMismatch
|
||||
};
|
||||
|
||||
struct EditorShellAssetValidationResult {
|
||||
|
||||
Reference in New Issue
Block a user