From 2e5cf53ba1a41ef3f28e89dcfbb42c3b6e66c48b Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 29 Jun 2026 03:48:39 +0100 Subject: [PATCH] Move Eve surface state lowering into runtime adapter --- Aetheria.State.Daemon/Program.cs | 8 +- Aetheria.State.Smoke/Program.cs | 2 +- Aetheria.State.Verify/Program.cs | 44 ++++++---- ...AetheriaRuntimeEveSurfaceStateProjector.cs | 80 ------------------- .../AetheriaRuntimeEveSurfaceAdapter.cs | 77 ++++++++++++++++++ 5 files changed, 110 insertions(+), 101 deletions(-) delete mode 100644 Aetheria.State/AetheriaRuntimeEveSurfaceStateProjector.cs diff --git a/Aetheria.State.Daemon/Program.cs b/Aetheria.State.Daemon/Program.cs index 3ac0fa722..d2d8cb722 100644 --- a/Aetheria.State.Daemon/Program.cs +++ b/Aetheria.State.Daemon/Program.cs @@ -780,19 +780,19 @@ static async Task PublishDaemonApiDocumentsAsync( .ConfigureAwait(false); if (result.GameSurface != null) await node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface) - .ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.GameSurface)) + .ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.GameSurface)) .ConfigureAwait(false); if (result.GameTuiSurface != null) await node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface) - .ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.GameTuiSurface)) + .ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.GameTuiSurface)) .ConfigureAwait(false); if (result.EditorSurface != null) await node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface) - .ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.EditorSurface)) + .ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.EditorSurface)) .ConfigureAwait(false); if (result.EditorTuiSurface != null) await node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonEditorTuiSurface) - .ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.EditorTuiSurface)) + .ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.EditorTuiSurface)) .ConfigureAwait(false); } diff --git a/Aetheria.State.Smoke/Program.cs b/Aetheria.State.Smoke/Program.cs index ea154edc1..0a1f11207 100644 --- a/Aetheria.State.Smoke/Program.cs +++ b/Aetheria.State.Smoke/Program.cs @@ -173,7 +173,7 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s } } await node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface) - .ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(daemonGameSurface)); + .ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(daemonGameSurface)); await node.MutableDocument(AetheriaStateNode.RuntimeSessionKey("smoke-runtime")).ReplaceAsync(new AetheriaRuntimeSession { RuntimeId = "smoke-runtime", diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index d4c117c84..4ee1484af 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -725,10 +725,6 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root) "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeCultCacheDocumentStore.cs"); - var runtimeSurfaceStateProjectorPath = Path.Combine( - root, - "Aetheria.State", - "AetheriaRuntimeEveSurfaceStateProjector.cs"); var playerSettingsSurfaceProjectorPath = Path.Combine( root, "Aetheria.State", @@ -772,9 +768,6 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root) var runtimeCultCacheDocumentStore = File.Exists(runtimeCultCacheDocumentStorePath) ? File.ReadAllText(runtimeCultCacheDocumentStorePath) : throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaRuntimeCultCacheDocumentStore.cs is missing."); - var runtimeSurfaceStateProjector = File.Exists(runtimeSurfaceStateProjectorPath) - ? File.ReadAllText(runtimeSurfaceStateProjectorPath) - : throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaRuntimeEveSurfaceStateProjector.cs is missing."); var playerSettingsSurfaceProjector = File.Exists(playerSettingsSurfaceProjectorPath) ? File.ReadAllText(playerSettingsSurfaceProjectorPath) : throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaPlayerSettingsSurfaceProjector.cs is missing."); @@ -896,9 +889,19 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root) "Aetheria runtime surfaces reintroduced local state binding flattening; state binding persistence belongs to CultMesh.StateBindingRecord."); } + var deletedRuntimeSurfaceStateProjectorPath = Path.Combine( + root, + "Aetheria.State", + "AetheriaRuntimeEveSurfaceStateProjector.cs"); + if (File.Exists(deletedRuntimeSurfaceStateProjectorPath)) + { + throw new InvalidOperationException( + "AetheriaRuntimeEveSurfaceStateProjector is dead conversion chaff; AetheriaRuntimeEveSurfaceAdapter owns runtime surface to Eve state lowering."); + } + var surfaceCommandProjectors = string.Join( "\n", - runtimeSurfaceStateProjector, + runtimeAdapter, playerSettingsSurfaceProjector, catalogSurfaceProjector, operationsSurfaceProjector); @@ -907,6 +910,8 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root) !runtimeCultCacheDocumentStore.Contains("routeDescription).ToBinding()", StringComparison.Ordinal) || !runtimeAdapter.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) || !runtimeAdapter.Contains("command.SchemaId", StringComparison.Ordinal) || + !runtimeAdapter.Contains("public static EveSurfaceState ToEveSurfaceState(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) || + !runtimeAdapter.Contains("global::Aetheria.State.Documents.EveSurfaceComponent ToEveSurfaceState(", StringComparison.Ordinal) || !surfaceCommandProjectors.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) || runtimeCultCacheDocumentStore.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal) || runtimeAdapter.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal)) @@ -10508,7 +10513,7 @@ static void RequireDaemonVersePublication(string root) var daemonHostProgramPath = Path.Combine(root, "Aetheria.State.Daemon", "Program.cs"); var documentRegistryPath = Path.Combine(root, "Aetheria.State", "AetheriaDocumentRegistry.cs"); var stateNodePath = Path.Combine(root, "Aetheria.State", "AetheriaStateNode.cs"); - var daemonSurfaceProjectorPath = Path.Combine(root, "Aetheria.State", "AetheriaRuntimeEveSurfaceStateProjector.cs"); + var runtimeEveSurfaceAdapterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeEveSurfaceAdapter.cs"); var providerAdvertisementPath = Path.Combine(root, "Aetheria.State", "AetheriaProviderAdvertisementProjector.cs"); var documentStorePath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeCultCacheDocumentStore.cs"); var boundaryPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeStateBoundary.cs"); @@ -10534,7 +10539,7 @@ static void RequireDaemonVersePublication(string root) daemonHostProgramPath, documentRegistryPath, stateNodePath, - daemonSurfaceProjectorPath, + runtimeEveSurfaceAdapterPath, providerAdvertisementPath, documentStorePath, boundaryPath, @@ -10569,7 +10574,7 @@ static void RequireDaemonVersePublication(string root) var daemonHostProgram = File.ReadAllText(daemonHostProgramPath); var documentRegistry = File.ReadAllText(documentRegistryPath); var stateNode = File.ReadAllText(stateNodePath); - var daemonSurfaceProjector = File.ReadAllText(daemonSurfaceProjectorPath); + var runtimeEveSurfaceAdapter = File.ReadAllText(runtimeEveSurfaceAdapterPath); var providerAdvertisement = File.ReadAllText(providerAdvertisementPath); var documentStore = File.ReadAllText(documentStorePath); var boundary = File.ReadAllText(boundaryPath); @@ -10842,11 +10847,18 @@ static void RequireDaemonVersePublication(string root) string.Join(", ", survivingDaemonNodeSymbols)); } - if (!daemonSurfaceProjector.Contains("public static EveSurfaceState ToState(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) || - !daemonSurfaceProjector.Contains("EveCommandTemplate", StringComparison.Ordinal) || - !daemonSurfaceProjector.Contains("EveSurfaceComponent", StringComparison.Ordinal)) + var deletedDaemonSurfaceProjectorPath = Path.Combine(root, "Aetheria.State", "AetheriaRuntimeEveSurfaceStateProjector.cs"); + if (File.Exists(deletedDaemonSurfaceProjectorPath)) { - throw new InvalidOperationException("Daemon Eve surface projector no longer lowers daemon surfaces into registered Eve surface state."); + throw new InvalidOperationException( + "Daemon Eve surface state lowering still lives in Aetheria.State projector chaff instead of the runtime Eve surface adapter."); + } + + if (!runtimeEveSurfaceAdapter.Contains("public static EveSurfaceState ToEveSurfaceState(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) || + !runtimeEveSurfaceAdapter.Contains("EveCommandTemplate", StringComparison.Ordinal) || + !runtimeEveSurfaceAdapter.Contains("global::Aetheria.State.Documents.EveSurfaceComponent", StringComparison.Ordinal)) + { + throw new InvalidOperationException("Runtime Eve surface adapter no longer lowers daemon surfaces into registered Eve surface state."); } if (!daemonDocuments.Contains("AetheriaRuntimeDaemonCommandKinds", StringComparison.Ordinal)) @@ -11482,7 +11494,7 @@ static void RequireDaemonVersePublication(string root) "AetheriaClient UI submission did not appear as a typed Eve state record.", "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest)", "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)", - ".ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(daemonGameSurface))", + ".ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(daemonGameSurface))", "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonProviderAdvertisement)", "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonHealth)", "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonCommandBoundary)", diff --git a/Aetheria.State/AetheriaRuntimeEveSurfaceStateProjector.cs b/Aetheria.State/AetheriaRuntimeEveSurfaceStateProjector.cs deleted file mode 100644 index 23c00a377..000000000 --- a/Aetheria.State/AetheriaRuntimeEveSurfaceStateProjector.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Aetheria.State.Documents; -using GameCult.Aetheria.State.Verse; - -namespace Aetheria.State; - -public static class AetheriaRuntimeEveSurfaceStateProjector -{ - public static EveSurfaceState ToState(AetheriaRuntimeSurfaceDocument document) - { - return new EveSurfaceState - { - ProviderId = document.ProviderId, - ProviderKind = document.ProviderKind, - Title = document.Title, - Version = document.Version, - UpdatedAtUtc = document.UpdatedAtUtc, - Surface = ToSurface(document.Surface), - Commands = document.Commands - .Select(command => - { - var record = GameCult.Mesh.CultMesh.OperationBindingRecord(command.Operation); - return new EveCommandTemplate - { - Command = record.OperationId, - Label = record.Label, - Transport = record.RouteDescription, - SchemaId = record.SchemaId, - RouteKind = record.RouteKind, - RouteDescription = record.RouteDescription - }; - }) - .ToArray() - }; - } - - private static EveSurface ToSurface(AetheriaRuntimeSurfaceTree surface) - { - return new EveSurface - { - Id = surface.Id, - Root = ToComponent(surface.Root), - Styles = surface.Styles - .Select(style => new EveStyleToken - { - Name = style.Name, - Value = style.Value - }) - .ToArray() - }; - } - - private static EveSurfaceComponent ToComponent(AetheriaRuntimeSurfaceComponent component) - { - var props = new Dictionary(component.Props, StringComparer.Ordinal); - AetheriaRuntimeSurfaceStateBindings.AddPointerProps(props, component.StateBindings); - - return new EveSurfaceComponent - { - Id = component.Id, - Kind = component.Kind, - Props = props, - Children = component.Children.Select(ToComponent).ToArray(), - StateBindings = component.StateBindings - .Select(binding => - { - var record = GameCult.Mesh.CultMesh.StateBindingRecord(binding); - return new EveSurfaceStateBinding - { - TargetProp = record.TargetProp, - PointerId = record.PointerId, - SourceId = record.SourceId, - SchemaId = record.SchemaId, - RouteKind = record.RouteKind, - RouteDescription = record.RouteDescription - }; - }) - .ToArray() - }; - } -} diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs index 52d755b4f..3ce0e58ab 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs @@ -11,6 +11,36 @@ namespace GameCult.Aetheria.State.Verse { public static class AetheriaRuntimeEveSurfaceAdapter { + public static EveSurfaceState ToEveSurfaceState(AetheriaRuntimeSurfaceDocument document) + { + if (document == null) throw new ArgumentNullException(nameof(document)); + + return new EveSurfaceState + { + ProviderId = document.ProviderId, + ProviderKind = document.ProviderKind, + Title = document.Title, + Version = document.Version, + UpdatedAtUtc = document.UpdatedAtUtc, + Surface = ToEveSurfaceState(document.Surface), + Commands = document.Commands + .Select(command => + { + var record = CultMesh.OperationBindingRecord(command.Operation); + return new global::Aetheria.State.Documents.EveCommandTemplate + { + Command = record.OperationId, + Label = record.Label, + Transport = record.RouteDescription, + SchemaId = record.SchemaId, + RouteKind = record.RouteKind, + RouteDescription = record.RouteDescription + }; + }) + .ToArray() + }; + } + public static EveSurfaceDocument ToEveSurfaceDocument(AetheriaRuntimeSurfaceDocument document) { return ToEveSurfaceDocument(document, null); @@ -134,6 +164,53 @@ namespace GameCult.Aetheria.State.Verse component.StateBindings.Select(ToCultMeshStateBinding).ToArray()); } + private static global::Aetheria.State.Documents.EveSurface ToEveSurfaceState( + AetheriaRuntimeSurfaceTree surface) + { + return new global::Aetheria.State.Documents.EveSurface + { + Id = surface.Id, + Root = ToEveSurfaceState(surface.Root), + Styles = surface.Styles + .Select(style => new global::Aetheria.State.Documents.EveStyleToken + { + Name = style.Name, + Value = style.Value + }) + .ToArray() + }; + } + + private static global::Aetheria.State.Documents.EveSurfaceComponent ToEveSurfaceState( + AetheriaRuntimeSurfaceComponent component) + { + var props = new Dictionary(component.Props, StringComparer.Ordinal); + AetheriaRuntimeSurfaceStateBindings.AddPointerProps(props, component.StateBindings); + + return new global::Aetheria.State.Documents.EveSurfaceComponent + { + Id = component.Id, + Kind = component.Kind, + Props = props, + Children = component.Children.Select(ToEveSurfaceState).ToArray(), + StateBindings = component.StateBindings + .Select(binding => + { + var record = CultMesh.StateBindingRecord(binding); + return new global::Aetheria.State.Documents.EveSurfaceStateBinding + { + TargetProp = record.TargetProp, + PointerId = record.PointerId, + SourceId = record.SourceId, + SchemaId = record.SchemaId, + RouteKind = record.RouteKind, + RouteDescription = record.RouteDescription + }; + }) + .ToArray() + }; + } + private static EveSurfaceComponent ToEveSurfaceComponent(global::Aetheria.State.Documents.EveSurfaceComponent component) { var props = new Dictionary(component.Props, StringComparer.Ordinal);