diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 5602218d7..12bdb9369 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -3307,9 +3307,7 @@ static void RequireEveRuntimeBootstrap(string root) } if (daemonSurfaceCommands.Contains("AetheriaRuntimeStateReader.TryReadDaemonRenderView", StringComparison.Ordinal) || - daemonSurfaceCommands.Contains("client.State.ReactiveDaemonFrame()", StringComparison.Ordinal) || daemonSurfaceCommands.Contains("TryReactiveDaemonSoaView(client)", StringComparison.Ordinal) || - daemonSurfaceCommands.Contains("client.State.ReactiveZoneRender()", StringComparison.Ordinal) || daemonSurfaceCommands.Contains("client.CurrentObservedDaemon()", StringComparison.Ordinal) || daemonSurfaceCommands.Contains("client.State.CurrentObservedDaemon()", StringComparison.Ordinal) || daemonSurfaceCommands.Contains("client.State.ReactiveObservedDaemon()", StringComparison.Ordinal) || @@ -8325,6 +8323,12 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root { "public CultMeshDocumentHandle Document()", "public enum AetheriaClientEveSurface", + "public CultMeshDocumentHandle DaemonFrameDocument()", + "public CultMeshReactiveDocument ReactiveDaemonFrame()", + "public CultMeshDocumentHandle DaemonSoaViewDocument()", + "public CultMeshReactiveDocument ReactiveDaemonSoaView()", + "public CultMeshDocumentHandle ZoneRenderDocument()", + "public CultMeshReactiveDocument ReactiveZoneRender()", "public CultMeshDocumentHandle CurrentDocking()", "public CultMeshReactiveDocument ReactiveCurrentDocking()", "public CultMeshDocumentHandle CurrentEntityDocument()", @@ -8390,15 +8394,12 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root "ReactiveStationRefitAsync(", "LatestDaemonFrame(", "LatestDaemonFrameAsync(", - "ReactiveDaemonFrame(", "ReactiveDaemonFrameAsync(", "LatestDaemonSoaView(", "LatestDaemonSoaViewAsync(", - "ReactiveDaemonSoaView(", "ReactiveDaemonSoaViewAsync(", "LatestZoneRender(", "LatestZoneRenderAsync(", - "ReactiveZoneRender(", "ReactiveZoneRenderAsync(", "LatestPlayer(", "LatestPlayerAsync(", @@ -12045,7 +12046,7 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) "AetheriaRuntimeLoadoutTemplatesDocument", "StarbridgeSummaryAsync", "CultMeshReactiveDocument? managedDaemonFrame = null;", - "managedDaemonFrame = state.Reactive();", + "managedDaemonFrame = state.ReactiveDaemonFrame();", "managedCatalog = state.ReactiveCatalogSnapshot();", "managedLoadoutTemplates = state.Reactive();", "managedStarbridgeScenario = state.Reactive();", @@ -12216,7 +12217,7 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) "CultMeshReactiveDocument? _eveStateRefHealth", "CultMeshReactiveDocument? _eveStateRefCommandBoundary", "CultMeshReactiveDocument? _eveStateRefCatalog", - "_eveStateRefFrame ??= Reactive()", + "_eveStateRefFrame ??= ReactiveDaemonFrame()", "_eveStateRefHealth ??= Reactive()", "_eveStateRefCommandBoundary ??= Reactive()", "_eveStateRefCatalog ??= ReactiveCatalogSnapshot()", @@ -16353,6 +16354,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "public static CultMeshReactiveDocument ReactiveStationRefit(", "public static CultMeshReactiveDocument ReactiveCatalogSnapshot(", "public static CultMeshReactiveDocument ReactivePlayerSettingsDocument(", + "public static CultMeshReactiveDocument ReactiveDaemonFrame(", + "public static CultMeshReactiveDocument ReactiveDaemonSoaView(", + "public static CultMeshReactiveDocument ReactiveZoneRender(", "public static CultMeshReactiveDocument Reactive(", "AetheriaClientEveSurface surface", "public static CultMeshReactiveDocument ReactiveEveSurface(", @@ -16500,7 +16504,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "public AetheriaClientState State => _state;", "var frame = CurrentDaemonFrame();", "private CultMeshReactiveDocument? _daemonFrame;", - "_daemonFrame ??= State.Reactive();" + "_daemonFrame ??= State.ReactiveDaemonFrame();" }; var missingManagedClientConnectionSymbols = requiredManagedClientConnectionSymbols .Where(symbol => !aetheriaClient.Contains(symbol, StringComparison.Ordinal)) @@ -16512,9 +16516,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) string.Join(", ", missingManagedClientConnectionSymbols)); } - if (aetheriaClient.Contains("State.ReactiveDaemonFrame()", StringComparison.Ordinal) || - aetheriaClient.Contains("TryReactiveDaemonSoaView()", StringComparison.Ordinal) || - aetheriaClient.Contains("State.ReactiveZoneRender()", StringComparison.Ordinal) || + if (aetheriaClient.Contains("TryReactiveDaemonSoaView()", StringComparison.Ordinal) || aetheriaClient.Contains("CurrentObservedDaemon()", StringComparison.Ordinal) || aetheriaClient.Contains("State.CurrentObservedDaemon()", StringComparison.Ordinal) || aetheriaClient.Contains("State.ReactiveObservedDaemon()", StringComparison.Ordinal) || @@ -16566,7 +16568,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) var requiredManagedCommandFrameSymbols = new[] { "internal AetheriaRuntimeDaemonFrameDocument? CurrentDaemonFrame()", - "_daemonFrame ??= State.Reactive();", + "_daemonFrame ??= State.ReactiveDaemonFrame();", "return _daemonFrame.Current;", "Func submit", "frame?.SessionId ?? _sessionId" @@ -16582,9 +16584,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) } if (!daemonRuntimeDocumentTests.Contains("ManagedStateSamplesCurrentDaemonRenderViewFromReactiveDocuments()", StringComparison.Ordinal) || - !daemonRuntimeDocumentTests.Contains("using var observedFrame = client.State.Reactive();", StringComparison.Ordinal) || - !daemonRuntimeDocumentTests.Contains("using var observedSoaView = client.State.Reactive();", StringComparison.Ordinal) || - !daemonRuntimeDocumentTests.Contains("using var observedZoneRender = client.State.Reactive();", 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("AetheriaRuntimeDaemonRenderView.TryCreateCurrent(", StringComparison.Ordinal) || daemonRuntimeDocumentTests.Contains("client.State.CurrentObservedDaemon()", StringComparison.Ordinal)) { @@ -16805,9 +16807,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) !daemonObserver.Contains("CultMeshReactiveDocument _daemonFrame", StringComparison.Ordinal) || !daemonObserver.Contains("CultMeshReactiveDocument _daemonSoaView", StringComparison.Ordinal) || !daemonObserver.Contains("CultMeshReactiveDocument _zoneRender", StringComparison.Ordinal) || - !daemonObserver.Contains("_daemonFrame ??= state.Reactive();", StringComparison.Ordinal) || - !daemonObserver.Contains("_daemonSoaView ??= TryReactive(state);", StringComparison.Ordinal) || - !daemonObserver.Contains("_zoneRender ??= state.Reactive();", StringComparison.Ordinal) || + !daemonObserver.Contains("_daemonFrame ??= state.ReactiveDaemonFrame();", StringComparison.Ordinal) || + !daemonObserver.Contains("_daemonSoaView ??= state.ReactiveDaemonSoaView();", StringComparison.Ordinal) || + !daemonObserver.Contains("_zoneRender ??= state.ReactiveZoneRender();", StringComparison.Ordinal) || !daemonObserver.Contains("AetheriaRuntimeDaemonRenderView.TryCreateCurrent(", StringComparison.Ordinal) || !daemonObserver.Contains("DisposeRenderViewDocuments()", StringComparison.Ordinal)) { @@ -18275,7 +18277,7 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root) "CultMeshReactiveDocument _loadoutFrame", "CreateLoadoutTemplate(targetEntityKey)", ".CreateLoadoutTemplate(targetEntityKey ?? \"\")", - ".Reactive(\"unity-inventory\")", + ".ReactiveDaemonFrame(\"unity-inventory\")", "_loadoutFrame?.Dispose()", ".Ui(\"unity-inventory\")", ".SaveLoadoutTemplateAsync(loadout, \"unity-inventory\")" @@ -18304,7 +18306,7 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root) "InventoryPanel", "AetheriaRuntimeDaemonFrameDocument", "_loadoutFrame", - ".Reactive(\"unity-inventory\")", + ".ReactiveDaemonFrame(\"unity-inventory\")", "AetheriaRuntimeDaemonFrameSession", ".ObserveDaemonFrame()"); @@ -18360,11 +18362,10 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root) if (snapshotDocuments.Contains("state.Daemon.LatestFrame.ReactiveAsync", StringComparison.Ordinal) || snapshotDocuments.Contains("state.LatestFrame.ReactiveAsync", StringComparison.Ordinal) || - snapshotDocuments.Contains(".ObserveDaemonFrame()", StringComparison.Ordinal) || - snapshotDocuments.Contains(".ReactiveDaemonFrame()", StringComparison.Ordinal)) + snapshotDocuments.Contains(".ObserveDaemonFrame()", StringComparison.Ordinal)) { throw new InvalidOperationException( - "Loadout template save payloads must use generic AetheriaClientState reactive typed document access instead of named wrappers or raw handle walks."); + "Loadout template save payloads must not sample managed daemon-frame state inside snapshot composition."); } if (clientState.Contains("ReactiveLoadoutSnapshotProjector", StringComparison.Ordinal) || diff --git a/Assets/Scripts/Gameplay/AetheriaDaemonObserver.cs b/Assets/Scripts/Gameplay/AetheriaDaemonObserver.cs index 63e11025c..61e0a2488 100644 --- a/Assets/Scripts/Gameplay/AetheriaDaemonObserver.cs +++ b/Assets/Scripts/Gameplay/AetheriaDaemonObserver.cs @@ -129,23 +129,9 @@ public sealed class AetheriaDaemonObserver : MonoBehaviour return; } - _daemonFrame ??= state.Reactive(); - _daemonSoaView ??= TryReactive(state); - _zoneRender ??= state.Reactive(); - } - - private static CultMeshReactiveDocument TryReactive( - AetheriaClientState state) - where TDocument : class - { - try - { - return state.Reactive(); - } - catch (System.Collections.Generic.KeyNotFoundException) - { - return null; - } + _daemonFrame ??= state.ReactiveDaemonFrame(); + _daemonSoaView ??= state.ReactiveDaemonSoaView(); + _zoneRender ??= state.ReactiveZoneRender(); } private AetheriaClientState ResolveState() diff --git a/Assets/Scripts/Gameplay/AetheriaUnityRuntimeClientProvider.cs b/Assets/Scripts/Gameplay/AetheriaUnityRuntimeClientProvider.cs index 2da9d6cd2..6c5438e82 100644 --- a/Assets/Scripts/Gameplay/AetheriaUnityRuntimeClientProvider.cs +++ b/Assets/Scripts/Gameplay/AetheriaUnityRuntimeClientProvider.cs @@ -176,6 +176,45 @@ public static class AetheriaUnityRuntimeClientProvider return RuntimeState(stateBoot, runtimeId).ReactivePlayerSettingsDocument(); } + public static CultMeshReactiveDocument ReactiveDaemonFrame( + string runtimeId = "") + { + return RuntimeState(runtimeId).ReactiveDaemonFrame(); + } + + public static CultMeshReactiveDocument ReactiveDaemonFrame( + AetheriaRuntimeStateBootReport stateBoot, + string runtimeId = "") + { + return RuntimeState(stateBoot, runtimeId).ReactiveDaemonFrame(); + } + + public static CultMeshReactiveDocument ReactiveDaemonSoaView( + string runtimeId = "") + { + return RuntimeState(runtimeId).ReactiveDaemonSoaView(); + } + + public static CultMeshReactiveDocument ReactiveDaemonSoaView( + AetheriaRuntimeStateBootReport stateBoot, + string runtimeId = "") + { + return RuntimeState(stateBoot, runtimeId).ReactiveDaemonSoaView(); + } + + public static CultMeshReactiveDocument ReactiveZoneRender( + string runtimeId = "") + { + return RuntimeState(runtimeId).ReactiveZoneRender(); + } + + public static CultMeshReactiveDocument ReactiveZoneRender( + AetheriaRuntimeStateBootReport stateBoot, + string runtimeId = "") + { + return RuntimeState(stateBoot, runtimeId).ReactiveZoneRender(); + } + public static CultMeshReactiveDocument Reactive( AetheriaRuntimeStateBootReport stateBoot, string runtimeId = "") diff --git a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs index 4014840de..f29e6886c 100644 --- a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs +++ b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs @@ -167,7 +167,7 @@ public class DaemonRuntimeDocumentTests .GetResult(); var currentEntity = ReadLatest(client.State.Document()); - var latestFrame = ReadLatest(client.State.Document()); + var latestFrame = ReadLatest(client.State.DaemonFrameDocument()); var catalog = ReadLatest(client.State.Document()); var playerSettings = ReadLatest(client.State.Document()); var verseHostSettings = ReadLatest(client.State.Document()); @@ -177,7 +177,7 @@ public class DaemonRuntimeDocumentTests .GetAwaiter() .GetResult(); var latestFrameByType = client.State - .Document() + .DaemonFrameDocument() .LatestAsync() .GetAwaiter() .GetResult(); @@ -201,11 +201,11 @@ public class DaemonRuntimeDocumentTests .ReactiveAsync() .GetAwaiter() .GetResult(); - using var zoneRenderReactive = client.State.Reactive(); - var observedAuthoritativeFrame = ReadLatest(client.State.Document()); + using var zoneRenderReactive = client.State.ReactiveZoneRender(); + var observedAuthoritativeFrame = ReadLatest(client.State.DaemonFrameDocument()); using var catalogReactive = client.State.ReactiveCatalogSnapshot(); - using var daemonFrameReactive = client.State.Reactive(); - using var daemonSoaViewReactive = client.State.Reactive(); + using var daemonFrameReactive = client.State.ReactiveDaemonFrame(); + using var daemonSoaViewReactive = client.State.ReactiveDaemonSoaView(); Assert.IsTrue(AetheriaRuntimeDaemonRenderView.TryCreateCurrent( daemonFrameReactive, daemonSoaViewReactive, @@ -251,12 +251,12 @@ public class DaemonRuntimeDocumentTests Assert.AreEqual("aetheria.current.entity", client.State.CurrentEntity.DocumentId); Assert.AreSame(client.State.CurrentEntity, client.State.Document()); Assert.AreSame(client.State.Catalog, client.State.Document()); - Assert.AreSame(client.State.ZoneRender, client.State.Document()); + Assert.AreSame(client.State.ZoneRender, client.State.ZoneRenderDocument()); Assert.AreSame( client.State.StarbridgeSummary, client.State.Document()); - Assert.AreSame(client.State.DaemonFrame, client.State.Document()); - Assert.AreSame(client.State.DaemonSoaView, client.State.Document()); + Assert.AreSame(client.State.DaemonFrame, client.State.DaemonFrameDocument()); + Assert.AreSame(client.State.DaemonSoaView, client.State.DaemonSoaViewDocument()); Assert.IsNotNull(ReadLatest(client.State.Document())); Assert.IsNotNull(ReadLatest(client.State.Document())); Assert.IsNotNull(ReadLatest(client.State.Document())); @@ -2210,9 +2210,9 @@ public class DaemonRuntimeDocumentTests .OpenAsync(statePath, "unity-observer-test", pullOnOpen: true) .GetAwaiter() .GetResult(); - using var observedFrame = client.State.Reactive(); - using var observedSoaView = client.State.Reactive(); - using var observedZoneRender = client.State.Reactive(); + using var observedFrame = client.State.ReactiveDaemonFrame(); + using var observedSoaView = client.State.ReactiveDaemonSoaView(); + using var observedZoneRender = client.State.ReactiveZoneRender(); Assert.IsTrue(AetheriaRuntimeDaemonRenderView.TryCreateCurrent( observedFrame, observedSoaView, @@ -2268,9 +2268,9 @@ public class DaemonRuntimeDocumentTests .OpenAsync(statePath, "unity-reactive-observer-test", pullOnOpen: true) .GetAwaiter() .GetResult(); - using var observedFrame = client.State.Reactive(); - using var observedSoaView = client.State.Reactive(); - using var observedZoneRender = client.State.Reactive(); + using var observedFrame = client.State.ReactiveDaemonFrame(); + using var observedSoaView = client.State.ReactiveDaemonSoaView(); + using var observedZoneRender = client.State.ReactiveZoneRender(); var observed = AetheriaRuntimeDaemonRenderView.TryCreateCurrent( observedFrame, observedSoaView, @@ -2315,9 +2315,9 @@ public class DaemonRuntimeDocumentTests .OpenAsync(statePath, "unity-frame-only-observer-test", pullOnOpen: true) .GetAwaiter() .GetResult(); - using var observedFrame = client.State.Reactive(); - using var observedSoaView = client.State.Reactive(); - using var observedZoneRender = client.State.Reactive(); + using var observedFrame = client.State.ReactiveDaemonFrame(); + using var observedSoaView = client.State.ReactiveDaemonSoaView(); + using var observedZoneRender = client.State.ReactiveZoneRender(); Assert.IsTrue(AetheriaRuntimeDaemonRenderView.TryCreateCurrent( observedFrame, observedSoaView, diff --git a/Assets/Scripts/UI/Menu/InventoryPanel.cs b/Assets/Scripts/UI/Menu/InventoryPanel.cs index 85b2724a9..74c7bad4a 100644 --- a/Assets/Scripts/UI/Menu/InventoryPanel.cs +++ b/Assets/Scripts/UI/Menu/InventoryPanel.cs @@ -1534,7 +1534,7 @@ private void Update() try { _loadoutFrame = AetheriaUnityRuntimeClientProvider - .Reactive("unity-inventory"); + .ReactiveDaemonFrame("unity-inventory"); } catch (Exception ex) { diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs index 358d1e166..7f302e822 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs @@ -180,7 +180,7 @@ namespace GameCult.Aetheria.State.Verse ThrowIfDisposed(); try { - _daemonFrame ??= State.Reactive(); + _daemonFrame ??= State.ReactiveDaemonFrame(); return _daemonFrame.Current; } catch diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs index 4781d0fea..50be3341c 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs @@ -193,6 +193,36 @@ namespace GameCult.Aetheria.State.Verse return Document().Reactive(); } + public CultMeshDocumentHandle DaemonFrameDocument() + { + return DaemonFrame; + } + + public CultMeshReactiveDocument ReactiveDaemonFrame() + { + return DaemonFrameDocument().Reactive(); + } + + public CultMeshDocumentHandle DaemonSoaViewDocument() + { + return DaemonSoaView; + } + + public CultMeshReactiveDocument ReactiveDaemonSoaView() + { + return DaemonSoaViewDocument().Reactive(); + } + + public CultMeshDocumentHandle ZoneRenderDocument() + { + return ZoneRender; + } + + public CultMeshReactiveDocument ReactiveZoneRender() + { + return ZoneRenderDocument().Reactive(); + } + public CultMeshDocumentHandle CurrentDocking() { return CurrentDockingDocument; @@ -380,7 +410,7 @@ namespace GameCult.Aetheria.State.Verse public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver() { - _eveStateRefFrame ??= Reactive(); + _eveStateRefFrame ??= ReactiveDaemonFrame(); _eveStateRefHealth ??= Reactive(); _eveStateRefCommandBoundary ??= Reactive(); _eveStateRefCatalog ??= ReactiveCatalogSnapshot(); diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs index fa0aa3f24..7933b71fb 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs @@ -497,7 +497,7 @@ namespace GameCult.Aetheria.State.Verse seatId => Document( AetheriaRuntimeVerseRecordKeys.StarbridgePlayerSeat(seatId))); - managedDaemonFrame = state.Reactive(); + managedDaemonFrame = state.ReactiveDaemonFrame(); managedCatalog = state.ReactiveCatalogSnapshot(); managedLoadoutTemplates = state.Reactive(); managedStarbridgeScenario = state.Reactive();