Use generic reactive daemon documents

This commit is contained in:
Meta Vens 2026-06-28 23:41:03 +01:00
commit 0e694abe9a
7 changed files with 54 additions and 81 deletions

View file

@ -7295,8 +7295,7 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root)
"public CultMeshReactiveDocument<AetheriaRuntimeZoneContactsDocument> ReactiveZoneContacts(",
"public Task<CultMeshReactiveDocument<AetheriaRuntimeStationRefitDocument>> ReactiveStationRefitAsync(",
"public CultMeshReactiveDocument<AetheriaRuntimeStationRefitDocument> ReactiveStationRefit(",
"public Task<CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument>> ReactiveZoneRenderAsync(",
"public CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> ReactiveZoneRender(",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(",
"public Task<CultMeshReactiveDocument<AetheriaRuntimeCurrentZoneDocument>> ReactiveZoneAsync(",
"public CultMeshReactiveDocument<AetheriaRuntimeCurrentZoneDocument> ReactiveZone(",
"public Task<CultMeshReactiveDocument<AetheriaRuntimeCurrentEntityDocument>> ReactiveEntityAsync(",
@ -8133,9 +8132,8 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
var requiredClientSymbols = new[]
{
"public AetheriaRuntimeDaemonFrameDocument LatestDaemonFrame()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> ReactiveDaemonFrame(",
"public AetheriaRuntimeDaemonSoaViewDocument LatestDaemonSoaView()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> ReactiveDaemonSoaView(",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(",
"public AetheriaRuntimeObservedDaemonState? LatestObservedDaemon()",
"public AetheriaRuntimeObservedDockingState? CurrentDocking(",
"public CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot> ReactiveCatalog(",
@ -8180,6 +8178,14 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
string.Join(", ", missingClientSymbols));
}
if (topLevelClientState.Contains("ReactiveDaemonFrame(", StringComparison.Ordinal) ||
topLevelClientState.Contains("ReactiveDaemonSoaView(", StringComparison.Ordinal) ||
topLevelClientState.Contains("ReactiveZoneRender(", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"AetheriaClientState must not reintroduce named daemon reactive wrappers; use Reactive<TDocument>() for managed typed document access.");
}
var observedDaemonState = File.ReadAllText(observedDaemonStatePath);
if (!observedDaemonState.Contains("public static bool TryCreateCurrent(", StringComparison.Ordinal) ||
!observedDaemonState.Contains("new AetheriaRuntimeObservedDaemonState(currentFrame, currentSoaView, currentZoneRender)", StringComparison.Ordinal))
@ -11468,11 +11474,11 @@ static void RequireAetheriaRuntimeVerseClientContract(string root)
"private readonly CultMeshReactiveDocument<AetheriaRuntimeStarbridgeScenarioDocument> _starbridgeScenario;",
"private readonly CultMeshReactiveDocument<AetheriaRuntimeStarbridgeSessionDocument> _starbridgeSession;",
"public AetheriaRuntimeManagedClientInputs(AetheriaClientState state)",
"_daemonFrame = state.ReactiveDaemonFrame();",
"_catalog = state.ReactiveCatalog();",
"_loadoutTemplates = state.ReactiveLoadoutTemplates();",
"_starbridgeScenario = state.Starbridge.ReactiveScenario();",
"_starbridgeSession = state.Starbridge.ReactiveSession();",
"_daemonFrame = state.Reactive<AetheriaRuntimeDaemonFrameDocument>();",
"_catalog = state.Reactive<AetheriaRuntimeCatalogSnapshot>();",
"_loadoutTemplates = state.Reactive<AetheriaRuntimeLoadoutTemplatesDocument>();",
"_starbridgeScenario = state.Reactive<AetheriaRuntimeStarbridgeScenarioDocument>();",
"_starbridgeSession = state.Reactive<AetheriaRuntimeStarbridgeSessionDocument>();",
"public AetheriaRuntimeCatalogSnapshot Catalog => _catalog.Current",
"public AetheriaRuntimeLoadoutTemplatesDocument LoadoutTemplates => _loadoutTemplates.Current",
"public AetheriaRuntimeDaemonFrameDocument RequireFrame()",
@ -15686,9 +15692,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
var requiredManagedObservedDaemonSymbols = new[]
{
"public AetheriaRuntimeObservedDaemonState? CurrentObservedDaemon(",
"using var frame = ReactiveDaemonFrame(options);",
"using var soaView = TryReactiveDaemonSoaView(options);",
"using var zoneRender = ReactiveZoneRender(options);",
"using var frame = Reactive<AetheriaRuntimeDaemonFrameDocument>(options);",
"using var soaView = TryReactive<AetheriaRuntimeDaemonSoaViewDocument>(options);",
"using var zoneRender = Reactive<AetheriaRuntimeZoneRenderDocument>(options);",
"AetheriaRuntimeObservedDaemonState.TryCreateCurrent(frame, soaView, zoneRender, out var current)"
};
var missingManagedObservedDaemonSymbols = requiredManagedObservedDaemonSymbols
@ -15702,9 +15708,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
}
if (!daemonRuntimeDocumentTests.Contains("ManagedStateSamplesCurrentObservedDaemonFromReactiveDocuments()", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("using var observedFrame = client.State.ReactiveDaemonFrame();", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("using var observedSoaView = client.State.ReactiveDaemonSoaView();", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("using var observedZoneRender = client.State.ReactiveZoneRender();", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("using var observedFrame = client.State.Reactive<AetheriaRuntimeDaemonFrameDocument>();", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("using var observedSoaView = client.State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("using var observedZoneRender = client.State.Reactive<AetheriaRuntimeZoneRenderDocument>();", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("AetheriaRuntimeObservedDaemonState.TryCreateCurrent(", StringComparison.Ordinal) ||
!daemonRuntimeDocumentTests.Contains("var sampledObserved = client.State.CurrentObservedDaemon();", StringComparison.Ordinal))
{
@ -15926,9 +15932,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
!daemonObserver.Contains("CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> _daemonFrame", StringComparison.Ordinal) ||
!daemonObserver.Contains("CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> _daemonSoaView", StringComparison.Ordinal) ||
!daemonObserver.Contains("CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> _zoneRender", StringComparison.Ordinal) ||
!daemonObserver.Contains("_daemonFrame ??= state.ReactiveDaemonFrame();", StringComparison.Ordinal) ||
!daemonObserver.Contains("_daemonSoaView ??= TryReactiveDaemonSoaView(state);", StringComparison.Ordinal) ||
!daemonObserver.Contains("_zoneRender ??= state.ReactiveZoneRender();", StringComparison.Ordinal) ||
!daemonObserver.Contains("_daemonFrame ??= state.Reactive<AetheriaRuntimeDaemonFrameDocument>();", StringComparison.Ordinal) ||
!daemonObserver.Contains("_daemonSoaView ??= TryReactive<AetheriaRuntimeDaemonSoaViewDocument>(state);", StringComparison.Ordinal) ||
!daemonObserver.Contains("_zoneRender ??= state.Reactive<AetheriaRuntimeZoneRenderDocument>();", StringComparison.Ordinal) ||
!daemonObserver.Contains("AetheriaRuntimeObservedDaemonState.TryCreateCurrent(", StringComparison.Ordinal) ||
!daemonObserver.Contains("DisposeObservedDaemonDocuments()", StringComparison.Ordinal))
{
@ -17372,7 +17378,7 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
"CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> _loadoutFrame",
"ProjectLoadoutTemplate(targetEntityKey)",
"AetheriaRuntimeLoadoutSnapshotProjector.ProjectLoadoutTemplate(",
".ReactiveDaemonFrame()",
".Reactive<AetheriaRuntimeDaemonFrameDocument>()",
"_loadoutFrame?.Dispose()",
".Ui.SaveLoadoutTemplateAsync(loadout, \"unity-inventory\")"
};
@ -17398,7 +17404,7 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
"InventoryPanel",
"AetheriaRuntimeDaemonFrameDocument",
"_loadoutFrame",
".ReactiveDaemonFrame()",
".Reactive<AetheriaRuntimeDaemonFrameDocument>()",
"AetheriaRuntimeDaemonFrameSession",
".ObserveDaemonFrame()");
@ -17415,7 +17421,7 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
{
"ProjectLoadoutTemplateAsync(",
"AetheriaClientState state",
".ReactiveDaemonFrame()",
".Reactive<AetheriaRuntimeDaemonFrameDocument>()",
"ProjectLoadoutTemplate(",
"frame.Current?.Run ?? new AetheriaRuntimeRunCheckpointCommit()"
};
@ -17437,10 +17443,11 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
if (loadoutSnapshotProjector.Contains("state.Daemon.LatestFrame.ReactiveAsync", StringComparison.Ordinal) ||
loadoutSnapshotProjector.Contains("state.LatestFrame.ReactiveAsync", StringComparison.Ordinal) ||
loadoutSnapshotProjector.Contains(".ObserveDaemonFrame()", StringComparison.Ordinal))
loadoutSnapshotProjector.Contains(".ObserveDaemonFrame()", StringComparison.Ordinal) ||
loadoutSnapshotProjector.Contains(".ReactiveDaemonFrame()", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Loadout template save payloads must use named AetheriaClientState reactive daemon frame access instead of walking raw CultMesh handles.");
"Loadout template save payloads must use generic AetheriaClientState reactive typed document access instead of named wrappers or raw handle walks.");
}
if (clientState.Contains("ReactiveLoadoutSnapshotProjector", StringComparison.Ordinal) ||

View file

@ -131,17 +131,18 @@ public sealed class AetheriaDaemonObserver : MonoBehaviour
return;
}
_daemonFrame ??= state.ReactiveDaemonFrame();
_daemonSoaView ??= TryReactiveDaemonSoaView(state);
_zoneRender ??= state.ReactiveZoneRender();
_daemonFrame ??= state.Reactive<AetheriaRuntimeDaemonFrameDocument>();
_daemonSoaView ??= TryReactive<AetheriaRuntimeDaemonSoaViewDocument>(state);
_zoneRender ??= state.Reactive<AetheriaRuntimeZoneRenderDocument>();
}
private static CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> TryReactiveDaemonSoaView(
private static CultMeshReactiveDocument<TDocument> TryReactive<TDocument>(
AetheriaClientState state)
where TDocument : class
{
try
{
return state.ReactiveDaemonSoaView();
return state.Reactive<TDocument>();
}
catch (System.Collections.Generic.KeyNotFoundException)
{

View file

@ -206,8 +206,8 @@ public class DaemonRuntimeDocumentTests
var observed = client.State.LatestObservedDaemon();
var observedAuthoritativeFrame = client.State.LatestDaemonFrame();
using var catalogReactive = client.State.ReactiveCatalog();
using var daemonFrameReactive = client.State.ReactiveDaemonFrame();
using var daemonSoaViewReactive = client.State.ReactiveDaemonSoaView();
using var daemonFrameReactive = client.State.Reactive<AetheriaRuntimeDaemonFrameDocument>();
using var daemonSoaViewReactive = client.State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();
using var loadoutTemplatesReactive = client.State.ReactiveLoadoutTemplates();
using var sectorMapReactive = client.State.ReactiveSectorMap();
using var playerSettingsReactive = client.State.Settings.ReactivePlayer();
@ -2263,9 +2263,9 @@ public class DaemonRuntimeDocumentTests
.OpenAsync(statePath, "unity-reactive-observer-test", pullOnOpen: true)
.GetAwaiter()
.GetResult();
using var observedFrame = client.State.ReactiveDaemonFrame();
using var observedSoaView = client.State.ReactiveDaemonSoaView();
using var observedZoneRender = client.State.ReactiveZoneRender();
using var observedFrame = client.State.Reactive<AetheriaRuntimeDaemonFrameDocument>();
using var observedSoaView = client.State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();
using var observedZoneRender = client.State.Reactive<AetheriaRuntimeZoneRenderDocument>();
var observed = AetheriaRuntimeObservedDaemonState.TryCreateCurrent(
observedFrame,
observedSoaView,

View file

@ -1552,7 +1552,7 @@ private void Update()
{
_loadoutFrame = ResolveClient()
.State
.ReactiveDaemonFrame();
.Reactive<AetheriaRuntimeDaemonFrameDocument>();
}
catch (Exception ex)
{

View file

@ -209,18 +209,6 @@ 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();
@ -231,18 +219,6 @@ 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 async Task<AetheriaRuntimeObservedDaemonState?> LatestObservedDaemonAsync()
{
var frame = await LatestDaemonFrameAsync().ConfigureAwait(false);
@ -259,9 +235,9 @@ namespace GameCult.Aetheria.State.Verse
public AetheriaRuntimeObservedDaemonState? CurrentObservedDaemon(
CultMeshReactiveDocumentOptions? options = null)
{
using var frame = ReactiveDaemonFrame(options);
using var soaView = TryReactiveDaemonSoaView(options);
using var zoneRender = ReactiveZoneRender(options);
using var frame = Reactive<AetheriaRuntimeDaemonFrameDocument>(options);
using var soaView = TryReactive<AetheriaRuntimeDaemonSoaViewDocument>(options);
using var zoneRender = Reactive<AetheriaRuntimeZoneRenderDocument>(options);
return AetheriaRuntimeObservedDaemonState.TryCreateCurrent(frame, soaView, zoneRender, out var current)
? current
: null;
@ -278,12 +254,13 @@ namespace GameCult.Aetheria.State.Verse
: null;
}
private CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument>? TryReactiveDaemonSoaView(
private CultMeshReactiveDocument<TDocument>? TryReactive<TDocument>(
CultMeshReactiveDocumentOptions? options)
where TDocument : class
{
try
{
return ReactiveDaemonSoaView(options);
return Reactive<TDocument>(options);
}
catch (KeyNotFoundException)
{
@ -532,18 +509,6 @@ namespace GameCult.Aetheria.State.Verse
return LatestZoneRenderAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
public Task<CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument>> ReactiveZoneRenderAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return ZoneRender.ReactiveAsync(options);
}
public CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> ReactiveZoneRender(
CultMeshReactiveDocumentOptions? options = null)
{
return ZoneRender.Reactive(options);
}
public Observable<TDocument> Watch<TDocument>()
where TDocument : class
{

View file

@ -15,7 +15,7 @@ namespace GameCult.Aetheria.State.Verse
{
if (state == null) throw new ArgumentNullException(nameof(state));
using var frame = state.ReactiveDaemonFrame();
using var frame = state.Reactive<AetheriaRuntimeDaemonFrameDocument>();
return Task.FromResult(ProjectLoadoutTemplate(
frame.Current?.Run ?? new AetheriaRuntimeRunCheckpointCommit(),
entityKey ?? ""));

View file

@ -18,11 +18,11 @@ namespace GameCult.Aetheria.State.Verse
if (state == null)
throw new ArgumentNullException(nameof(state));
_daemonFrame = state.ReactiveDaemonFrame();
_catalog = state.ReactiveCatalog();
_loadoutTemplates = state.ReactiveLoadoutTemplates();
_starbridgeScenario = state.Starbridge.ReactiveScenario();
_starbridgeSession = state.Starbridge.ReactiveSession();
_daemonFrame = state.Reactive<AetheriaRuntimeDaemonFrameDocument>();
_catalog = state.Reactive<AetheriaRuntimeCatalogSnapshot>();
_loadoutTemplates = state.Reactive<AetheriaRuntimeLoadoutTemplatesDocument>();
_starbridgeScenario = state.Reactive<AetheriaRuntimeStarbridgeScenarioDocument>();
_starbridgeSession = state.Reactive<AetheriaRuntimeStarbridgeSessionDocument>();
}
public AetheriaRuntimeCatalogSnapshot Catalog => _catalog.Current