Move observed daemon sampling to client owner
This commit is contained in:
parent
1bf8a0be2a
commit
a1b6fc0c07
5 changed files with 73 additions and 35 deletions
|
|
@ -3285,7 +3285,7 @@ static void RequireEveRuntimeBootstrap(string root)
|
|||
"EveSurfaceCommandRequest request",
|
||||
"request.ProviderId, \"aetheria.daemon\"",
|
||||
"AetheriaClient",
|
||||
"client.State.CurrentObservedDaemon()",
|
||||
"client.CurrentObservedDaemon()",
|
||||
"new AetheriaRuntimeDaemonOperationClient(",
|
||||
"AetheriaRuntimeDaemonSurfaceCommandCatalog.TrySubmitArgumentless(",
|
||||
"AetheriaRuntimeDaemonSurfaceCommandCatalog.CommandPrefix"
|
||||
|
|
@ -3304,6 +3304,7 @@ static void RequireEveRuntimeBootstrap(string root)
|
|||
daemonSurfaceCommands.Contains("client.State.ReactiveDaemonFrame()", StringComparison.Ordinal) ||
|
||||
daemonSurfaceCommands.Contains("TryReactiveDaemonSoaView(client)", StringComparison.Ordinal) ||
|
||||
daemonSurfaceCommands.Contains("client.State.ReactiveZoneRender()", StringComparison.Ordinal) ||
|
||||
daemonSurfaceCommands.Contains("client.State.CurrentObservedDaemon()", StringComparison.Ordinal) ||
|
||||
daemonSurfaceCommands.Contains("client.State.ReactiveObservedDaemon()", StringComparison.Ordinal) ||
|
||||
daemonSurfaceCommands.Contains("observedState.TryCurrent(out var current)", StringComparison.Ordinal))
|
||||
{
|
||||
|
|
@ -8248,7 +8249,7 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
|
|||
if (survivingObservedDaemonConvenienceWrappers.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"AetheriaClientState still exposes one-shot observed-daemon aggregate wrappers; use CurrentObservedDaemon() or generic typed document reads: " +
|
||||
"AetheriaClientState still exposes one-shot observed-daemon aggregate wrappers; use caller-owned managed typed documents: " +
|
||||
string.Join(", ", survivingObservedDaemonConvenienceWrappers));
|
||||
}
|
||||
var survivingFixedReactiveWrappers = forbiddenFixedReactiveWrappers
|
||||
|
|
@ -15979,8 +15980,10 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
!observedDaemonState.Contains("CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> zoneRender", StringComparison.Ordinal) ||
|
||||
!observedDaemonState.Contains("var currentZoneRender = zoneRender?.Current;", StringComparison.Ordinal) ||
|
||||
!observedDaemonState.Contains("new AetheriaRuntimeObservedDaemonState(currentFrame, currentSoaView, currentZoneRender)", StringComparison.Ordinal) ||
|
||||
!aetheriaClientState.Contains("using var zoneRender = Reactive<AetheriaRuntimeZoneRenderDocument>(options);", StringComparison.Ordinal) ||
|
||||
!aetheriaClientState.Contains("AetheriaRuntimeObservedDaemonState.TryCreateCurrent(frame, soaView, zoneRender, out var current)", StringComparison.Ordinal))
|
||||
!aetheriaClient.Contains("private CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument>? _observedFrame;", StringComparison.Ordinal) ||
|
||||
!aetheriaClient.Contains("private CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument>? _observedSoaView;", StringComparison.Ordinal) ||
|
||||
!aetheriaClient.Contains("private CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument>? _observedZoneRender;", StringComparison.Ordinal) ||
|
||||
!aetheriaClient.Contains("AetheriaRuntimeObservedDaemonState.TryCreateCurrent(", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Observed zone-render state acquisition must sample managed typed zone-render documents directly.");
|
||||
|
|
@ -16033,7 +16036,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
var requiredManagedClientConnectionSymbols = new[]
|
||||
{
|
||||
"public AetheriaClientState State => _state;",
|
||||
"var observed = State.CurrentObservedDaemon();"
|
||||
"var observed = CurrentObservedDaemon();"
|
||||
};
|
||||
var missingManagedClientConnectionSymbols = requiredManagedClientConnectionSymbols
|
||||
.Where(symbol => !aetheriaClient.Contains(symbol, StringComparison.Ordinal))
|
||||
|
|
@ -16048,6 +16051,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
if (aetheriaClient.Contains("State.ReactiveDaemonFrame()", StringComparison.Ordinal) ||
|
||||
aetheriaClient.Contains("TryReactiveDaemonSoaView()", StringComparison.Ordinal) ||
|
||||
aetheriaClient.Contains("State.ReactiveZoneRender()", StringComparison.Ordinal) ||
|
||||
aetheriaClient.Contains("State.CurrentObservedDaemon()", StringComparison.Ordinal) ||
|
||||
aetheriaClient.Contains("State.ReactiveObservedDaemon()", StringComparison.Ordinal) ||
|
||||
aetheriaClient.Contains("Aetheria() => State", StringComparison.Ordinal) ||
|
||||
aetheriaClient.Contains("observedState.TryCurrent(out var current)", StringComparison.Ordinal))
|
||||
|
|
@ -16063,8 +16067,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
"public Task<TDocument> LatestAsync<TDocument>()",
|
||||
"public Observable<TDocument> Watch<TDocument>()",
|
||||
"public Task<CultMeshReactiveDocument<TDocument>> ReactiveAsync<TDocument>(",
|
||||
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(",
|
||||
"public AetheriaRuntimeObservedDaemonState? CurrentObservedDaemon("
|
||||
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>("
|
||||
};
|
||||
var missingManagedStateAccessSymbols = requiredManagedStateAccessSymbols
|
||||
.Where(symbol => !aetheriaClientState.Contains(symbol, StringComparison.Ordinal))
|
||||
|
|
@ -16076,21 +16079,30 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
string.Join(", ", missingManagedStateAccessSymbols));
|
||||
}
|
||||
|
||||
if (aetheriaClientState.Contains("public AetheriaRuntimeObservedDaemonState? CurrentObservedDaemon(", StringComparison.Ordinal) ||
|
||||
aetheriaClientState.Contains("AetheriaRuntimeObservedDaemonState.TryCreateCurrent(frame, soaView, zoneRender", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"AetheriaClientState must not expose one-shot observed daemon aggregation; command owners should hold managed typed daemon documents.");
|
||||
}
|
||||
|
||||
var requiredManagedObservedDaemonSymbols = new[]
|
||||
{
|
||||
"public AetheriaRuntimeObservedDaemonState? CurrentObservedDaemon(",
|
||||
"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)"
|
||||
"private CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument>? _observedFrame;",
|
||||
"private CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument>? _observedSoaView;",
|
||||
"private CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument>? _observedZoneRender;",
|
||||
"_observedFrame ??= State.Reactive<AetheriaRuntimeDaemonFrameDocument>();",
|
||||
"_observedSoaView ??= State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();",
|
||||
"_observedZoneRender ??= State.Reactive<AetheriaRuntimeZoneRenderDocument>();",
|
||||
"AetheriaRuntimeObservedDaemonState.TryCreateCurrent("
|
||||
};
|
||||
var missingManagedObservedDaemonSymbols = requiredManagedObservedDaemonSymbols
|
||||
.Where(symbol => !aetheriaClientState.Contains(symbol, StringComparison.Ordinal))
|
||||
.Where(symbol => !aetheriaClient.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
if (missingManagedObservedDaemonSymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"AetheriaClientState must compose current observed daemon state from direct managed reactive typed documents: " +
|
||||
"AetheriaClient must compose current observed daemon state from owned managed reactive typed documents: " +
|
||||
string.Join(", ", missingManagedObservedDaemonSymbols));
|
||||
}
|
||||
|
||||
|
|
@ -16099,10 +16111,10 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
!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))
|
||||
daemonRuntimeDocumentTests.Contains("client.State.CurrentObservedDaemon()", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Daemon runtime document tests must teach observed daemon sampling through direct reactive daemon documents and CurrentObservedDaemon().");
|
||||
"Daemon runtime document tests must teach observed daemon sampling through direct reactive daemon documents.");
|
||||
}
|
||||
|
||||
var requiredObservedDaemonStateSymbols = new[]
|
||||
|
|
|
|||
|
|
@ -205,11 +205,15 @@ public class DaemonRuntimeDocumentTests
|
|||
.GetResult();
|
||||
using var zoneRenderReactive = client.State
|
||||
.Reactive<AetheriaRuntimeZoneRenderDocument>();
|
||||
var observed = client.State.CurrentObservedDaemon();
|
||||
var observedAuthoritativeFrame = client.State.Latest<AetheriaRuntimeDaemonFrameDocument>();
|
||||
using var catalogReactive = client.State.Reactive<AetheriaRuntimeCatalogSnapshot>();
|
||||
using var daemonFrameReactive = client.State.Reactive<AetheriaRuntimeDaemonFrameDocument>();
|
||||
using var daemonSoaViewReactive = client.State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();
|
||||
Assert.IsTrue(AetheriaRuntimeObservedDaemonState.TryCreateCurrent(
|
||||
daemonFrameReactive,
|
||||
daemonSoaViewReactive,
|
||||
zoneRenderReactive,
|
||||
out var observed));
|
||||
using var loadoutTemplatesReactive = client.State.Reactive<AetheriaRuntimeLoadoutTemplatesDocument>();
|
||||
using var sectorMapReactive = client.State.Reactive<AetheriaRuntimeSectorMapDocument>();
|
||||
using var playerSettingsReactive = client.State.Reactive<AetheriaRuntimePlayerSettingsDocument>();
|
||||
|
|
@ -2220,7 +2224,14 @@ public class DaemonRuntimeDocumentTests
|
|||
.OpenAsync(statePath, "unity-observer-test", pullOnOpen: true)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
var observed = client.State.CurrentObservedDaemon();
|
||||
using var observedFrame = client.State.Reactive<AetheriaRuntimeDaemonFrameDocument>();
|
||||
using var observedSoaView = client.State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();
|
||||
using var observedZoneRender = client.State.Reactive<AetheriaRuntimeZoneRenderDocument>();
|
||||
Assert.IsTrue(AetheriaRuntimeObservedDaemonState.TryCreateCurrent(
|
||||
observedFrame,
|
||||
observedSoaView,
|
||||
observedZoneRender,
|
||||
out var observed));
|
||||
|
||||
Assert.IsNotNull(observed);
|
||||
Assert.IsTrue(observed.IsAuthoritative);
|
||||
|
|
@ -2281,12 +2292,9 @@ public class DaemonRuntimeDocumentTests
|
|||
out var currentObserved)
|
||||
? currentObserved
|
||||
: null;
|
||||
var sampledObserved = client.State.CurrentObservedDaemon();
|
||||
Assert.IsNotNull(observed);
|
||||
Assert.IsNotNull(sampledObserved);
|
||||
Assert.IsTrue(observed.IsAuthoritative);
|
||||
Assert.AreEqual("reactive-daemon-run", observed.Run.RunId);
|
||||
Assert.AreEqual(observed.Run.RunId, sampledObserved.Run.RunId);
|
||||
Assert.AreEqual("entity:reactive-observer-target", observed.Run.CurrentEntityKey);
|
||||
Assert.AreEqual(330, observed.Frame.FrameId);
|
||||
Assert.AreEqual(331, observed.SoaView.Generation);
|
||||
|
|
@ -2321,7 +2329,14 @@ public class DaemonRuntimeDocumentTests
|
|||
.OpenAsync(statePath, "unity-frame-only-observer-test", pullOnOpen: true)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
var observed = client.State.CurrentObservedDaemon();
|
||||
using var observedFrame = client.State.Reactive<AetheriaRuntimeDaemonFrameDocument>();
|
||||
using var observedSoaView = client.State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();
|
||||
using var observedZoneRender = client.State.Reactive<AetheriaRuntimeZoneRenderDocument>();
|
||||
Assert.IsTrue(AetheriaRuntimeObservedDaemonState.TryCreateCurrent(
|
||||
observedFrame,
|
||||
observedSoaView,
|
||||
observedZoneRender,
|
||||
out var observed));
|
||||
|
||||
Assert.IsNotNull(observed);
|
||||
Assert.IsTrue(observed.IsAuthoritative);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using GameCult.Eve.Surface;
|
||||
using GameCult.Mesh;
|
||||
|
||||
#nullable enable
|
||||
|
||||
|
|
@ -16,6 +17,9 @@ namespace GameCult.Aetheria.State.Verse
|
|||
private readonly AetheriaControl _control;
|
||||
private readonly AetheriaUi _ui;
|
||||
private readonly AetheriaClientState _state;
|
||||
private CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument>? _observedFrame;
|
||||
private CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument>? _observedSoaView;
|
||||
private CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument>? _observedZoneRender;
|
||||
private bool _disposed;
|
||||
|
||||
private AetheriaClient(AetheriaRuntimeVerseClient verse, string clientId, string sessionId)
|
||||
|
|
@ -150,6 +154,9 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return;
|
||||
|
||||
_disposed = true;
|
||||
_observedFrame?.Dispose();
|
||||
_observedSoaView?.Dispose();
|
||||
_observedZoneRender?.Dispose();
|
||||
_verse.Dispose();
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +166,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
ThrowIfDisposed();
|
||||
if (submit == null) throw new ArgumentNullException(nameof(submit));
|
||||
|
||||
var observed = State.CurrentObservedDaemon();
|
||||
var observed = CurrentObservedDaemon();
|
||||
var operationClient = new AetheriaRuntimeDaemonOperationClient(
|
||||
StatePath,
|
||||
_clientId,
|
||||
|
|
@ -172,6 +179,21 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return submit(operationClient, observed);
|
||||
}
|
||||
|
||||
internal AetheriaRuntimeObservedDaemonState? CurrentObservedDaemon()
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
_observedFrame ??= State.Reactive<AetheriaRuntimeDaemonFrameDocument>();
|
||||
_observedSoaView ??= State.Reactive<AetheriaRuntimeDaemonSoaViewDocument>();
|
||||
_observedZoneRender ??= State.Reactive<AetheriaRuntimeZoneRenderDocument>();
|
||||
return AetheriaRuntimeObservedDaemonState.TryCreateCurrent(
|
||||
_observedFrame,
|
||||
_observedSoaView,
|
||||
_observedZoneRender,
|
||||
out var current)
|
||||
? current
|
||||
: null;
|
||||
}
|
||||
|
||||
private void ThrowIfDisposed()
|
||||
{
|
||||
if (_disposed)
|
||||
|
|
|
|||
|
|
@ -215,17 +215,6 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return Document<TDocument>().LatestAsync().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public AetheriaRuntimeObservedDaemonState? CurrentObservedDaemon(
|
||||
CultMeshReactiveDocumentOptions? options = null)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public CultMeshDocumentHandle<TDocument> Document<TDocument>(AetheriaClientEveSurface surface)
|
||||
where TDocument : class
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return false;
|
||||
}
|
||||
|
||||
var observed = client.State.CurrentObservedDaemon();
|
||||
var observed = client.CurrentObservedDaemon();
|
||||
var operationClient = new AetheriaRuntimeDaemonOperationClient(
|
||||
client.StatePath,
|
||||
string.IsNullOrWhiteSpace(request.ClientId) ? AetheriaRuntimeDaemonOperationClient.DefaultClientId : request.ClientId,
|
||||
|
|
|
|||
Loading…
Reference in a new issue