Route daemon surface reads through client state

This commit is contained in:
Meta Vens 2026-06-28 11:14:31 +01:00
commit 81eb52f8a7
4 changed files with 190 additions and 45 deletions

View file

@ -3197,10 +3197,10 @@ static void RequireEveRuntimeBootstrap(string root)
"AetheriaUnityRuntimeClientProvider.ResolveClient(",
"CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>",
"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<string, string> CreateEveSurfaceStateRefResolver()",
"public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()",
"public async Task<CultMeshStateRefResolver> 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",

View file

@ -204,14 +204,18 @@ public class DaemonRuntimeDocumentTests
using var zoneRenderReactive = client.State
.Reactive<AetheriaRuntimeZoneRenderDocument>();
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<AetheriaRuntimeCurrentEntityDocument>());
@ -224,25 +228,17 @@ public class DaemonRuntimeDocumentTests
client.State.Starbridge.Summary,
client.State.DocumentBySchema(AetheriaRuntimeDaemonSchemas.StarbridgeSessionSummary));
Assert.AreSame(client.State.LatestFrame, client.State.Document<AetheriaRuntimeDaemonFrameDocument>());
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<AetheriaRuntimeDaemonSoaViewDocument>());
Assert.IsNotNull(client.State.LatestProviderAdvertisement());
Assert.IsNotNull(client.State.LatestHealth());
Assert.IsNotNull(client.State.LatestCommandBoundary());
Assert.AreSame(
client.State.Daemon.ProviderAdvertisement,
client.State.Document<AetheriaRuntimeDaemonProviderAdvertisementDocument>());
Assert.AreSame(client.State.Daemon.Health, client.State.Document<AetheriaRuntimeDaemonHealthDocument>());
Assert.AreSame(
client.State.Daemon.CommandBoundary,
client.State.Document<AetheriaRuntimeDaemonCommandBoundaryDocument>());
Assert.AreSame(
client.State.Daemon.AuthorityPolicy,
client.State.Document<AetheriaRuntimeVerseAuthorityPolicyDocument>());
Assert.AreSame(
client.State.Daemon.AuthorityPolicy,
client.State.Document<AetheriaRuntimeVerseAuthorityPolicyDocument>(),
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<AetheriaRuntimePlayerSettingsDocument>());
Assert.AreSame(client.State.Settings.VerseHost, client.State.Document<AetheriaRuntimeVerseHostSettingsDocument>());
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);
}

View file

@ -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;
}

View file

@ -302,6 +302,134 @@ namespace GameCult.Aetheria.State.Verse
return LatestObservedDaemonAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<AetheriaRuntimeDaemonProviderAdvertisementDocument> LatestProviderAdvertisementAsync()
{
return Daemon.LatestProviderAdvertisementAsync();
}
public AetheriaRuntimeDaemonProviderAdvertisementDocument LatestProviderAdvertisement()
{
return LatestProviderAdvertisementAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<AetheriaRuntimeDaemonHealthDocument> LatestHealthAsync()
{
return Daemon.LatestHealthAsync();
}
public AetheriaRuntimeDaemonHealthDocument LatestHealth()
{
return LatestHealthAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<AetheriaRuntimeDaemonCommandBoundaryDocument> LatestCommandBoundaryAsync()
{
return Daemon.LatestCommandBoundaryAsync();
}
public AetheriaRuntimeDaemonCommandBoundaryDocument LatestCommandBoundary()
{
return LatestCommandBoundaryAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<AetheriaRuntimeVerseAuthorityPolicyDocument> LatestAuthorityPolicyAsync()
{
return Daemon.LatestAuthorityPolicyAsync();
}
public AetheriaRuntimeVerseAuthorityPolicyDocument LatestAuthorityPolicy()
{
return LatestAuthorityPolicyAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<global::Aetheria.State.Documents.EveSurfaceState> LatestGameSurfaceAsync()
{
return Daemon.LatestGameSurfaceAsync();
}
public global::Aetheria.State.Documents.EveSurfaceState LatestGameSurface()
{
return LatestGameSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>> ReactiveGameSurfaceAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveGameSurfaceAsync(options);
}
public CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState> ReactiveGameSurface(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveGameSurface(options);
}
public Task<global::Aetheria.State.Documents.EveSurfaceState> LatestGameTuiSurfaceAsync()
{
return Daemon.LatestGameTuiSurfaceAsync();
}
public global::Aetheria.State.Documents.EveSurfaceState LatestGameTuiSurface()
{
return LatestGameTuiSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>> ReactiveGameTuiSurfaceAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveGameTuiSurfaceAsync(options);
}
public CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState> ReactiveGameTuiSurface(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveGameTuiSurface(options);
}
public Task<global::Aetheria.State.Documents.EveSurfaceState> LatestEditorSurfaceAsync()
{
return Daemon.LatestEditorSurfaceAsync();
}
public global::Aetheria.State.Documents.EveSurfaceState LatestEditorSurface()
{
return LatestEditorSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>> ReactiveEditorSurfaceAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveEditorSurfaceAsync(options);
}
public CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState> ReactiveEditorSurface(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveEditorSurface(options);
}
public Task<global::Aetheria.State.Documents.EveSurfaceState> LatestEditorTuiSurfaceAsync()
{
return Daemon.LatestEditorTuiSurfaceAsync();
}
public global::Aetheria.State.Documents.EveSurfaceState LatestEditorTuiSurface()
{
return LatestEditorTuiSurfaceAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>> ReactiveEditorTuiSurfaceAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveEditorTuiSurfaceAsync(options);
}
public CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState> ReactiveEditorTuiSurface(
CultMeshReactiveDocumentOptions? options = null)
{
return Daemon.ReactiveEditorTuiSurface(options);
}
public Task<AetheriaRuntimeLoadoutTemplatesDocument> LatestLoadoutTemplatesAsync()
{
return LoadoutTemplates.LatestAsync();
@ -451,9 +579,9 @@ namespace GameCult.Aetheria.State.Verse
public async Task<CultMeshStateRefResolver> 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);