diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index aad7fbf95..908ba02c7 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -3777,7 +3777,6 @@ static void RequireMainMenuSettingsShellUsesEveSurface(string root) "ProjectMainMenuSurfaceState(", "new AetheriaRuntimePlayerSettingsSurfaceState(", "new AetheriaRuntimeClientTargetSurfaceState(", - "new AetheriaRuntimeMainMenuSurfaceState(", "_nextMenu.panel.Title.text = \"settings\"", "_nextMenu.panel.Title.text = TitleSubtitle(\"input\", \"settings\")", "_nextMenu.panel.Title.text = TitleSubtitle(\"audio\", \"settings\")" @@ -3802,8 +3801,9 @@ static void RequireMainMenuSettingsShellUsesEveSurface(string root) "BuildInputSettings(", "BuildPlayerSettingsShell(", "BuildVerseSettingsShell(", - "private static AetheriaRuntimeMainMenuSurfaceState ComposeRootState(", - "private static AetheriaRuntimePlayerSettingsSurfaceState ComposePlayerSettingsState(", + "private static AetheriaRuntimeSurfaceDocument BuildRoot(", + "private static AetheriaRuntimeSurfaceDocument BuildInputSettings(", + "var verseLabel = VerseLabel(verseTitle, verseId)", "AetheriaRuntimePlayerSettingsSurfaceBuilder.Build(state, version)", "AetheriaRuntimeSurfaceDocument document", "WithBackAction(", @@ -3827,11 +3827,14 @@ static void RequireMainMenuSettingsShellUsesEveSurface(string root) string.Join(", ", missingBuilderSymbols)); } - if (mainMenuSurfaceBuilder.Contains("public static AetheriaRuntimeMainMenuSurfaceState Project", StringComparison.Ordinal) || + if (mainMenuSurfaceBuilder.Contains("AetheriaRuntimeMainMenuSurfaceState", StringComparison.Ordinal) || + mainMenuSurfaceBuilder.Contains("ComposeRootState(", StringComparison.Ordinal) || + mainMenuSurfaceBuilder.Contains("ComposePlayerSettingsState(", StringComparison.Ordinal) || + mainMenuSurfaceBuilder.Contains("public static AetheriaRuntimeMainMenuSurfaceState Project", StringComparison.Ordinal) || mainMenuSurfaceBuilder.Contains("public static AetheriaRuntimePlayerSettingsSurfaceState Project", StringComparison.Ordinal)) { throw new InvalidOperationException( - "Shared main-menu surface builder must accept typed documents and return finished Eve documents; do not re-expose public Project helpers."); + "Shared main-menu surface builder must accept typed documents and return finished Eve documents; do not rebuild a shadow main-menu SurfaceState projection layer."); } } @@ -3953,7 +3956,8 @@ static void RequireMainMenuRootUsesEveSurface(string root) "AetheriaRuntimeMainMenuCommands.NewGame", "AetheriaRuntimeMainMenuCommands.ShowSettings", "AetheriaRuntimeMainMenuCommands.Quit", - "AetheriaRuntimeMainMenuSurfaceState", + "private static AetheriaRuntimeSurfaceDocument BuildRoot(", + "var verseLabel = VerseLabel(verseTitle, verseId)", "public enum AetheriaRuntimeMainMenuCommandKind", "public readonly struct AetheriaRuntimeMainMenuCommand", "public static class AetheriaRuntimeMainMenuSurfaceCommands", @@ -4175,7 +4179,8 @@ static void RequireMainMenuInputSettingsDelegateToRuntimeScreen(string root) } if (!mainMenuSurfaceBuilder.Contains("AetheriaRuntimeMainMenuCommands.OpenRuntimeInputScreen", StringComparison.Ordinal) || - !mainMenuSurfaceBuilder.Contains("CanOpenRuntimeInputScreen", StringComparison.Ordinal)) + !mainMenuSurfaceBuilder.Contains("bool canOpenRuntimeInputScreen", StringComparison.Ordinal) || + !mainMenuSurfaceBuilder.Contains("if (canOpenRuntimeInputScreen)", StringComparison.Ordinal)) { throw new InvalidOperationException( "Shared main-menu input surface no longer exposes the runtime input-screen handoff."); @@ -9433,7 +9438,8 @@ static void RequireClientTargetBootAuthority(string root) }; var requiredMainMenuBuilderSymbols = new[] { - "AetheriaRuntimeMainMenuSurfaceState", + "private static AetheriaRuntimeSurfaceDocument BuildRoot(", + "var verseLabel = VerseLabel(verseTitle, verseId)", "\"Client Target\"", "\"Transport\"", "\"Target Source\"" diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs index 884e0c489..0361da039 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs @@ -25,69 +25,6 @@ namespace GameCult.Aetheria.State.Verse public const string BackToSettings = "aetheria.main_menu.settings.back_to_settings"; } - public sealed class AetheriaRuntimeMainMenuSurfaceState - { - public AetheriaRuntimeMainMenuSurfaceState( - string targetLabel, - string targetKind, - string targetSource, - string verseTitle, - string verseId, - string verseVisibility, - string verseCultMeshAddress, - bool inGame, - bool hasAuthoritativeDaemonFrame, - string daemonRunId, - long daemonFrameId, - int bindingOverrideCount, - int actionBarInputCount, - bool canOpenRuntimeInputScreen, - string updatedAtUtc) - { - TargetLabel = targetLabel ?? ""; - TargetKind = targetKind ?? ""; - TargetSource = targetSource ?? ""; - VerseTitle = verseTitle ?? ""; - VerseId = verseId ?? ""; - VerseVisibility = verseVisibility ?? ""; - VerseCultMeshAddress = verseCultMeshAddress ?? ""; - InGame = inGame; - HasAuthoritativeDaemonFrame = hasAuthoritativeDaemonFrame; - DaemonRunId = daemonRunId ?? ""; - DaemonFrameId = daemonFrameId; - BindingOverrideCount = bindingOverrideCount; - ActionBarInputCount = actionBarInputCount; - CanOpenRuntimeInputScreen = canOpenRuntimeInputScreen; - UpdatedAtUtc = updatedAtUtc ?? ""; - } - - public string TargetLabel { get; } - public string TargetKind { get; } - public string TargetSource { get; } - public string VerseTitle { get; } - public string VerseId { get; } - public string VerseVisibility { get; } - public string VerseCultMeshAddress { get; } - public bool InGame { get; } - public bool HasAuthoritativeDaemonFrame { get; } - public string DaemonRunId { get; } - public long DaemonFrameId { get; } - public int BindingOverrideCount { get; } - public int ActionBarInputCount { get; } - public bool CanOpenRuntimeInputScreen { get; } - public string UpdatedAtUtc { get; } - - public string VerseLabel - { - get - { - var title = string.IsNullOrWhiteSpace(VerseTitle) ? "Unknown Verse" : VerseTitle; - var verseId = string.IsNullOrWhiteSpace(VerseId) ? "unknown" : VerseId; - return string.Equals(title, verseId, StringComparison.Ordinal) ? title : $"{title} ({verseId})"; - } - } - } - public static class AetheriaRuntimeMainMenuSurfaceBuilder { public static AetheriaRuntimeSurfaceDocument BuildRoot( @@ -99,67 +36,6 @@ namespace GameCult.Aetheria.State.Verse long version = 1) { return BuildRoot( - ComposeRootState( - stateBoot, - playerSettings, - canOpenRuntimeInputScreen, - inGame, - updatedAtUtc), - version); - } - - public static AetheriaRuntimeSurfaceDocument BuildRoot( - AetheriaRuntimeStateBootReport stateBoot, - AetheriaRuntimeDaemonFrameDocument daemonFrame, - AetheriaRuntimeVerseHostSettingsDocument verseHost, - AetheriaRuntimePlayerSettingsDocument playerSettings, - bool canOpenRuntimeInputScreen, - bool inGame, - string updatedAtUtc, - long version = 1) - { - return BuildRoot( - ComposeRootState( - stateBoot, - daemonFrame, - verseHost, - playerSettings, - canOpenRuntimeInputScreen, - inGame, - updatedAtUtc), - version); - } - - public static AetheriaRuntimeSurfaceDocument BuildRoot( - AetheriaRuntimeStateBootReport stateBoot, - AetheriaRuntimeSectorMapDocument sectorMap, - AetheriaRuntimeVerseHostSettingsDocument verseHost, - AetheriaRuntimePlayerSettingsDocument playerSettings, - bool canOpenRuntimeInputScreen, - bool inGame, - string updatedAtUtc, - long version = 1) - { - return BuildRoot( - ComposeRootState( - stateBoot, - sectorMap, - verseHost, - playerSettings, - canOpenRuntimeInputScreen, - inGame, - updatedAtUtc), - version); - } - - private static AetheriaRuntimeMainMenuSurfaceState ComposeRootState( - AetheriaRuntimeStateBootReport stateBoot, - AetheriaRuntimePlayerSettingsDocument playerSettings, - bool canOpenRuntimeInputScreen, - bool inGame, - string updatedAtUtc) - { - return new AetheriaRuntimeMainMenuSurfaceState( stateBoot.TargetLabel, stateBoot.TargetKind, stateBoot.TargetSource, @@ -168,25 +44,24 @@ namespace GameCult.Aetheria.State.Verse "unknown", stateBoot.CultMeshAddress, inGame, - false, - "", - -1, - playerSettings?.BindingOverrides?.Length ?? 0, - playerSettings?.ActionBarInputs?.Length ?? 0, - canOpenRuntimeInputScreen, - updatedAtUtc); + hasAuthoritativeDaemonFrame: false, + daemonRunId: "", + daemonFrameId: -1, + updatedAtUtc, + version); } - private static AetheriaRuntimeMainMenuSurfaceState ComposeRootState( + public static AetheriaRuntimeSurfaceDocument BuildRoot( AetheriaRuntimeStateBootReport stateBoot, AetheriaRuntimeDaemonFrameDocument daemonFrame, AetheriaRuntimeVerseHostSettingsDocument verseHost, AetheriaRuntimePlayerSettingsDocument playerSettings, bool canOpenRuntimeInputScreen, bool inGame, - string updatedAtUtc) + string updatedAtUtc, + long version = 1) { - return new AetheriaRuntimeMainMenuSurfaceState( + return BuildRoot( stateBoot.TargetLabel, stateBoot.TargetKind, stateBoot.TargetSource, @@ -195,25 +70,24 @@ namespace GameCult.Aetheria.State.Verse verseHost?.Visibility ?? "unknown", verseHost?.CultMeshAddress ?? stateBoot.CultMeshAddress, inGame, - daemonFrame != null, + hasAuthoritativeDaemonFrame: daemonFrame != null, daemonFrame?.Run?.RunId ?? "", daemonFrame?.FrameId ?? -1, - playerSettings?.BindingOverrides?.Length ?? 0, - playerSettings?.ActionBarInputs?.Length ?? 0, - canOpenRuntimeInputScreen, - updatedAtUtc); + updatedAtUtc, + version); } - private static AetheriaRuntimeMainMenuSurfaceState ComposeRootState( + public static AetheriaRuntimeSurfaceDocument BuildRoot( AetheriaRuntimeStateBootReport stateBoot, AetheriaRuntimeSectorMapDocument sectorMap, AetheriaRuntimeVerseHostSettingsDocument verseHost, AetheriaRuntimePlayerSettingsDocument playerSettings, bool canOpenRuntimeInputScreen, bool inGame, - string updatedAtUtc) + string updatedAtUtc, + long version = 1) { - return new AetheriaRuntimeMainMenuSurfaceState( + return BuildRoot( stateBoot.TargetLabel, stateBoot.TargetKind, stateBoot.TargetSource, @@ -222,13 +96,11 @@ namespace GameCult.Aetheria.State.Verse verseHost?.Visibility ?? "unknown", verseHost?.CultMeshAddress ?? stateBoot.CultMeshAddress, inGame, - sectorMap != null, + hasAuthoritativeDaemonFrame: sectorMap != null, sectorMap?.RunId ?? "", sectorMap?.FrameId ?? -1, - playerSettings?.BindingOverrides?.Length ?? 0, - playerSettings?.ActionBarInputs?.Length ?? 0, - canOpenRuntimeInputScreen, - updatedAtUtc); + updatedAtUtc, + version); } public static AetheriaRuntimeSurfaceDocument BuildInputSettings( @@ -240,12 +112,11 @@ namespace GameCult.Aetheria.State.Verse long version = 1) { return BuildInputSettings( - ComposeRootState( - stateBoot, - playerSettings, - canOpenRuntimeInputScreen, - inGame, - updatedAtUtc), + playerSettings?.BindingOverrides?.Length ?? 0, + playerSettings?.ActionBarInputs?.Length ?? 0, + canOpenRuntimeInputScreen, + inGame, + updatedAtUtc, version); } @@ -254,14 +125,7 @@ namespace GameCult.Aetheria.State.Verse string updatedAtUtc, long version = 1) { - return BuildPlayerSettingsShell(ComposePlayerSettingsState(playerSettings, updatedAtUtc), version); - } - - private static AetheriaRuntimePlayerSettingsSurfaceState ComposePlayerSettingsState( - AetheriaRuntimePlayerSettingsDocument playerSettings, - string updatedAtUtc) - { - return new AetheriaRuntimePlayerSettingsSurfaceState( + var state = new AetheriaRuntimePlayerSettingsSurfaceState( playerSettings?.PlayerName ?? "", playerSettings?.TutorialPassed ?? false, "", @@ -270,29 +134,41 @@ namespace GameCult.Aetheria.State.Verse playerSettings?.NebulaQuality ?? "", playerSettings?.ShowAsteroidsInMinimap ?? false, updatedAtUtc); + + return BuildPlayerSettingsShell(state, version); } - public static AetheriaRuntimeSurfaceDocument BuildRoot( - AetheriaRuntimeMainMenuSurfaceState state, - long version = 1) + private static AetheriaRuntimeSurfaceDocument BuildRoot( + string targetLabel, + string targetKind, + string targetSource, + string verseTitle, + string verseId, + string verseVisibility, + string verseCultMeshAddress, + bool inGame, + bool hasAuthoritativeDaemonFrame, + string daemonRunId, + long daemonFrameId, + string updatedAtUtc, + long version) { - state ??= EmptyState(); - var commands = new List(); var actionButtons = new List(); var cardChildren = new List(); - var targetKind = string.IsNullOrWhiteSpace(state.TargetKind) ? "unknown" : state.TargetKind; - var targetSource = string.IsNullOrWhiteSpace(state.TargetSource) ? "unknown" : state.TargetSource; - var verseVisibility = string.IsNullOrWhiteSpace(state.VerseVisibility) ? "unknown" : state.VerseVisibility; - var verseMeshAddress = string.IsNullOrWhiteSpace(state.VerseCultMeshAddress) ? "unpublished" : state.VerseCultMeshAddress; + targetKind = string.IsNullOrWhiteSpace(targetKind) ? "unknown" : targetKind; + targetSource = string.IsNullOrWhiteSpace(targetSource) ? "unknown" : targetSource; + verseVisibility = string.IsNullOrWhiteSpace(verseVisibility) ? "unknown" : verseVisibility; + var verseMeshAddress = string.IsNullOrWhiteSpace(verseCultMeshAddress) ? "unpublished" : verseCultMeshAddress; + var verseLabel = VerseLabel(verseTitle, verseId); - if (!state.InGame) + if (!inGame) { - if (!state.HasAuthoritativeDaemonFrame) + if (!hasAuthoritativeDaemonFrame) { cardChildren.Add(Text( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.continue.note", - $"No authoritative daemon frame is available in {state.VerseLabel} yet. Start or connect a daemon before opening the observer scene.")); + $"No authoritative daemon frame is available in {verseLabel} yet. Start or connect a daemon before opening the observer scene.")); } else { @@ -304,18 +180,18 @@ namespace GameCult.Aetheria.State.Verse cardChildren.Add(Metric( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.continue.run", "Daemon Run", - state.DaemonRunId)); + daemonRunId)); cardChildren.Add(Metric( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.continue.frame", "Daemon Frame", - state.DaemonFrameId.ToString())); + daemonFrameId.ToString())); } } cardChildren.Add(Metric( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.target.title", "Client Target", - state.TargetLabel)); + targetLabel)); cardChildren.Add(Metric( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.target.transport", "Transport", @@ -327,7 +203,7 @@ namespace GameCult.Aetheria.State.Verse cardChildren.Add(Metric( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.verse.title", "Verse", - state.VerseLabel)); + verseLabel)); cardChildren.Add(Metric( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.verse.visibility", "Visibility", @@ -347,13 +223,13 @@ namespace GameCult.Aetheria.State.Verse cardChildren.Add(Text( $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.note", - $"The client lowers this shell through Eve. The client target chooses which Verse it follows; game truth belongs to the daemon serving {state.VerseLabel}.")); + $"The client lowers this shell through Eve. The client target chooses which Verse it follows; game truth belongs to the daemon serving {verseLabel}.")); cardChildren.Add(ButtonColumn($"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.actions", actionButtons.ToArray())); return BuildSurfaceDocument( AetheriaRuntimeMainMenuCommands.RootSurfaceId, "Aetheria Terminus", - state.UpdatedAtUtc, + updatedAtUtc, version, commands, Card( @@ -392,12 +268,14 @@ namespace GameCult.Aetheria.State.Verse Button("aetheria.mainMenu.settings.back", "Back", AetheriaRuntimeMainMenuCommands.BackToMain)))); } - public static AetheriaRuntimeSurfaceDocument BuildInputSettings( - AetheriaRuntimeMainMenuSurfaceState state, - long version = 1) + private static AetheriaRuntimeSurfaceDocument BuildInputSettings( + int bindingOverrideCount, + int actionBarInputCount, + bool canOpenRuntimeInputScreen, + bool inGame, + string updatedAtUtc, + long version) { - state ??= EmptyState(); - var commands = new List { Command(AetheriaRuntimeMainMenuCommands.BackToSettings, "Back") @@ -408,21 +286,21 @@ namespace GameCult.Aetheria.State.Verse Metric( "aetheria.mainMenu.input.bindingOverrides", "Binding Overrides", - state.BindingOverrideCount.ToString()), + bindingOverrideCount.ToString()), Metric( "aetheria.mainMenu.input.actionBarInputs", "Action-Bar Inputs", - state.ActionBarInputCount.ToString()) + actionBarInputCount.ToString()) }; - if (state.CanOpenRuntimeInputScreen) + if (canOpenRuntimeInputScreen) { commands.Insert(0, Command(AetheriaRuntimeMainMenuCommands.OpenRuntimeInputScreen, "Open Remap Screen")); cardChildren.Add(Text( "aetheria.mainMenu.input.note", "The runtime Eve input screen owns low-level InputSystem rebinding and action-bar input edits. This title shell reports typed player-settings state and hands off to that owner.")); } - else if (state.InGame) + else if (inGame) { cardChildren.Add(Text( "aetheria.mainMenu.input.note", @@ -436,7 +314,7 @@ namespace GameCult.Aetheria.State.Verse } var buttons = new List(); - if (state.CanOpenRuntimeInputScreen) + if (canOpenRuntimeInputScreen) { buttons.Add(Button( "aetheria.mainMenu.input.openRuntimeScreen", @@ -450,7 +328,7 @@ namespace GameCult.Aetheria.State.Verse return BuildSurfaceDocument( AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId, "Aetheria Input Settings", - state.UpdatedAtUtc, + updatedAtUtc, version, commands, Card( @@ -511,24 +389,11 @@ namespace GameCult.Aetheria.State.Verse .ToArray()); } - private static AetheriaRuntimeMainMenuSurfaceState EmptyState() + private static string VerseLabel(string verseTitle, string verseId) { - return new AetheriaRuntimeMainMenuSurfaceState( - "", - "", - "", - "", - "", - "", - "", - inGame: false, - hasAuthoritativeDaemonFrame: false, - daemonRunId: "", - daemonFrameId: -1, - bindingOverrideCount: 0, - actionBarInputCount: 0, - canOpenRuntimeInputScreen: false, - updatedAtUtc: ""); + var title = string.IsNullOrWhiteSpace(verseTitle) ? "Unknown Verse" : verseTitle; + var id = string.IsNullOrWhiteSpace(verseId) ? "unknown" : verseId; + return string.Equals(title, id, StringComparison.Ordinal) ? title : $"{title} ({id})"; } private static AetheriaRuntimeSurfaceDocument BuildSurfaceDocument(