# MainMenuActionRouter **命名空间**: `XCEngine::Editor::Actions` **类型**: `header-helper` **源文件**: `editor/src/Actions/MainMenuActionRouter.h` **描述**: 主菜单栏动作路由层,负责把 File / Edit / Run / Scripts / View / Help 菜单项与全局快捷键翻译成 `Commands` 调用或 `EventBus` 请求事件。 ## 概述 `MainMenuActionRouter` 当前是 [MenuBar](../../panels/MenuBar/MenuBar.md) 的顶层工作流入口,而不只是几个 `ImGui::MenuItem` 的薄封装。 按当前源码,它把三类链路汇到一起: - 项目 / 场景文档命令 - Play mode 请求事件 - 布局与 About 这类宿主级 UI 事件 这页最需要和旧文档区分的一点是: - 当前菜单里已经没有旧的场景资源迁移入口 - 项目维护相关的真实菜单项现在只有 `Save Project` 与 `Scripts -> Rebuild Script Assemblies` ## 当前菜单结构 ### File `DrawFileMenuActions(context)` 当前按顺序绘制: - `New Project...` - `Open Project...` - `Save Project` - `New Scene` - `Open Scene` - `Save Scene` - `Save Scene As...` - `Exit` 对应执行链路分别是: - `ExecuteNewProject()` -> `Commands::NewProjectWithDialog(context)` - `ExecuteOpenProject()` -> `Commands::OpenProjectWithDialog(context)` - `ExecuteSaveProject()` -> `Commands::SaveProject(context)` - `ExecuteNewScene()` -> `Commands::NewScene(context)` - `ExecuteOpenScene()` -> `Commands::OpenSceneWithDialog(context)` - `ExecuteSaveScene()` -> `Commands::SaveCurrentScene(context)` - `ExecuteSaveSceneAs()` -> `Commands::SaveSceneAsWithDialog(context)` - `RequestEditorExit()` -> `EditorExitRequestedEvent` 这里要注意两个实现语义: - `MainMenuActionRouter` 自己不处理保存结果弹窗;它只负责转接到 `Commands` - `Save Project` 与场景保存一样,都受 `IsEditorDocumentEditingAllowed(...)` 约束 ### Edit `Edit` 菜单继续委托给 [EditActionRouter](../EditActionRouter/EditActionRouter.md),因此复制、粘贴、删除和重命名等上下文编辑行为不在这里重复定义。 ### Run `DrawRunMenuActions(context)` 当前提供: - `Play` / `Stop` - `Pause` / `Resume` - `Step` 这些入口不直接推进运行时,而是分别走: - `RequestTogglePlayMode()` -> `PlayModeStartRequestedEvent` / `PlayModeStopRequestedEvent` - `RequestTogglePauseMode()` -> `PlayModePauseRequestedEvent` / `PlayModeResumeRequestedEvent` - `RequestStepPlayMode()` -> `PlayModeStepRequestedEvent` 因此 Run 菜单本质上是 [EventBus](../../Core/EventBus/EventBus.md) 的请求端。 ### Scripts `DrawScriptsMenuActions(context)` 当前只有一个入口: - `Rebuild Script Assemblies` 完整链路是: ```text MainMenuActionRouter -> ExecuteRebuildScriptAssemblies(context) -> Commands::RebuildScriptAssemblies(context) -> Application::Get().RebuildScriptingAssemblies() -> 成功时 ProjectManager.RefreshCurrentFolder() ``` 菜单启用状态由 `Commands::CanRebuildScriptAssemblies(context)` 控制,而不是菜单层自己猜测。 菜单层当前不会消费 `RebuildScriptAssemblies(...)` 的布尔返回值。成功或失败的反馈主要依赖下游日志、脚本状态页和后续 UI 状态。 ### View / Help - `View -> Reset Layout` 发布 `DockLayoutResetRequestedEvent` - `Help -> About` 通过 [`DeferredPopupState`](../../UI/PopupState/DeferredPopupState.md) 请求打开 About 对话框 ## 快捷键与可用性 `HandleMenuBarShortcuts(context)` 当前只处理: - Play / Pause / Step - New / Open / Save Scene - Undo / Redo - `EditActionRouter` 定义的编辑快捷键 项目级菜单项当前都还是“菜单点击入口”,没有绑定全局快捷键,包括: - `New Project...` - `Open Project...` - `Save Project` - `Rebuild Script Assemblies` 菜单启用状态则基于四组条件: - `canEditDocuments` - `canPause` - `canStep` - 下游 `ProjectCommands` 返回的 guard,如 `CanRebuildScriptAssemblies(...)` 其中项目维护相关项有一个共同前提:当前 runtime mode 必须允许文档编辑。换句话说,在 `Play` / `Paused` 期间,`Save Project` 和 `Rebuild Script Assemblies` 这类会改动项目内容的入口都会被禁用。 ## 和下游项目工作流的关系 当前和项目工作流相关的主链路可以概括成: ```text MenuBar -> MainMenuActionRouter -> ProjectCommands -> Application / IProjectManager -> ProjectManager / SceneManager / ProjectPanel ``` 其中: - “保存项目”最终落到 [`ProjectCommands::SaveProject`](../../Commands/ProjectCommands/ProjectCommands.md)。 - “重建脚本程序集”最终落到 [`Application::RebuildScriptingAssemblies`](../../Application/RebuildScriptingAssemblies.md)。 - `ProjectPanel` 本身不暴露这两个入口,但会在下游 `RefreshCurrentFolder()` 之后同步自己的 `Assets` 视图。 这里再补一个容易误解的点: - `Rebuild Script Assemblies` 产物主要在 `/Library/ScriptAssemblies` - 而 `ProjectPanel` 只投影 `/Assets` 所以脚本重建成功后,菜单链路虽然会触发一次 `RefreshCurrentFolder()`,但它不保证 Project 面板一定出现肉眼可见的树变化。 ## 测试锚点 `tests/Editor/test_action_routing.cpp` 当前直接或间接覆盖了这组路由的关键行为: - `MainMenuRouterRequestsExitResetAndAboutPopup` - `MainMenuRouterRequestsPlayPauseResumeAndStepEvents` - `ProjectCommandsReportWhenScriptAssembliesCanBeRebuilt` 前两项验证菜单层事件路由,最后一项验证 `Scripts` 菜单下游命令的可用性。 ## 当前限制 - 主菜单动作仍以内联 helper 形式定义在头文件中,不是可注册的命令表。 - 项目级菜单项当前没有默认快捷键。 - `MainMenuActionRouter` 自己不展示保存结果或脚本重建结果摘要;返回值在这一层不会被消费,反馈更多依赖下游日志与状态页。 - 文件菜单还没有 recent projects、project settings、build profiles 等更完整的项目入口。 ## 相关文档 - [Actions](../Actions.md) - [EditorActions](../EditorActions/EditorActions.md) - [EditActionRouter](../EditActionRouter/EditActionRouter.md) - [MenuBar](../../panels/MenuBar/MenuBar.md) - [ProjectCommands](../../Commands/ProjectCommands/ProjectCommands.md) - [SceneCommands](../../Commands/SceneCommands/SceneCommands.md) - [EventBus](../../Core/EventBus/EventBus.md) - [PopupState](../../UI/PopupState/PopupState.md)