Expose reactive daemon frame accessors

This commit is contained in:
Meta Vens 2026-06-28 11:05:55 +01:00
commit e78ef8ccb3
4 changed files with 49 additions and 7 deletions

View file

@ -7594,7 +7594,9 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
var requiredClientSymbols = new[]
{
"public AetheriaRuntimeDaemonFrameDocument LatestDaemonFrame()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> ReactiveDaemonFrame(",
"public AetheriaRuntimeDaemonSoaViewDocument LatestDaemonSoaView()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> ReactiveDaemonSoaView(",
"public AetheriaClientDockingSnapshot LatestDockingState()",
"public AetheriaClientReactiveDockingState ReactiveDockingState(",
"public AetheriaRuntimeObservedDaemonState? LatestObservedDaemon()",
@ -7654,6 +7656,13 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
string.Join(", ", missingObservedSymbols));
}
if (observedDaemonState.Contains("state.LatestFrame.ReactiveAsync", StringComparison.Ordinal) ||
observedDaemonState.Contains("state.LatestSoaView.ReactiveAsync", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Observed daemon reactive state must delegate through named AetheriaClientState reactive accessors instead of walking raw CultMesh handles.");
}
if (observedDaemonState.Contains("state.LatestDaemonFrameAsync()", StringComparison.Ordinal) ||
observedDaemonState.Contains("state.LatestDaemonSoaViewAsync()", StringComparison.Ordinal) ||
observedDaemonState.Contains("state.ReactiveObservedDaemonAsync()", StringComparison.Ordinal) ||
@ -14871,8 +14880,8 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
"AetheriaRuntimeDaemonSoaViewIndex.Build(soaView)",
"public sealed class AetheriaRuntimeReactiveObservedDaemonState",
"public static async Task<AetheriaRuntimeReactiveObservedDaemonState> CreateAsync(",
"state.LatestFrame.ReactiveAsync(options)",
"state.LatestSoaView.ReactiveAsync(options)",
"state.ReactiveDaemonFrameAsync(options)",
"state.ReactiveDaemonSoaViewAsync(options)",
"public bool TryCurrent(out AetheriaRuntimeObservedDaemonState? observed)"
};
var missingObservedDaemonStateSymbols = requiredObservedDaemonStateSymbols
@ -14891,7 +14900,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
"FramePath",
"SoaViewPath",
"AetheriaRuntimeDaemonFrameStore.GetFramePath",
"SoaViewStore.GetViewPath"
"SoaViewStore.GetViewPath",
"state.LatestFrame.ReactiveAsync",
"state.LatestSoaView.ReactiveAsync"
};
var observedDaemonStateBypassHits = forbiddenObservedDaemonStateSymbols
.Where(symbol => observedDaemonState.Contains(symbol, StringComparison.Ordinal))
@ -16472,7 +16483,7 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
"ProjectLoadoutTemplateAsync(",
"AetheriaClientState state",
"public sealed class AetheriaRuntimeReactiveLoadoutSnapshotProjector",
"state.Daemon.LatestFrame.ReactiveAsync(options)",
"state.ReactiveDaemonFrameAsync(options)",
"public AetheriaRuntimeLoadoutTemplateCommit ProjectLoadoutTemplate(string entityKey)",
"ProjectLoadoutTemplate(",
"frame.Run ?? new AetheriaRuntimeRunCheckpointCommit()",
@ -16494,6 +16505,13 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
"Loadout template save payloads still perform one-shot daemon frame reads instead of using a reactive typed frame document.");
}
if (loadoutSnapshotProjector.Contains("state.Daemon.LatestFrame.ReactiveAsync", StringComparison.Ordinal) ||
loadoutSnapshotProjector.Contains("state.LatestFrame.ReactiveAsync", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Loadout template save payloads must use named AetheriaClientState reactive daemon frame access instead of walking raw CultMesh handles.");
}
var forbiddenActionSymbols = new[]
{
"AetheriaRuntimeStateCommitLog.QueueLoadoutTemplate",

View file

@ -211,6 +211,18 @@ namespace GameCult.Aetheria.State.Verse
return LatestDaemonFrameAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument>> ReactiveDaemonFrameAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return LatestFrame.ReactiveAsync(options);
}
public CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> ReactiveDaemonFrame(
CultMeshReactiveDocumentOptions? options = null)
{
return LatestFrame.Reactive(options);
}
public Task<AetheriaRuntimeDaemonSoaViewDocument> LatestDaemonSoaViewAsync()
{
return LatestSoaView.LatestAsync();
@ -221,6 +233,18 @@ namespace GameCult.Aetheria.State.Verse
return LatestDaemonSoaViewAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument>> ReactiveDaemonSoaViewAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return LatestSoaView.ReactiveAsync(options);
}
public CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> ReactiveDaemonSoaView(
CultMeshReactiveDocumentOptions? options = null)
{
return LatestSoaView.Reactive(options);
}
public Task<AetheriaClientDockingSnapshot> LatestDockingStateAsync()
{
return DockingState.LatestAsync();

View file

@ -267,7 +267,7 @@ namespace GameCult.Aetheria.State.Verse
{
if (state == null) throw new ArgumentNullException(nameof(state));
var frame = await state.Daemon.LatestFrame.ReactiveAsync(options).ConfigureAwait(false);
var frame = await state.ReactiveDaemonFrameAsync(options).ConfigureAwait(false);
return new AetheriaRuntimeReactiveLoadoutSnapshotProjector(frame);
}

View file

@ -56,7 +56,7 @@ namespace GameCult.Aetheria.State.Verse
{
if (state == null) throw new ArgumentNullException(nameof(state));
var frame = await state.LatestFrame.ReactiveAsync(options).ConfigureAwait(false);
var frame = await state.ReactiveDaemonFrameAsync(options).ConfigureAwait(false);
var soaView = await TryCreateSoaViewAsync(state, options).ConfigureAwait(false);
return new AetheriaRuntimeReactiveObservedDaemonState(frame, soaView);
}
@ -106,7 +106,7 @@ namespace GameCult.Aetheria.State.Verse
{
try
{
return await state.LatestSoaView.ReactiveAsync(options).ConfigureAwait(false);
return await state.ReactiveDaemonSoaViewAsync(options).ConfigureAwait(false);
}
catch (KeyNotFoundException)
{