From e1d25705e582b4daf12bf5447a8a41676fa3cbb3 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 28 Jun 2026 01:32:22 +0100 Subject: [PATCH] Expand Aetheria managed state facade --- .../Tests/DaemonRuntimeDocumentTests.cs | 9 ++++ .../StarbridgePlayerSeatDocumentTests.cs | 9 ++++ .../Runtime/AetheriaClientState.cs | 51 ++++++++++++++++++- .../Runtime/AetheriaRuntimeVerseClient.cs | 12 ++++- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs index c5a34f63f..34c43d977 100644 --- a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs +++ b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs @@ -167,10 +167,15 @@ public class DaemonRuntimeDocumentTests .GetResult(); var currentEntity = client.Aetheria().Current.Entity.LatestAsync().GetAwaiter().GetResult(); + var latestFrame = client.Aetheria().LatestFrame.LatestAsync().GetAwaiter().GetResult(); var currentEntityByType = client.Aetheria() .LatestAsync() .GetAwaiter() .GetResult(); + var latestFrameByType = client.Aetheria() + .LatestAsync() + .GetAwaiter() + .GetResult(); var currentEntityFromClientType = client .LatestAsync() .GetAwaiter() @@ -186,6 +191,7 @@ public class DaemonRuntimeDocumentTests Assert.AreEqual("aetheria.current.entity", client.State.Current.Entity.DocumentId); Assert.AreSame(client.State.Current.Entity, client.State.Document()); Assert.AreSame(client.State.ZoneRender, client.Document()); + Assert.AreSame(client.State.LatestFrame, client.Document()); Assert.AreSame( client.State.Current.Entity, client.State.DocumentBySchema(AetheriaRuntimeDaemonSchemas.CurrentEntity)); @@ -202,6 +208,9 @@ public class DaemonRuntimeDocumentTests out var sectorMapBySchema)); Assert.AreSame(client.State.SectorMap, sectorMapBySchema); Assert.AreEqual(AetheriaRuntimeDaemonSchemas.CurrentEntity, currentEntity.Schema); + Assert.AreEqual(AetheriaRuntimeDaemonSchemas.Frame, latestFrame.Schema); + Assert.AreEqual(frame.FrameId, latestFrame.FrameId); + Assert.AreEqual(frame.FrameId, latestFrameByType.FrameId); Assert.AreEqual("zone.0.entity.0", currentEntity.EntityKey); Assert.AreEqual(0, currentEntity.EntityIndex); Assert.AreEqual("Player", currentEntity.Entity?.DisplayName); diff --git a/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs b/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs index 7413ada65..dbf23f843 100644 --- a/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs +++ b/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs @@ -77,11 +77,20 @@ public class StarbridgePlayerSeatDocumentTests .GetResult(); var handle = client.Document( AetheriaRuntimeVerseRecordKeys.StarbridgePlayerSeat(seat.SeatId)); + var aetheriaSeat = client + .Aetheria() + .Starbridge + .PlayerSeat(seat.SeatId); using var reactive = handle.Reactive(); + using var aetheriaReactive = aetheriaSeat.Reactive(); Assert.AreEqual("seat-support", handle.Latest().SeatId); + Assert.AreEqual("seat-support", aetheriaSeat.Latest().SeatId); Assert.AreEqual("item:cockpit:support", reactive.Current.CockpitItemKey); + Assert.AreEqual("item:cockpit:support", aetheriaReactive.Current.CockpitItemKey); Assert.AreEqual("entity:pod:support", reactive.Current.EscapePodEntityKey); + Assert.AreEqual("entity:pod:support", aetheriaReactive.Current.EscapePodEntityKey); Assert.AreEqual("unity-support", reactive.Document.Context.RuntimeId); + Assert.AreEqual("unity-support", aetheriaReactive.Document.Context.RuntimeId); } } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs index f75e90c7f..6181790d4 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs @@ -13,34 +13,55 @@ namespace GameCult.Aetheria.State.Verse private readonly CultMeshDocumentCatalog _documents; internal AetheriaClientState( + CultMeshDocumentHandle latestFrame, + CultMeshDocumentHandle latestSoaView, CultMeshDocumentHandle currentZone, CultMeshDocumentHandle currentEntity, CultMeshDocumentHandle currentDocking, CultMeshDocumentHandle zoneContacts, CultMeshDocumentHandle stationRefit, CultMeshDocumentHandle sectorMap, - CultMeshDocumentHandle zoneRender) + CultMeshDocumentHandle zoneRender, + CultMeshDocumentHandle starbridgeScenario, + CultMeshDocumentHandle starbridgeSession, + Func> starbridgePlayerSeat) { + LatestFrame = latestFrame ?? throw new ArgumentNullException(nameof(latestFrame)); + LatestSoaView = latestSoaView ?? throw new ArgumentNullException(nameof(latestSoaView)); Current = new AetheriaClientCurrentState(currentZone, currentEntity, currentDocking); ZoneContacts = zoneContacts ?? throw new ArgumentNullException(nameof(zoneContacts)); StationRefit = stationRefit ?? throw new ArgumentNullException(nameof(stationRefit)); SectorMap = sectorMap ?? throw new ArgumentNullException(nameof(sectorMap)); ZoneRender = zoneRender ?? throw new ArgumentNullException(nameof(zoneRender)); DockingState = new AetheriaClientDockingState(Current.Entity, Current.Docking, StationRefit); + Starbridge = new AetheriaClientStarbridgeState( + starbridgeScenario, + starbridgeSession, + starbridgePlayerSeat); _documents = CultMesh.Documents( + LatestFrame, + LatestSoaView, Current.Zone, Current.Entity, Current.Docking, ZoneContacts, StationRefit, SectorMap, - ZoneRender); + ZoneRender, + Starbridge.Scenario, + Starbridge.Session); } + public CultMeshDocumentHandle LatestFrame { get; } + + public CultMeshDocumentHandle LatestSoaView { get; } + public AetheriaClientCurrentState Current { get; } public AetheriaClientDockingState DockingState { get; } + public AetheriaClientStarbridgeState Starbridge { get; } + public CultMeshDocumentHandle ZoneContacts { get; } public CultMeshDocumentHandle StationRefit { get; } @@ -210,4 +231,30 @@ namespace GameCult.Aetheria.State.Verse public bool IsDocked => StationRefit?.IsDocked == true && CurrentDockingBay != null; } + + public sealed class AetheriaClientStarbridgeState + { + private readonly Func> _playerSeat; + + internal AetheriaClientStarbridgeState( + CultMeshDocumentHandle scenario, + CultMeshDocumentHandle session, + Func> playerSeat) + { + Scenario = scenario ?? throw new ArgumentNullException(nameof(scenario)); + Session = session ?? throw new ArgumentNullException(nameof(session)); + _playerSeat = playerSeat ?? throw new ArgumentNullException(nameof(playerSeat)); + } + + public CultMeshDocumentHandle Scenario { get; } + + public CultMeshDocumentHandle Session { get; } + + public CultMeshDocumentHandle PlayerSeat(string seatId) + { + if (string.IsNullOrWhiteSpace(seatId)) + throw new ArgumentException("Seat id must be non-empty.", nameof(seatId)); + return _playerSeat(seatId); + } + } } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs index 173738a61..0e2de0358 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs @@ -727,6 +727,10 @@ namespace GameCult.Aetheria.State.Verse .Select(change => change.Document!); return new AetheriaClientState( + Document( + AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest), + Document( + AetheriaRuntimeVerseRecordKeys.DaemonSoaViewLatest), ProjectedDocument( "aetheria.current.zone", frame => Task.FromResult(AetheriaRuntimeRtsProjection.ProjectCurrentZone(frame)), @@ -756,7 +760,13 @@ namespace GameCult.Aetheria.State.Verse ProjectedDocument( "aetheria.zone.render", frame => Task.FromResult(AetheriaRuntimeRtsProjection.ProjectZoneRender(frame)), - AetheriaRuntimeDaemonSchemas.ZoneRender)); + AetheriaRuntimeDaemonSchemas.ZoneRender), + Document( + AetheriaRuntimeVerseRecordKeys.StarbridgeScenarioLatest), + Document( + AetheriaRuntimeVerseRecordKeys.StarbridgeSessionLatest), + seatId => Document( + AetheriaRuntimeVerseRecordKeys.StarbridgePlayerSeat(seatId))); CultMeshDocumentHandle ProjectedDocument( string documentId,