Remove generic managed state access

This commit is contained in:
Meta Vens 2026-06-29 08:06:19 +01:00
commit f49e9b200b
4 changed files with 167 additions and 213 deletions

View file

@ -7179,10 +7179,10 @@ static void RequireInventoryValidationUsesManagedTypedDocuments(string root)
}
var clientState = File.ReadAllText(clientStatePath);
if (!clientState.Contains("public CultMeshDocumentHandle<TDocument> Document<TDocument>()", StringComparison.Ordinal) ||
!clientState.Contains("public CultMeshDocumentHandle<TDocument> Document<TDocument>(int index)", StringComparison.Ordinal) ||
!clientState.Contains("public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(", StringComparison.Ordinal) ||
!clientState.Contains("public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(int index)", StringComparison.Ordinal) ||
if (!clientState.Contains("public CultMeshDocumentHandle<AetheriaRuntimeInventoryDocument> Inventory(", StringComparison.Ordinal) ||
!clientState.Contains("public CultMeshReactiveDocument<AetheriaRuntimeInventoryDocument> ReactiveInventory(", StringComparison.Ordinal) ||
!clientState.Contains("public CultMeshDocumentHandle<AetheriaRuntimeZoneDetailsDocument> ZoneDetails(", StringComparison.Ordinal) ||
!clientState.Contains("public CultMeshReactiveDocument<AetheriaRuntimeZoneDetailsDocument> ReactiveZoneDetails(", StringComparison.Ordinal) ||
clientState.Contains("AetheriaClientState.Zone(", StringComparison.Ordinal) ||
clientState.Contains("AetheriaClientState.Entity(", StringComparison.Ordinal) ||
clientState.Contains("AetheriaClientZone", StringComparison.Ordinal) ||
@ -7303,7 +7303,8 @@ static void RequireMenuDockingUsesManagedTypedSnapshot(string root)
{
"public CultMeshDocumentHandle<AetheriaRuntimeStationRefitDocument> StationRefit { get; }",
"public CultMeshDocumentHandle<AetheriaRuntimeCurrentDockingDocument> CurrentDockingDocument { get; }",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()"
"public CultMeshDocumentHandle<AetheriaRuntimeStationRefitDocument> StationRefitDocument()",
"public CultMeshDocumentHandle<AetheriaRuntimeCurrentDockingDocument> CurrentDocking()"
};
var missingClientSymbols = requiredClientSymbols
.Where(symbol => !clientState.Contains(symbol, StringComparison.Ordinal))
@ -7475,8 +7476,9 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root)
var clientState = File.ReadAllText(clientStatePath);
var requiredClientSymbols = new[]
{
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(int index)"
"public CultMeshDocumentHandle<AetheriaRuntimeCatalogSnapshot> CatalogSnapshot()",
"public CultMeshDocumentHandle<AetheriaRuntimePlayerSettingsDocument> PlayerSettingsDocument()",
"public CultMeshDocumentHandle<AetheriaRuntimeInventoryDocument> Inventory("
};
var missingClientSymbols = requiredClientSymbols
.Where(symbol => !clientState.Contains(symbol, StringComparison.Ordinal))
@ -7484,7 +7486,7 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root)
if (missingClientSymbols.Length > 0)
{
throw new InvalidOperationException(
"AetheriaClientState must expose typed document handles for shared and indexed Unity documents, with reactive sync owned by CultMesh handles: " +
"AetheriaClientState must expose named typed document handles for shared and indexed Unity documents, with reactive sync owned by CultMesh handles: " +
string.Join(", ", missingClientSymbols));
}
@ -8113,7 +8115,6 @@ static void RequireUnityViewportAndMapReadsUseManagedAccessors(string root)
var clientState = File.ReadAllText(clientStatePath);
var requiredClientSymbols = new[]
{
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()",
"public CultMeshDocumentHandle<AetheriaRuntimeObjectsViewportDocument> ObjectsViewport(",
"public CultMeshReactiveDocument<AetheriaRuntimeObjectsViewportDocument> ReactiveObjectsViewport(",
"public CultMeshDocumentHandle<AetheriaRuntimeRenderSplatsViewportDocument> RenderSplatsViewport(",
@ -8325,8 +8326,15 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
StringSplitOptions.None)[0];
var requiredClientSymbols = new[]
{
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()",
"public enum AetheriaClientEveSurface",
"public CultMeshDocumentHandle<AetheriaRuntimeDaemonProviderAdvertisementDocument> ProviderAdvertisementDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonProviderAdvertisementDocument> ReactiveProviderAdvertisement()",
"public CultMeshDocumentHandle<AetheriaRuntimeDaemonHealthDocument> HealthDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonHealthDocument> ReactiveHealth()",
"public CultMeshDocumentHandle<AetheriaRuntimeDaemonCommandBoundaryDocument> CommandBoundaryDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonCommandBoundaryDocument> ReactiveCommandBoundary()",
"public CultMeshDocumentHandle<AetheriaRuntimeVerseAuthorityPolicyDocument> AuthorityPolicyDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeVerseAuthorityPolicyDocument> ReactiveAuthorityPolicy()",
"public CultMeshDocumentHandle<AetheriaRuntimeDaemonFrameDocument> DaemonFrameDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> ReactiveDaemonFrame()",
"public CultMeshDocumentHandle<AetheriaRuntimeDaemonSoaViewDocument> DaemonSoaViewDocument()",
@ -8356,15 +8364,6 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
"public static bool TryResolveEveSurface(",
"public CultMeshDocumentHandle<global::Aetheria.State.Documents.EveSurfaceState>? EveSurfaceDocument(",
"public CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>? ReactiveEveSurface(",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(AetheriaClientEveSurface surface)",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(AetheriaRuntimeRtsViewportBounds viewport)",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(int index)",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(string seatId)",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>()",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(AetheriaClientEveSurface surface)",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(AetheriaRuntimeRtsViewportBounds viewport)",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(int index)",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(string seatId)",
"public CultMeshDocumentHandle<AetheriaRuntimeRtsViewportDocument> RtsViewport(",
"public CultMeshReactiveDocument<AetheriaRuntimeRtsViewportDocument> ReactiveRtsViewport(",
"public CultMeshDocumentHandle<AetheriaRuntimeObjectsViewportDocument> ObjectsViewport(",
@ -8379,6 +8378,12 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
"public CultMeshReactiveDocument<AetheriaRuntimeSelectedObjectDocument> ReactiveSelectedObject(",
"public CultMeshDocumentHandle<AetheriaRuntimeInventoryDocument> Inventory(",
"public CultMeshReactiveDocument<AetheriaRuntimeInventoryDocument> ReactiveInventory(",
"public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeScenarioDocument> StarbridgeScenarioDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeStarbridgeScenarioDocument> ReactiveStarbridgeScenario()",
"public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeSessionDocument> StarbridgeSessionDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeStarbridgeSessionDocument> ReactiveStarbridgeSession()",
"public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeSessionSummaryDocument> StarbridgeSummaryDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeStarbridgeSessionSummaryDocument> ReactiveStarbridgeSummary()",
"public CultMeshDocumentHandle<AetheriaRuntimeStarbridgePlayerSeatDocument> StarbridgePlayerSeat(",
"public CultMeshReactiveDocument<AetheriaRuntimeStarbridgePlayerSeatDocument> ReactiveStarbridgePlayerSeat("
};
@ -8394,11 +8399,15 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
if (clientState.Contains("public Task<TDocument> LatestAsync<TDocument>", StringComparison.Ordinal) ||
clientState.Contains("public TDocument Latest<TDocument>", StringComparison.Ordinal) ||
clientState.Contains("public CultMeshDocumentHandle<TDocument> Document<TDocument>", StringComparison.Ordinal) ||
clientState.Contains("public CultMeshReactiveDocument<TDocument> Reactive<TDocument>", StringComparison.Ordinal) ||
clientState.Contains("TryGetDocument<TDocument>", StringComparison.Ordinal) ||
clientState.Contains("CultMeshDocumentCatalog", StringComparison.Ordinal) ||
clientState.Contains("public Task<CultMeshReactiveDocument<TDocument>> ReactiveAsync<TDocument>", StringComparison.Ordinal) ||
clientState.Contains("public Observable<TDocument> Watch<TDocument>", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"AetheriaClientState must not reintroduce generic latest/watch shortcuts; callers should sample native typed document handles.");
"AetheriaClientState must not reintroduce generic document catalogs or latest/watch shortcuts; callers should use named typed document handles.");
}
var forbiddenFixedReactiveWrappers = new[]
@ -8748,7 +8757,7 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root
if (!clientState.Contains("StarbridgeSummary", StringComparison.Ordinal) ||
!checkedSources["DaemonRuntimeDocumentTests.cs"].Contains(
"client.State.Document<AetheriaRuntimeStarbridgeSessionSummaryDocument>()",
"client.State.StarbridgeSummaryDocument()",
StringComparison.Ordinal))
{
throw new InvalidOperationException(
@ -12071,8 +12080,8 @@ static void RequireAetheriaRuntimeVerseClientContract(string root)
"managedDaemonFrame = state.ReactiveDaemonFrame();",
"managedCatalog = state.ReactiveCatalogSnapshot();",
"managedLoadoutTemplates = state.ReactiveLoadoutTemplates();",
"managedStarbridgeScenario = state.Reactive<AetheriaRuntimeStarbridgeScenarioDocument>();",
"managedStarbridgeSession = state.Reactive<AetheriaRuntimeStarbridgeSessionDocument>();",
"managedStarbridgeScenario = state.ReactiveStarbridgeScenario();",
"managedStarbridgeSession = state.ReactiveStarbridgeSession();",
"AetheriaRuntimeDaemonFrameDocument RequireManagedFrame()",
"RequireManagedFrame()",
"RequireManagedCatalog()",
@ -12184,7 +12193,7 @@ static void RequireAetheriaRuntimeVerseClientContract(string root)
client.Contains("latestFrameDocument.Reactive()", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Aetheria Verse client derived documents must sample directly owned generic reactive typed documents instead of a named input/session wrapper.");
"Aetheria Verse client derived documents must sample directly owned named reactive typed documents instead of an input/session wrapper.");
}
if (client.Contains("AetheriaRuntimeReactiveProjectionInputs", StringComparison.Ordinal) ||
@ -12232,16 +12241,17 @@ static void RequireAetheriaRuntimeVerseClientContract(string root)
{
"public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()",
"public sealed class AetheriaClientState : IDisposable",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(int index)",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(int index)",
"Aetheria typed state does not expose an indexed document",
"public CultMeshDocumentHandle<AetheriaRuntimeInventoryDocument> Inventory(",
"public CultMeshReactiveDocument<AetheriaRuntimeInventoryDocument> ReactiveInventory(",
"public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeSessionDocument> StarbridgeSessionDocument()",
"public CultMeshReactiveDocument<AetheriaRuntimeStarbridgeSessionDocument> ReactiveStarbridgeSession()",
"CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument>? _eveStateRefFrame",
"CultMeshReactiveDocument<AetheriaRuntimeDaemonHealthDocument>? _eveStateRefHealth",
"CultMeshReactiveDocument<AetheriaRuntimeDaemonCommandBoundaryDocument>? _eveStateRefCommandBoundary",
"CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot>? _eveStateRefCatalog",
"_eveStateRefFrame ??= ReactiveDaemonFrame()",
"_eveStateRefHealth ??= Reactive<AetheriaRuntimeDaemonHealthDocument>()",
"_eveStateRefCommandBoundary ??= Reactive<AetheriaRuntimeDaemonCommandBoundaryDocument>()",
"_eveStateRefHealth ??= ReactiveHealth()",
"_eveStateRefCommandBoundary ??= ReactiveCommandBoundary()",
"_eveStateRefCatalog ??= ReactiveCatalogSnapshot()",
"() => _eveStateRefFrame.Current",
"() => _eveStateRefHealth.Current",
@ -16569,11 +16579,12 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
var requiredManagedStateAccessSymbols = new[]
{
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(AetheriaClientEveSurface surface)",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(AetheriaRuntimeRtsViewportBounds viewport)",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(int index)",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>(string seatId)"
"public CultMeshDocumentHandle<AetheriaRuntimeDaemonFrameDocument> DaemonFrameDocument()",
"public CultMeshDocumentHandle<AetheriaRuntimeCatalogSnapshot> CatalogSnapshot()",
"public CultMeshDocumentHandle<AetheriaRuntimeCurrentEntityDocument> CurrentEntityDocument()",
"public CultMeshDocumentHandle<AetheriaRuntimeObjectsViewportDocument> ObjectsViewport(",
"public CultMeshDocumentHandle<AetheriaRuntimeInventoryDocument> Inventory(",
"public CultMeshDocumentHandle<AetheriaRuntimeStarbridgePlayerSeatDocument> StarbridgePlayerSeat("
};
var missingManagedStateAccessSymbols = requiredManagedStateAccessSymbols
.Where(symbol => !aetheriaClientState.Contains(symbol, StringComparison.Ordinal))
@ -16581,19 +16592,23 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
if (missingManagedStateAccessSymbols.Length > 0)
{
throw new InvalidOperationException(
"AetheriaClientState must expose direct typed document handles instead of AetheriaClient forwarding shortcuts or per-document session wrappers: " +
"AetheriaClientState must expose direct named typed document handles instead of AetheriaClient forwarding shortcuts or per-document session wrappers: " +
string.Join(", ", missingManagedStateAccessSymbols));
}
if (aetheriaClientState.Contains("public Task<TDocument> LatestAsync<TDocument>", StringComparison.Ordinal) ||
aetheriaClientState.Contains("public TDocument Latest<TDocument>", StringComparison.Ordinal) ||
aetheriaClientState.Contains("public Observable<TDocument> Watch<TDocument>", StringComparison.Ordinal) ||
aetheriaClientState.Contains("public CultMeshDocumentHandle<TDocument> Document<TDocument>", StringComparison.Ordinal) ||
aetheriaClientState.Contains("public CultMeshReactiveDocument<TDocument> Reactive<TDocument>", StringComparison.Ordinal) ||
aetheriaClientState.Contains("TryGetDocument<TDocument>", StringComparison.Ordinal) ||
aetheriaClientState.Contains("CultMeshDocumentCatalog", StringComparison.Ordinal) ||
aetheriaClientState.Contains("public Task<CultMeshReactiveDocument<TDocument>> ReactiveAsync<TDocument>", StringComparison.Ordinal) ||
aetheriaClientState.Contains("DocumentBySchema(", StringComparison.Ordinal) ||
aetheriaClientState.Contains("TryGetDocumentBySchema(", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"AetheriaClientState still exposes generic latest/watch or schema-string shortcuts instead of direct typed CultMesh document handles.");
"AetheriaClientState still exposes generic document catalogs, latest/watch, or schema-string shortcuts instead of direct named typed CultMesh document handles.");
}
if (aetheriaClientState.Contains("public AetheriaRuntimeDaemonRenderView? CurrentObservedDaemon(", StringComparison.Ordinal) ||

View file

@ -166,13 +166,13 @@ public class DaemonRuntimeDocumentTests
.GetAwaiter()
.GetResult();
var currentEntity = ReadLatest(client.State.Document<AetheriaRuntimeCurrentEntityDocument>());
var currentEntity = ReadLatest(client.State.CurrentEntityDocument());
var latestFrame = ReadLatest(client.State.DaemonFrameDocument());
var catalog = ReadLatest(client.State.Document<AetheriaRuntimeCatalogSnapshot>());
var playerSettings = ReadLatest(client.State.Document<AetheriaRuntimePlayerSettingsDocument>());
var catalog = ReadLatest(client.State.CatalogSnapshot());
var playerSettings = ReadLatest(client.State.PlayerSettingsDocument());
var verseHostSettings = ReadLatest(client.State.VerseHostSettingsDocument());
var currentEntityByType = client.State
.Document<AetheriaRuntimeCurrentEntityDocument>()
.CurrentEntityDocument()
.LatestAsync()
.GetAwaiter()
.GetResult();
@ -192,12 +192,12 @@ public class DaemonRuntimeDocumentTests
var zoneDetails = ReadLatest(client.State.ZoneDetails(0));
var inventory = ReadLatest(client.State.Inventory(0));
var currentEntityFromClientType = client.State
.Document<AetheriaRuntimeCurrentEntityDocument>()
.CurrentEntityDocument()
.LatestAsync()
.GetAwaiter()
.GetResult();
using var currentEntityReactive = client.State
.Document<AetheriaRuntimeCurrentEntityDocument>()
.CurrentEntityDocument()
.ReactiveAsync()
.GetAwaiter()
.GetResult();
@ -230,38 +230,38 @@ public class DaemonRuntimeDocumentTests
using var playerHudCatalog = client.State.ReactiveCatalogSnapshot();
using var playerHudSettings = client.State.ReactivePlayerSettingsDocument();
using var playerHudEntity = client.State.ReactiveCurrentEntity();
var gameSurface = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.Game));
var gameTuiSurface = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.GameTui));
var editorSurface = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.Editor));
var editorTuiSurface = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.EditorTui));
var authorityStatus = ReadLatest(client.State.Document<AetheriaRuntimeVerseAuthorityPolicyDocument>());
var gameSurface = ReadLatest(client.State.GameSurface);
var gameTuiSurface = ReadLatest(client.State.GameTuiSurface);
var editorSurface = ReadLatest(client.State.EditorSurface);
var editorTuiSurface = ReadLatest(client.State.EditorTuiSurface);
var authorityStatus = ReadLatest(client.State.AuthorityPolicyDocument());
var currentDocking = client.State.CurrentDockingDocument
.LatestAsync()
.GetAwaiter()
.GetResult();
var stationRefit = ReadLatest(client.State.Document<AetheriaRuntimeStationRefitDocument>());
var stationRefit = ReadLatest(client.State.StationRefitDocument());
Assert.AreEqual(currentEntity.EntityKey, currentEntityDocumentReactive.Current.EntityKey);
Assert.AreEqual(currentDocking.CurrentEntityKey, currentDockingReactive.Current.CurrentEntityKey);
Assert.AreEqual(stationRefit.StationEntityKey, stationRefitReactive.Current.StationEntityKey);
using var reactiveGameSurface = client.State.Reactive<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.Game);
using var reactiveGameTuiSurface = client.State.Reactive<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.GameTui);
using var reactiveEditorSurface = client.State.Reactive<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.Editor);
using var reactiveEditorTuiSurface = client.State.Reactive<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.EditorTui);
using var reactiveGameSurface = client.State.GameSurface.Reactive();
using var reactiveGameTuiSurface = client.State.GameTuiSurface.Reactive();
using var reactiveEditorSurface = client.State.EditorSurface.Reactive();
using var reactiveEditorTuiSurface = client.State.EditorTuiSurface.Reactive();
Assert.AreEqual("aetheria.current.entity", client.State.CurrentEntity.DocumentId);
Assert.AreSame(client.State.CurrentEntity, client.State.Document<AetheriaRuntimeCurrentEntityDocument>());
Assert.AreSame(client.State.Catalog, client.State.Document<AetheriaRuntimeCatalogSnapshot>());
Assert.AreSame(client.State.CurrentEntity, client.State.CurrentEntityDocument());
Assert.AreSame(client.State.Catalog, client.State.CatalogSnapshot());
Assert.AreSame(client.State.ZoneRender, client.State.ZoneRenderDocument());
Assert.AreSame(
client.State.StarbridgeSummary,
client.State.Document<AetheriaRuntimeStarbridgeSessionSummaryDocument>());
client.State.StarbridgeSummaryDocument());
Assert.AreSame(client.State.DaemonFrame, client.State.DaemonFrameDocument());
Assert.AreSame(client.State.DaemonSoaView, client.State.DaemonSoaViewDocument());
Assert.IsNotNull(ReadLatest(client.State.Document<AetheriaRuntimeDaemonProviderAdvertisementDocument>()));
Assert.IsNotNull(ReadLatest(client.State.Document<AetheriaRuntimeDaemonHealthDocument>()));
Assert.IsNotNull(ReadLatest(client.State.Document<AetheriaRuntimeDaemonCommandBoundaryDocument>()));
Assert.IsNotNull(ReadLatest(client.State.ProviderAdvertisementDocument()));
Assert.IsNotNull(ReadLatest(client.State.HealthDocument()));
Assert.IsNotNull(ReadLatest(client.State.CommandBoundaryDocument()));
Assert.AreSame(
client.State.Document<AetheriaRuntimeVerseAuthorityPolicyDocument>(),
client.State.AuthorityPolicyDocument(),
client.State.AuthorityPolicy);
Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId, reactiveGameSurface.Current.Surface.Id);
Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, reactiveGameTuiSurface.Current.Surface.Id);
@ -269,15 +269,14 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, reactiveEditorTuiSurface.Current.Surface.Id);
Assert.AreEqual(currentDocking.CurrentEntityKey, currentDockingReactive.Current.CurrentEntityKey);
Assert.AreEqual(stationRefit.StationEntityKey, stationRefitReactive.Current.StationEntityKey);
Assert.AreSame(client.State.PlayerSettings, client.State.Document<AetheriaRuntimePlayerSettingsDocument>());
Assert.AreSame(client.State.PlayerSettings, client.State.PlayerSettingsDocument());
Assert.AreSame(client.State.VerseHostSettings, client.State.VerseHostSettingsDocument());
Assert.AreSame(client.State.CurrentEntity, client.State.Document<AetheriaRuntimeCurrentEntityDocument>());
Assert.AreSame(client.State.CurrentEntity, client.State.CurrentEntityDocument());
Assert.AreSame(client.State.ZoneContacts, client.State.ZoneContactsDocument());
Assert.AreEqual(
typeof(AetheriaRuntimeCurrentEntityDocument),
client.State.Document<AetheriaRuntimeCurrentEntityDocument>().DocumentType);
Assert.IsTrue(client.State.TryGetDocument<AetheriaRuntimeSectorMapDocument>(out var sectorMapDocument));
Assert.AreSame(client.State.SectorMap, sectorMapDocument);
client.State.CurrentEntityDocument().DocumentType);
Assert.AreSame(client.State.SectorMap, client.State.SectorMapDocument());
Assert.AreEqual(AetheriaRuntimeDaemonSchemas.CurrentEntity, currentEntity.Schema);
Assert.AreEqual(AetheriaRuntimeDaemonSchemas.Frame, latestFrame.Schema);
Assert.AreEqual(frame.FrameId, latestFrame.FrameId);
@ -361,9 +360,9 @@ public class DaemonRuntimeDocumentTests
.GetAwaiter()
.GetResult();
var player = ReadLatest(client.State.Document<AetheriaRuntimePlayerSettingsDocument>());
var player = ReadLatest(client.State.PlayerSettingsDocument());
var verseHost = ReadLatest(client.State.VerseHostSettingsDocument());
var catalog = ReadLatest(client.State.Document<AetheriaRuntimeCatalogSnapshot>());
var catalog = ReadLatest(client.State.CatalogSnapshot());
Assert.AreEqual(AetheriaRuntimeCatalogSnapshot.SchemaId, client.State.Catalog.Sources.Last().SchemaId);
Assert.IsNotNull(catalog);
@ -371,7 +370,7 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual(AetheriaRuntimeVerseHostSettingsDocument.SchemaId, verseHost.Schema);
Assert.AreEqual("", player.PlayerName);
Assert.AreEqual("", verseHost.VerseId);
Assert.AreSame(client.State.PlayerSettings, client.State.Document<AetheriaRuntimePlayerSettingsDocument>());
Assert.AreSame(client.State.PlayerSettings, client.State.PlayerSettingsDocument());
Assert.AreSame(client.State.VerseHostSettings, client.State.VerseHostSettingsDocument());
}
@ -597,10 +596,10 @@ public class DaemonRuntimeDocumentTests
.OpenAsync(statePath, "unity-surface-test", pullOnOpen: true)
.GetAwaiter()
.GetResult();
var unityGameSurfaceState = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.Game));
var unityGameTuiSurfaceState = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.GameTui));
var unityEditorSurfaceState = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.Editor));
var unityEditorTuiSurfaceState = ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.EditorTui));
var unityGameSurfaceState = ReadLatest(client.State.GameSurface);
var unityGameTuiSurfaceState = ReadLatest(client.State.GameTuiSurface);
var unityEditorSurfaceState = ReadLatest(client.State.EditorSurface);
var unityEditorTuiSurfaceState = ReadLatest(client.State.EditorTuiSurface);
var surfaceResolver = client.State.CreateEveSurfaceCultMeshStateRefResolver();
var unityGameSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(
unityGameSurfaceState,
@ -632,7 +631,7 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, unityEditorTuiSurface.Surface.Id);
Assert.AreEqual("editor.daemon", unityEditorTuiSurface.ProviderKind);
var genericGameSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(
ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.Game)),
ReadLatest(client.State.GameSurface),
surfaceResolver);
Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId, genericGameSurface.Surface.Id);
Assert.AreEqual(unityGameSurface.ProviderId, genericGameSurface.ProviderId);
@ -655,11 +654,11 @@ public class DaemonRuntimeDocumentTests
AetheriaRuntimeDaemonStateRefs.CurrentTargetName,
AetheriaRuntimeDaemonSchemas.Frame));
var genericGameTuiSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(
ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.GameTui)),
ReadLatest(client.State.GameTuiSurface),
surfaceResolver);
Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, genericGameTuiSurface.Surface.Id);
var genericEditorTuiSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(
ReadLatest(client.State.Document<global::Aetheria.State.Documents.EveSurfaceState>(AetheriaClientEveSurface.EditorTui)),
ReadLatest(client.State.EditorTuiSurface),
surfaceResolver);
Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, genericEditorTuiSurface.Surface.Id);
}

View file

@ -15,7 +15,6 @@ namespace GameCult.Aetheria.State.Verse
public sealed class AetheriaClientState : IDisposable
{
private readonly CultMeshDocumentCatalog _documents;
private readonly Func<AetheriaRuntimeRtsViewportBounds, CultMeshDocumentHandle<AetheriaRuntimeRtsViewportDocument>> _mapViewport;
private readonly Func<AetheriaRuntimeRtsViewportBounds, CultMeshDocumentHandle<AetheriaRuntimeObjectsViewportDocument>> _objectsViewport;
private readonly Func<AetheriaRuntimeRtsViewportBounds, CultMeshDocumentHandle<AetheriaRuntimeGravityViewportDocument>> _gravityViewport;
@ -95,41 +94,56 @@ namespace GameCult.Aetheria.State.Verse
StarbridgeSession = starbridgeSession ?? throw new ArgumentNullException(nameof(starbridgeSession));
StarbridgeSummary = starbridgeSummary ?? throw new ArgumentNullException(nameof(starbridgeSummary));
_starbridgePlayerSeat = starbridgePlayerSeat ?? throw new ArgumentNullException(nameof(starbridgePlayerSeat));
_documents = CultMesh.Documents(
ProviderAdvertisement,
Health,
CommandBoundary,
AuthorityPolicy,
GameSurface,
GameTuiSurface,
EditorSurface,
EditorTuiSurface,
DaemonFrame,
DaemonSoaView,
Catalog,
LoadoutTemplates,
PlayerSettings,
VerseHostSettings,
CurrentZone,
CurrentEntity,
CurrentDockingDocument,
ZoneContacts,
StationRefit,
SectorMap,
ZoneRender,
StarbridgeScenario,
StarbridgeSession,
StarbridgeSummary);
}
public CultMeshDocumentHandle<AetheriaRuntimeDaemonProviderAdvertisementDocument> ProviderAdvertisement { get; }
public CultMeshDocumentHandle<AetheriaRuntimeDaemonProviderAdvertisementDocument> ProviderAdvertisementDocument()
{
return ProviderAdvertisement;
}
public CultMeshReactiveDocument<AetheriaRuntimeDaemonProviderAdvertisementDocument> ReactiveProviderAdvertisement()
{
return ProviderAdvertisementDocument().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeDaemonHealthDocument> Health { get; }
public CultMeshDocumentHandle<AetheriaRuntimeDaemonHealthDocument> HealthDocument()
{
return Health;
}
public CultMeshReactiveDocument<AetheriaRuntimeDaemonHealthDocument> ReactiveHealth()
{
return HealthDocument().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeDaemonCommandBoundaryDocument> CommandBoundary { get; }
public CultMeshDocumentHandle<AetheriaRuntimeDaemonCommandBoundaryDocument> CommandBoundaryDocument()
{
return CommandBoundary;
}
public CultMeshReactiveDocument<AetheriaRuntimeDaemonCommandBoundaryDocument> ReactiveCommandBoundary()
{
return CommandBoundaryDocument().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeVerseAuthorityPolicyDocument> AuthorityPolicy { get; }
public CultMeshDocumentHandle<AetheriaRuntimeVerseAuthorityPolicyDocument> AuthorityPolicyDocument()
{
return AuthorityPolicy;
}
public CultMeshReactiveDocument<AetheriaRuntimeVerseAuthorityPolicyDocument> ReactiveAuthorityPolicy()
{
return AuthorityPolicyDocument().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeDaemonFrameDocument> DaemonFrame { get; }
public CultMeshDocumentHandle<AetheriaRuntimeDaemonSoaViewDocument> DaemonSoaView { get; }
@ -158,10 +172,40 @@ namespace GameCult.Aetheria.State.Verse
public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeScenarioDocument> StarbridgeScenario { get; }
public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeScenarioDocument> StarbridgeScenarioDocument()
{
return StarbridgeScenario;
}
public CultMeshReactiveDocument<AetheriaRuntimeStarbridgeScenarioDocument> ReactiveStarbridgeScenario()
{
return StarbridgeScenarioDocument().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeSessionDocument> StarbridgeSession { get; }
public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeSessionDocument> StarbridgeSessionDocument()
{
return StarbridgeSession;
}
public CultMeshReactiveDocument<AetheriaRuntimeStarbridgeSessionDocument> ReactiveStarbridgeSession()
{
return StarbridgeSessionDocument().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeSessionSummaryDocument> StarbridgeSummary { get; }
public CultMeshDocumentHandle<AetheriaRuntimeStarbridgeSessionSummaryDocument> StarbridgeSummaryDocument()
{
return StarbridgeSummary;
}
public CultMeshReactiveDocument<AetheriaRuntimeStarbridgeSessionSummaryDocument> ReactiveStarbridgeSummary()
{
return StarbridgeSummaryDocument().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeZoneContactsDocument> ZoneContacts { get; }
public CultMeshDocumentHandle<AetheriaRuntimeStationRefitDocument> StationRefit { get; }
@ -170,29 +214,6 @@ namespace GameCult.Aetheria.State.Verse
public CultMeshDocumentHandle<AetheriaRuntimeZoneRenderDocument> ZoneRender { get; }
public bool TryGetDocument<TDocument>(
out CultMeshDocumentHandle<TDocument> document)
where TDocument : class
{
return _documents.TryGetDocument(out document);
}
public CultMeshDocumentHandle<TDocument> Document<TDocument>()
where TDocument : class
{
if (TryGetDocument<TDocument>(out var document))
return document;
throw new NotSupportedException(
$"Aetheria typed state does not expose a managed document for {typeof(TDocument).FullName}.");
}
public CultMeshReactiveDocument<TDocument> Reactive<TDocument>()
where TDocument : class
{
return Document<TDocument>().Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeDaemonFrameDocument> DaemonFrameDocument()
{
return DaemonFrame;
@ -358,25 +379,10 @@ namespace GameCult.Aetheria.State.Verse
public CultMeshDocumentHandle<global::Aetheria.State.Documents.EveSurfaceState>? EveSurfaceDocument(
string? surfaceId)
{
return TryResolveEveSurface(surfaceId, out var surface)
? Document<global::Aetheria.State.Documents.EveSurfaceState>(surface)
: null;
}
if (!TryResolveEveSurface(surfaceId, out var surface))
return null;
public CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>? ReactiveEveSurface(
string? surfaceId)
{
return EveSurfaceDocument(surfaceId)?.Reactive();
}
public CultMeshDocumentHandle<TDocument> Document<TDocument>(AetheriaClientEveSurface surface)
where TDocument : class
{
if (typeof(TDocument) != typeof(global::Aetheria.State.Documents.EveSurfaceState))
throw new NotSupportedException(
$"Aetheria typed state does not expose an Eve surface document for {typeof(TDocument).FullName}.");
var document = surface switch
return surface switch
{
AetheriaClientEveSurface.Game => GameSurface,
AetheriaClientEveSurface.GameTui => GameTuiSurface,
@ -384,37 +390,12 @@ namespace GameCult.Aetheria.State.Verse
AetheriaClientEveSurface.EditorTui => EditorTuiSurface,
_ => throw new ArgumentOutOfRangeException(nameof(surface), surface, null)
};
return (CultMeshDocumentHandle<TDocument>)(object)document;
}
public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(AetheriaClientEveSurface surface)
where TDocument : class
public CultMeshReactiveDocument<global::Aetheria.State.Documents.EveSurfaceState>? ReactiveEveSurface(
string? surfaceId)
{
return Document<TDocument>(surface).Reactive();
}
public CultMeshDocumentHandle<TDocument> Document<TDocument>(AetheriaRuntimeRtsViewportBounds viewport)
where TDocument : class
{
viewport ??= new AetheriaRuntimeRtsViewportBounds();
if (typeof(TDocument) == typeof(AetheriaRuntimeRtsViewportDocument))
return (CultMeshDocumentHandle<TDocument>)(object)_mapViewport(viewport);
if (typeof(TDocument) == typeof(AetheriaRuntimeObjectsViewportDocument))
return (CultMeshDocumentHandle<TDocument>)(object)_objectsViewport(viewport);
if (typeof(TDocument) == typeof(AetheriaRuntimeGravityViewportDocument))
return (CultMeshDocumentHandle<TDocument>)(object)_gravityViewport(viewport);
if (typeof(TDocument) == typeof(AetheriaRuntimeRenderSplatsViewportDocument))
return (CultMeshDocumentHandle<TDocument>)(object)_renderSplatsViewport(viewport);
throw new NotSupportedException(
$"Aetheria typed state does not expose a viewport document for {typeof(TDocument).FullName}.");
}
public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(AetheriaRuntimeRtsViewportBounds viewport)
where TDocument : class
{
return Document<TDocument>(viewport).Reactive();
return EveSurfaceDocument(surfaceId)?.Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeRtsViewportDocument> RtsViewport(
@ -465,29 +446,6 @@ namespace GameCult.Aetheria.State.Verse
return RenderSplatsViewport(viewport).Reactive();
}
public CultMeshDocumentHandle<TDocument> Document<TDocument>(int index)
where TDocument : class
{
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index), index, "Aetheria document index must be non-negative.");
if (typeof(TDocument) == typeof(AetheriaRuntimeZoneDetailsDocument))
return (CultMeshDocumentHandle<TDocument>)(object)_zoneDetails(index);
if (typeof(TDocument) == typeof(AetheriaRuntimeSelectedObjectDocument))
return (CultMeshDocumentHandle<TDocument>)(object)_selectedObject(index);
if (typeof(TDocument) == typeof(AetheriaRuntimeInventoryDocument))
return (CultMeshDocumentHandle<TDocument>)(object)_inventory(index);
throw new NotSupportedException(
$"Aetheria typed state does not expose an indexed document for {typeof(TDocument).FullName}.");
}
public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(int index)
where TDocument : class
{
return Document<TDocument>(index).Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeZoneDetailsDocument> ZoneDetails(int zoneIndex)
{
if (zoneIndex < 0)
@ -527,24 +485,6 @@ namespace GameCult.Aetheria.State.Verse
return Inventory(entityIndex).Reactive();
}
public CultMeshDocumentHandle<TDocument> Document<TDocument>(string seatId)
where TDocument : class
{
if (typeof(TDocument) != typeof(AetheriaRuntimeStarbridgePlayerSeatDocument))
throw new NotSupportedException(
$"Aetheria typed state does not expose a keyed document for {typeof(TDocument).FullName}.");
if (string.IsNullOrWhiteSpace(seatId))
throw new ArgumentException("Seat id must be non-empty.", nameof(seatId));
return (CultMeshDocumentHandle<TDocument>)(object)_starbridgePlayerSeat(seatId);
}
public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(string seatId)
where TDocument : class
{
return Document<TDocument>(seatId).Reactive();
}
public CultMeshDocumentHandle<AetheriaRuntimeStarbridgePlayerSeatDocument> StarbridgePlayerSeat(string seatId)
{
if (string.IsNullOrWhiteSpace(seatId))
@ -562,8 +502,8 @@ namespace GameCult.Aetheria.State.Verse
public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()
{
_eveStateRefFrame ??= ReactiveDaemonFrame();
_eveStateRefHealth ??= Reactive<AetheriaRuntimeDaemonHealthDocument>();
_eveStateRefCommandBoundary ??= Reactive<AetheriaRuntimeDaemonCommandBoundaryDocument>();
_eveStateRefHealth ??= ReactiveHealth();
_eveStateRefCommandBoundary ??= ReactiveCommandBoundary();
_eveStateRefCatalog ??= ReactiveCatalogSnapshot();
return AetheriaRuntimeStateRefResolver.CreateEveSurfaceCultMeshStateRefResolver(

View file

@ -500,8 +500,8 @@ namespace GameCult.Aetheria.State.Verse
managedDaemonFrame = state.ReactiveDaemonFrame();
managedCatalog = state.ReactiveCatalogSnapshot();
managedLoadoutTemplates = state.ReactiveLoadoutTemplates();
managedStarbridgeScenario = state.Reactive<AetheriaRuntimeStarbridgeScenarioDocument>();
managedStarbridgeSession = state.Reactive<AetheriaRuntimeStarbridgeSessionDocument>();
managedStarbridgeScenario = state.ReactiveStarbridgeScenario();
managedStarbridgeSession = state.ReactiveStarbridgeSession();
_managedDaemonFrame = managedDaemonFrame;
_managedCatalog = managedCatalog;
_managedLoadoutTemplates = managedLoadoutTemplates;