From 81eb52f8a7d0d5c100bade75118bcc3df63c6697 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 28 Jun 2026 11:14:31 +0100 Subject: [PATCH] Route daemon surface reads through client state --- Aetheria.State.Verify/Program.cs | 37 +++-- .../Tests/DaemonRuntimeDocumentTests.cs | 56 ++++---- .../Runtime/AetheriaEveSurfacePresenter.cs | 8 +- .../Runtime/AetheriaClientState.cs | 134 +++++++++++++++++- 4 files changed, 190 insertions(+), 45 deletions(-) diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 8cb0a08f7..cc3151eae 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -3197,10 +3197,10 @@ static void RequireEveRuntimeBootstrap(string root) "AetheriaUnityRuntimeClientProvider.ResolveClient(", "CultMeshReactiveDocument", "ResolveReactiveDaemonSurfaceState(", - "client.State.Daemon.ReactiveGameSurface()", - "client.State.Daemon.ReactiveGameTuiSurface()", - "client.State.Daemon.ReactiveEditorSurface()", - "client.State.Daemon.ReactiveEditorTuiSurface()", + "client.State.ReactiveGameSurface()", + "client.State.ReactiveGameTuiSurface()", + "client.State.ReactiveEditorSurface()", + "client.State.ReactiveEditorTuiSurface()", "DisposeReactiveSurfaceState()", "AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(", "private bool ShouldMountSurface(", @@ -3232,6 +3232,10 @@ static void RequireEveRuntimeBootstrap(string root) presenter.Contains(".DaemonGameTuiSurfaceAsync()", StringComparison.Ordinal) || presenter.Contains(".DaemonEditorSurfaceAsync()", StringComparison.Ordinal) || presenter.Contains(".DaemonEditorTuiSurfaceAsync()", StringComparison.Ordinal) || + presenter.Contains("client.State.Daemon.ReactiveGameSurface()", StringComparison.Ordinal) || + presenter.Contains("client.State.Daemon.ReactiveGameTuiSurface()", StringComparison.Ordinal) || + presenter.Contains("client.State.Daemon.ReactiveEditorSurface()", StringComparison.Ordinal) || + presenter.Contains("client.State.Daemon.ReactiveEditorTuiSurface()", StringComparison.Ordinal) || presenter.Contains("client.State.Daemon.GameSurface.LatestAsync()", StringComparison.Ordinal) || presenter.Contains("client.State.Daemon.GameTuiSurface.LatestAsync()", StringComparison.Ordinal) || presenter.Contains("client.State.Daemon.EditorSurface.LatestAsync()", StringComparison.Ordinal) || @@ -7591,6 +7595,9 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root } var clientState = File.ReadAllText(clientStatePath); + var topLevelClientState = clientState.Split( + "public sealed class AetheriaClientDaemonState", + StringSplitOptions.None)[0]; var requiredClientSymbols = new[] { "public AetheriaRuntimeDaemonFrameDocument LatestDaemonFrame()", @@ -7696,7 +7703,13 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root ".State.Daemon.GameSurface.LatestAsync()", ".State.Daemon.GameTuiSurface.LatestAsync()", ".State.Daemon.EditorSurface.LatestAsync()", - ".State.Daemon.EditorTuiSurface.LatestAsync()" + ".State.Daemon.EditorTuiSurface.LatestAsync()", + "client.State.Daemon.LatestFrameDocument()", + "client.State.Daemon.LatestGameSurface()", + "client.State.Daemon.LatestGameTuiSurface()", + "client.State.Daemon.LatestEditorSurface()", + "client.State.Daemon.LatestEditorTuiSurface()", + "client.State.Daemon.LatestAuthorityPolicy()" } .Select(CompactSource) .ToArray(); @@ -10866,9 +10879,9 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) "public Func CreateEveSurfaceStateRefResolver()", "public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()", "public async Task CreateEveSurfaceCultMeshStateRefResolverAsync()", - "Daemon.LatestFrameDocumentAsync()", - "Daemon.LatestHealthAsync()", - "Daemon.LatestCommandBoundaryAsync()", + "LatestDaemonFrameAsync()", + "LatestHealthAsync()", + "LatestCommandBoundaryAsync()", "LatestCatalog", "AetheriaRuntimeStateRefResolver.CreateEveSurfaceCultMeshStateRefResolver(" }; @@ -10882,6 +10895,14 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) string.Join(", ", missingClientStateSymbols)); } + if (clientState.Contains("var frameTask = Daemon.LatestFrameDocumentAsync()", StringComparison.Ordinal) || + clientState.Contains("var healthTask = Daemon.LatestHealthAsync()", StringComparison.Ordinal) || + clientState.Contains("var commandBoundaryTask = Daemon.LatestCommandBoundaryAsync()", StringComparison.Ordinal)) + { + throw new InvalidOperationException( + "AetheriaClientState Eve state-ref resolver must use top-level managed accessors instead of walking through the nested daemon state."); + } + var requiredStateRefResolverSymbols = new[] { "public static class AetheriaRuntimeStateRefResolver", diff --git a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs index 8fbdd62f7..934ccfc63 100644 --- a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs +++ b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs @@ -204,14 +204,18 @@ public class DaemonRuntimeDocumentTests using var zoneRenderReactive = client.State .Reactive(); var observed = client.State.LatestObservedDaemon(); - var observedAuthoritativeFrame = client.State.Daemon.LatestFrameDocument(); - var gameSurface = client.State.Daemon.LatestGameSurface(); - var gameTuiSurface = client.State.Daemon.LatestGameTuiSurface(); - var editorSurface = client.State.Daemon.LatestEditorSurface(); - var editorTuiSurface = client.State.Daemon.LatestEditorTuiSurface(); - var authorityStatus = client.State.Daemon.LatestAuthorityPolicy(); + var observedAuthoritativeFrame = client.State.LatestDaemonFrame(); + var gameSurface = client.State.LatestGameSurface(); + var gameTuiSurface = client.State.LatestGameTuiSurface(); + var editorSurface = client.State.LatestEditorSurface(); + var editorTuiSurface = client.State.LatestEditorTuiSurface(); + var authorityStatus = client.State.LatestAuthorityPolicy(); var dockingState = client.State.LatestDockingState(); using var reactiveDockingState = client.State.ReactiveDockingState(); + using var reactiveGameSurface = client.State.ReactiveGameSurface(); + using var reactiveGameTuiSurface = client.State.ReactiveGameTuiSurface(); + using var reactiveEditorSurface = client.State.ReactiveEditorSurface(); + using var reactiveEditorTuiSurface = client.State.ReactiveEditorTuiSurface(); Assert.AreEqual("aetheria.current.entity", client.State.Current.Entity.DocumentId); Assert.AreSame(client.State.Current.Entity, client.State.Document()); @@ -224,25 +228,17 @@ public class DaemonRuntimeDocumentTests client.State.Starbridge.Summary, client.State.DocumentBySchema(AetheriaRuntimeDaemonSchemas.StarbridgeSessionSummary)); Assert.AreSame(client.State.LatestFrame, client.State.Document()); - Assert.AreSame(client.State.Daemon.LatestFrame, client.State.LatestFrame); - Assert.AreSame(client.State.Daemon.LatestSoaView, client.State.LatestSoaView); + Assert.AreSame(client.State.LatestSoaView, client.State.Document()); + Assert.IsNotNull(client.State.LatestProviderAdvertisement()); + Assert.IsNotNull(client.State.LatestHealth()); + Assert.IsNotNull(client.State.LatestCommandBoundary()); Assert.AreSame( - client.State.Daemon.ProviderAdvertisement, - client.State.Document()); - Assert.AreSame(client.State.Daemon.Health, client.State.Document()); - Assert.AreSame( - client.State.Daemon.CommandBoundary, - client.State.Document()); - Assert.AreSame( - client.State.Daemon.AuthorityPolicy, - client.State.Document()); - Assert.AreSame( - client.State.Daemon.AuthorityPolicy, + client.State.Document(), client.State.DocumentBySchema(AetheriaRuntimeVerseAuthoritySchemas.Policy)); - Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId, client.State.Daemon.GameSurface.DocumentId); - Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, client.State.Daemon.GameTuiSurface.DocumentId); - Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId, client.State.Daemon.EditorSurface.DocumentId); - Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, client.State.Daemon.EditorTuiSurface.DocumentId); + Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId, reactiveGameSurface.Current.Surface.Id); + Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, reactiveGameTuiSurface.Current.Surface.Id); + Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId, reactiveEditorSurface.Current.Surface.Id); + Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, reactiveEditorTuiSurface.Current.Surface.Id); Assert.AreSame(client.State.Settings.Player, client.State.Document()); Assert.AreSame(client.State.Settings.VerseHost, client.State.Document()); Assert.AreSame( @@ -551,10 +547,10 @@ public class DaemonRuntimeDocumentTests .OpenAsync(statePath, "unity-surface-test", pullOnOpen: true) .GetAwaiter() .GetResult(); - var unityGameSurfaceState = client.State.Daemon.LatestGameSurface(); - var unityGameTuiSurfaceState = client.State.Daemon.LatestGameTuiSurface(); - var unityEditorSurfaceState = client.State.Daemon.LatestEditorSurface(); - var unityEditorTuiSurfaceState = client.State.Daemon.LatestEditorTuiSurface(); + var unityGameSurfaceState = client.State.LatestGameSurface(); + var unityGameTuiSurfaceState = client.State.LatestGameTuiSurface(); + var unityEditorSurfaceState = client.State.LatestEditorSurface(); + var unityEditorTuiSurfaceState = client.State.LatestEditorTuiSurface(); var surfaceResolver = client.State.CreateEveSurfaceStateRefResolver(); var unityGameSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument( unityGameSurfaceState, @@ -586,7 +582,7 @@ public class DaemonRuntimeDocumentTests Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, unityEditorTuiSurface.Surface.Id); Assert.AreEqual("editor.daemon", unityEditorTuiSurface.ProviderKind); var genericGameSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument( - client.State.Daemon.LatestGameSurface(), + client.State.LatestGameSurface(), surfaceResolver); Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId, genericGameSurface.Surface.Id); Assert.AreEqual(unityGameSurface.ProviderId, genericGameSurface.ProviderId); @@ -609,11 +605,11 @@ public class DaemonRuntimeDocumentTests AetheriaRuntimeDaemonStateRefs.CurrentTargetName, AetheriaRuntimeDaemonSchemas.Frame)); var genericGameTuiSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument( - client.State.Daemon.LatestGameTuiSurface(), + client.State.LatestGameTuiSurface(), surfaceResolver); Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, genericGameTuiSurface.Surface.Id); var genericEditorTuiSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument( - client.State.Daemon.LatestEditorTuiSurface(), + client.State.LatestEditorTuiSurface(), surfaceResolver); Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, genericEditorTuiSurface.Surface.Id); } diff --git a/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs b/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs index e80d188f2..fbe348dfd 100644 --- a/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs +++ b/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs @@ -169,16 +169,16 @@ namespace GameCult.Aetheria.EveRuntime AetheriaClient client) { if (string.Equals(surfaceId, AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId, StringComparison.Ordinal)) - return client.State.Daemon.ReactiveGameSurface(); + return client.State.ReactiveGameSurface(); if (string.Equals(surfaceId, AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, StringComparison.Ordinal)) - return client.State.Daemon.ReactiveGameTuiSurface(); + return client.State.ReactiveGameTuiSurface(); if (string.Equals(surfaceId, AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId, StringComparison.Ordinal)) - return client.State.Daemon.ReactiveEditorSurface(); + return client.State.ReactiveEditorSurface(); if (string.Equals(surfaceId, AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, StringComparison.Ordinal)) - return client.State.Daemon.ReactiveEditorTuiSurface(); + return client.State.ReactiveEditorTuiSurface(); return null; } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs index aa61dc660..2499136c9 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs @@ -302,6 +302,134 @@ namespace GameCult.Aetheria.State.Verse return LatestObservedDaemonAsync().ConfigureAwait(false).GetAwaiter().GetResult(); } + public Task LatestProviderAdvertisementAsync() + { + return Daemon.LatestProviderAdvertisementAsync(); + } + + public AetheriaRuntimeDaemonProviderAdvertisementDocument LatestProviderAdvertisement() + { + return LatestProviderAdvertisementAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task LatestHealthAsync() + { + return Daemon.LatestHealthAsync(); + } + + public AetheriaRuntimeDaemonHealthDocument LatestHealth() + { + return LatestHealthAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task LatestCommandBoundaryAsync() + { + return Daemon.LatestCommandBoundaryAsync(); + } + + public AetheriaRuntimeDaemonCommandBoundaryDocument LatestCommandBoundary() + { + return LatestCommandBoundaryAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task LatestAuthorityPolicyAsync() + { + return Daemon.LatestAuthorityPolicyAsync(); + } + + public AetheriaRuntimeVerseAuthorityPolicyDocument LatestAuthorityPolicy() + { + return LatestAuthorityPolicyAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task LatestGameSurfaceAsync() + { + return Daemon.LatestGameSurfaceAsync(); + } + + public global::Aetheria.State.Documents.EveSurfaceState LatestGameSurface() + { + return LatestGameSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task> ReactiveGameSurfaceAsync( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveGameSurfaceAsync(options); + } + + public CultMeshReactiveDocument ReactiveGameSurface( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveGameSurface(options); + } + + public Task LatestGameTuiSurfaceAsync() + { + return Daemon.LatestGameTuiSurfaceAsync(); + } + + public global::Aetheria.State.Documents.EveSurfaceState LatestGameTuiSurface() + { + return LatestGameTuiSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task> ReactiveGameTuiSurfaceAsync( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveGameTuiSurfaceAsync(options); + } + + public CultMeshReactiveDocument ReactiveGameTuiSurface( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveGameTuiSurface(options); + } + + public Task LatestEditorSurfaceAsync() + { + return Daemon.LatestEditorSurfaceAsync(); + } + + public global::Aetheria.State.Documents.EveSurfaceState LatestEditorSurface() + { + return LatestEditorSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task> ReactiveEditorSurfaceAsync( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveEditorSurfaceAsync(options); + } + + public CultMeshReactiveDocument ReactiveEditorSurface( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveEditorSurface(options); + } + + public Task LatestEditorTuiSurfaceAsync() + { + return Daemon.LatestEditorTuiSurfaceAsync(); + } + + public global::Aetheria.State.Documents.EveSurfaceState LatestEditorTuiSurface() + { + return LatestEditorTuiSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + } + + public Task> ReactiveEditorTuiSurfaceAsync( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveEditorTuiSurfaceAsync(options); + } + + public CultMeshReactiveDocument ReactiveEditorTuiSurface( + CultMeshReactiveDocumentOptions? options = null) + { + return Daemon.ReactiveEditorTuiSurface(options); + } + public Task LatestLoadoutTemplatesAsync() { return LoadoutTemplates.LatestAsync(); @@ -451,9 +579,9 @@ namespace GameCult.Aetheria.State.Verse public async Task CreateEveSurfaceCultMeshStateRefResolverAsync() { - var frameTask = Daemon.LatestFrameDocumentAsync(); - var healthTask = Daemon.LatestHealthAsync(); - var commandBoundaryTask = Daemon.LatestCommandBoundaryAsync(); + var frameTask = LatestDaemonFrameAsync(); + var healthTask = LatestHealthAsync(); + var commandBoundaryTask = LatestCommandBoundaryAsync(); await Task.WhenAll(frameTask, healthTask, commandBoundaryTask).ConfigureAwait(false);