diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index b9354e799..106f6b852 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -7036,6 +7036,7 @@ static void RequireMenuDockingUsesManagedTypedSnapshot(string root) "public CultMeshDocumentHandle Docking { get; }", "public CultMeshReactiveDocument ReactiveDocking(", "public CultMeshReactiveDocument ReactiveStationRefit(", + "public AetheriaRuntimeCurrentDockingSession ObserveDocking(", "public AetheriaRuntimeStationRefitSession ObserveStationRefit(" }; var missingClientSymbols = requiredClientSymbols @@ -7161,26 +7162,37 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root) "public CultMeshReactiveDocument ReactiveVerseHost(", "public Task> ReactiveLoadoutTemplatesAsync(", "public CultMeshReactiveDocument ReactiveLoadoutTemplates(", + "public AetheriaRuntimeLoadoutTemplatesSession ObserveLoadoutTemplates(", "public Task> ReactiveSectorMapAsync(", "public CultMeshReactiveDocument ReactiveSectorMap(", + "public AetheriaRuntimeSectorMapSession ObserveSectorMap(", "public Task> ReactiveZoneContactsAsync(", "public CultMeshReactiveDocument ReactiveZoneContacts(", + "public AetheriaRuntimeZoneContactsSession ObserveZoneContacts(", "public Task> ReactiveStationRefitAsync(", "public CultMeshReactiveDocument ReactiveStationRefit(", + "public AetheriaRuntimeStationRefitSession ObserveStationRefit(", "public Task> ReactiveZoneRenderAsync(", "public CultMeshReactiveDocument ReactiveZoneRender(", + "public AetheriaRuntimeZoneRenderSession ObserveZoneRender(", "public Task> ReactiveZoneAsync(", "public CultMeshReactiveDocument ReactiveZone(", + "public AetheriaRuntimeCurrentZoneSession ObserveZone(", "public Task> ReactiveEntityAsync(", "public CultMeshReactiveDocument ReactiveEntity(", + "public AetheriaRuntimeCurrentEntitySession ObserveEntity(", "public Task> ReactiveDockingAsync(", "public CultMeshReactiveDocument ReactiveDocking(", + "public AetheriaRuntimeCurrentDockingSession ObserveDocking(", "public Task> ReactiveZoneAsync(", "public CultMeshReactiveDocument ReactiveZone(", + "public AetheriaRuntimeZoneDetailsSession ObserveZone(", "public Task> ReactiveSelectedObjectAsync(", "public CultMeshReactiveDocument ReactiveSelectedObject(", + "public AetheriaRuntimeSelectedObjectSession ObserveSelectedObject(", "public Task> ReactiveInventoryAsync(", - "public CultMeshReactiveDocument ReactiveInventory(" + "public CultMeshReactiveDocument ReactiveInventory(", + "public AetheriaRuntimeInventorySession ObserveInventory(" }; var missingClientSymbols = requiredClientSymbols .Where(symbol => !clientState.Contains(symbol, StringComparison.Ordinal)) @@ -7974,12 +7986,16 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root "public AetheriaRuntimeSelectedObjectDocument LatestSelectedObject(int entityIndex)", "public AetheriaRuntimeStarbridgeScenarioDocument LatestScenario()", "public CultMeshReactiveDocument ReactiveScenario(", + "public AetheriaRuntimeStarbridgeScenarioSession ObserveScenario(", "public AetheriaRuntimeStarbridgeSessionDocument LatestSession()", "public CultMeshReactiveDocument ReactiveSession(", + "public AetheriaRuntimeStarbridgeRunSession ObserveSession(", "public AetheriaRuntimeStarbridgeSessionSummaryDocument LatestSummary()", "public CultMeshReactiveDocument ReactiveSummary(", + "public AetheriaRuntimeStarbridgeSummarySession ObserveSummary(", "public AetheriaRuntimeStarbridgePlayerSeatDocument LatestPlayerSeat(string seatId)", - "public CultMeshReactiveDocument ReactivePlayerSeat(" + "public CultMeshReactiveDocument ReactivePlayerSeat(", + "public AetheriaRuntimeStarbridgePlayerSeatSession ObservePlayerSeat(" }; var missingClientSymbols = requiredClientSymbols .Where(symbol => !clientState.Contains(symbol, StringComparison.Ordinal)) @@ -8091,11 +8107,11 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root } if (!checkedSources["StarbridgePlayerSeatDocumentTests.cs"].Contains( - ".ReactivePlayerSeat(seat.SeatId)", + ".ObservePlayerSeat(seat.SeatId)", StringComparison.Ordinal)) { throw new InvalidOperationException( - "Starbridge player-seat examples must use the named managed reactive accessor instead of fetching the raw document handle."); + "Starbridge player-seat examples must use the named managed session accessor instead of fetching the raw document handle."); } Console.WriteLine("Domain document accessors: managed Aetheria state exposes named latest/reactive reads for daemon, viewport, detail, and Starbridge documents"); @@ -17123,7 +17139,7 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root) { "ProjectLoadoutTemplateAsync(", "AetheriaClientState state", - ".ReactiveDaemonFrameAsync()", + ".ObserveDaemonFrame()", "ProjectLoadoutTemplate(", "frame.Current?.Run ?? new AetheriaRuntimeRunCheckpointCommit()" }; diff --git a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs index 4337e8c39..a976f365f 100644 --- a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs +++ b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs @@ -207,16 +207,23 @@ public class DaemonRuntimeDocumentTests var observedAuthoritativeFrame = client.State.LatestDaemonFrame(); using var catalogSession = client.State.ObserveCatalog(); using var daemonFrameSession = client.State.ObserveDaemonFrame(); + using var daemonSoaViewSession = client.State.ObserveDaemonSoaView(); + using var loadoutTemplatesSession = client.State.ObserveLoadoutTemplates(); using var sectorMapSession = client.State.ObserveSectorMap(); using var playerSettingsSession = client.State.Settings.ObservePlayer(); using var verseHostSettingsSession = client.State.Settings.ObserveVerseHost(); using var zoneContactsSession = client.State.ObserveZoneContacts(); + using var zoneRenderSession = client.State.ObserveZoneRender(); using var currentZoneSession = client.State.Current.ObserveZone(); using var currentEntitySession = client.State.Current.ObserveEntity(); + using var currentDockingSession = client.State.Current.ObserveDocking(); using var stationRefitSession = client.State.ObserveStationRefit(); using var zoneDetailsSession = client.State.Details.ObserveZone(0); + using var selectedObjectSession = client.State.Details.ObserveSelectedObject(0); using var inventorySession = client.State.Details.ObserveInventory(0); + using var mapViewportSession = client.State.Viewports.ObserveMap(viewport); using var objectsViewportSession = client.State.Viewports.ObserveObjects(viewport); + using var gravityViewportSession = client.State.Viewports.ObserveGravity(viewport); using var renderSplatsViewportSession = client.State.Viewports.ObserveRenderSplats(viewport); using var playerHud = client.State.ObservePlayerHud(); var gameSurface = client.State.LatestGameSurface(); @@ -230,8 +237,6 @@ public class DaemonRuntimeDocumentTests .GetResult(); var stationRefit = client.State.LatestStationRefit(); var observedDocking = client.State.CurrentDocking(); - using var reactiveCurrentDocking = client.State.Current.ReactiveDocking(); - using var reactiveStationRefit = client.State.ReactiveStationRefit(); using var reactiveGameSurface = client.State.ReactiveGameSurface(); using var reactiveGameTuiSurface = client.State.ReactiveGameTuiSurface(); using var reactiveEditorSurface = client.State.ReactiveEditorSurface(); @@ -259,6 +264,8 @@ public class DaemonRuntimeDocumentTests Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, reactiveGameTuiSurface.Current.Surface.Id); Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId, reactiveEditorSurface.Current.Surface.Id); Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, reactiveEditorTuiSurface.Current.Surface.Id); + Assert.AreEqual(currentDocking.CurrentEntityKey, currentDockingSession.Current.CurrentEntityKey); + Assert.AreEqual(stationRefit.StationEntityKey, stationRefitSession.Current.StationEntityKey); Assert.AreSame(client.State.Settings.Player, client.State.Document()); Assert.AreSame(client.State.Settings.VerseHost, client.State.Document()); Assert.AreSame( diff --git a/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs b/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs index 37549845b..a65fffe8c 100644 --- a/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs +++ b/Assets/Scripts/Tests/StarbridgePlayerSeatDocumentTests.cs @@ -82,15 +82,14 @@ public class StarbridgePlayerSeatDocumentTests .State .Starbridge; using var reactive = handle.Reactive(); - using var aetheriaReactive = aetheriaStarbridge.ReactivePlayerSeat(seat.SeatId); + using var aetheriaSeat = aetheriaStarbridge.ObservePlayerSeat(seat.SeatId); Assert.AreEqual("seat-support", handle.Latest().SeatId); Assert.AreEqual("seat-support", client.State.Starbridge.LatestPlayerSeat(seat.SeatId).SeatId); Assert.AreEqual("item:cockpit:support", reactive.Current.CockpitItemKey); - Assert.AreEqual("item:cockpit:support", aetheriaReactive.Current.CockpitItemKey); + Assert.AreEqual("item:cockpit:support", aetheriaSeat.Current.CockpitItemKey); Assert.AreEqual("entity:pod:support", reactive.Current.EscapePodEntityKey); - Assert.AreEqual("entity:pod:support", aetheriaReactive.Current.EscapePodEntityKey); + Assert.AreEqual("entity:pod:support", aetheriaSeat.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 523099269..756266448 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs @@ -255,6 +255,12 @@ namespace GameCult.Aetheria.State.Verse return LatestSoaView.Reactive(options); } + public AetheriaRuntimeDaemonSoaViewSession ObserveDaemonSoaView( + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeDaemonSoaViewSession(ReactiveDaemonSoaView(options)); + } + public async Task LatestObservedDaemonAsync() { var frame = await LatestDaemonFrameAsync().ConfigureAwait(false); @@ -510,6 +516,12 @@ namespace GameCult.Aetheria.State.Verse return LoadoutTemplates.Reactive(options); } + public AetheriaRuntimeLoadoutTemplatesSession ObserveLoadoutTemplates( + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeLoadoutTemplatesSession(ReactiveLoadoutTemplates(options)); + } + public Task LatestSectorMapAsync() { return SectorMap.LatestAsync(); @@ -616,6 +628,12 @@ namespace GameCult.Aetheria.State.Verse return ZoneRender.Reactive(options); } + public AetheriaRuntimeZoneRenderSession ObserveZoneRender( + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeZoneRenderSession(ReactiveZoneRender(options)); + } + public Observable Watch() where TDocument : class { @@ -949,6 +967,12 @@ namespace GameCult.Aetheria.State.Verse { return Docking.Reactive(options); } + + public AetheriaRuntimeCurrentDockingSession ObserveDocking( + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeCurrentDockingSession(ReactiveDocking(options)); + } } public sealed class AetheriaClientSettingsState @@ -1070,6 +1094,13 @@ namespace GameCult.Aetheria.State.Verse return Map(viewport).Reactive(options); } + public AetheriaRuntimeMapViewportSession ObserveMap( + AetheriaRuntimeRtsViewportBounds viewport, + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeMapViewportSession(ReactiveMap(viewport, options)); + } + public CultMeshDocumentHandle Objects(AetheriaRuntimeRtsViewportBounds viewport) { return _objects(viewport ?? new AetheriaRuntimeRtsViewportBounds()); @@ -1135,6 +1166,13 @@ namespace GameCult.Aetheria.State.Verse return Gravity(viewport).Reactive(options); } + public AetheriaRuntimeGravityViewportSession ObserveGravity( + AetheriaRuntimeRtsViewportBounds viewport, + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeGravityViewportSession(ReactiveGravity(viewport, options)); + } + public CultMeshDocumentHandle RenderSplats(AetheriaRuntimeRtsViewportBounds viewport) { return _renderSplats(viewport ?? new AetheriaRuntimeRtsViewportBounds()); @@ -1253,6 +1291,13 @@ namespace GameCult.Aetheria.State.Verse return SelectedObject(entityIndex).Reactive(options); } + public AetheriaRuntimeSelectedObjectSession ObserveSelectedObject( + int entityIndex, + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeSelectedObjectSession(ReactiveSelectedObject(entityIndex, options)); + } + public CultMeshDocumentHandle Inventory(int entityIndex) { return _inventory(entityIndex); @@ -1341,6 +1386,12 @@ namespace GameCult.Aetheria.State.Verse return Scenario.Reactive(options); } + public AetheriaRuntimeStarbridgeScenarioSession ObserveScenario( + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeStarbridgeScenarioSession(ReactiveScenario(options)); + } + public Task LatestSessionAsync() { return Session.LatestAsync(); @@ -1363,6 +1414,12 @@ namespace GameCult.Aetheria.State.Verse return Session.Reactive(options); } + public AetheriaRuntimeStarbridgeRunSession ObserveSession( + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeStarbridgeRunSession(ReactiveSession(options)); + } + public Task LatestSummaryAsync() { return Summary.LatestAsync(); @@ -1385,6 +1442,12 @@ namespace GameCult.Aetheria.State.Verse return Summary.Reactive(options); } + public AetheriaRuntimeStarbridgeSummarySession ObserveSummary( + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeStarbridgeSummarySession(ReactiveSummary(options)); + } + public Task LatestPlayerSeatAsync(string seatId) { return PlayerSeat(seatId).LatestAsync(); @@ -1408,5 +1471,12 @@ namespace GameCult.Aetheria.State.Verse { return PlayerSeat(seatId).Reactive(options); } + + public AetheriaRuntimeStarbridgePlayerSeatSession ObservePlayerSeat( + string seatId, + CultMeshReactiveDocumentOptions? options = null) + { + return new AetheriaRuntimeStarbridgePlayerSeatSession(ReactivePlayerSeat(seatId, options)); + } } } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeLoadoutSnapshotProjector.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeLoadoutSnapshotProjector.cs index 2520e3e00..4c0fa4d4b 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeLoadoutSnapshotProjector.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeLoadoutSnapshotProjector.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using GameCult.Mesh; #nullable enable @@ -10,18 +9,16 @@ namespace GameCult.Aetheria.State.Verse { public static class AetheriaRuntimeLoadoutSnapshotProjector { - public static async Task ProjectLoadoutTemplateAsync( + public static Task ProjectLoadoutTemplateAsync( AetheriaClientState state, string entityKey) { if (state == null) throw new ArgumentNullException(nameof(state)); - using var frame = await state - .ReactiveDaemonFrameAsync() - .ConfigureAwait(false); - return ProjectLoadoutTemplate( + using var frame = state.ObserveDaemonFrame(); + return Task.FromResult(ProjectLoadoutTemplate( frame.Current?.Run ?? new AetheriaRuntimeRunCheckpointCommit(), - entityKey ?? ""); + entityKey ?? "")); } public static AetheriaRuntimeLoadoutTemplateCommit ProjectLoadoutTemplate( diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateSessions.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateSessions.cs index 8cc7173a6..dcb223ddc 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateSessions.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateSessions.cs @@ -95,6 +95,24 @@ namespace GameCult.Aetheria.State.Verse } } + public sealed class AetheriaRuntimeDaemonSoaViewSession : IDisposable + { + private readonly CultMeshReactiveDocument _soaView; + + public AetheriaRuntimeDaemonSoaViewSession( + CultMeshReactiveDocument soaView) + { + _soaView = soaView ?? throw new ArgumentNullException(nameof(soaView)); + } + + public AetheriaRuntimeDaemonSoaViewDocument? Current => _soaView.Current; + + public void Dispose() + { + _soaView.Dispose(); + } + } + public sealed class AetheriaRuntimeZoneContactsSession : IDisposable { private readonly CultMeshReactiveDocument _zoneContacts; @@ -131,6 +149,24 @@ namespace GameCult.Aetheria.State.Verse } } + public sealed class AetheriaRuntimeZoneRenderSession : IDisposable + { + private readonly CultMeshReactiveDocument _zoneRender; + + public AetheriaRuntimeZoneRenderSession( + CultMeshReactiveDocument zoneRender) + { + _zoneRender = zoneRender ?? throw new ArgumentNullException(nameof(zoneRender)); + } + + public AetheriaRuntimeZoneRenderDocument? Current => _zoneRender.Current; + + public void Dispose() + { + _zoneRender.Dispose(); + } + } + public sealed class AetheriaRuntimeCurrentZoneSession : IDisposable { private readonly CultMeshReactiveDocument _currentZone; @@ -167,6 +203,24 @@ namespace GameCult.Aetheria.State.Verse } } + public sealed class AetheriaRuntimeCurrentDockingSession : IDisposable + { + private readonly CultMeshReactiveDocument _currentDocking; + + public AetheriaRuntimeCurrentDockingSession( + CultMeshReactiveDocument currentDocking) + { + _currentDocking = currentDocking ?? throw new ArgumentNullException(nameof(currentDocking)); + } + + public AetheriaRuntimeCurrentDockingDocument? Current => _currentDocking.Current; + + public void Dispose() + { + _currentDocking.Dispose(); + } + } + public sealed class AetheriaRuntimeZoneDetailsSession : IDisposable { private readonly CultMeshReactiveDocument _zoneDetails; @@ -221,6 +275,24 @@ namespace GameCult.Aetheria.State.Verse } } + public sealed class AetheriaRuntimeMapViewportSession : IDisposable + { + private readonly CultMeshReactiveDocument _mapViewport; + + public AetheriaRuntimeMapViewportSession( + CultMeshReactiveDocument mapViewport) + { + _mapViewport = mapViewport ?? throw new ArgumentNullException(nameof(mapViewport)); + } + + public AetheriaRuntimeRtsViewportDocument? Current => _mapViewport.Current; + + public void Dispose() + { + _mapViewport.Dispose(); + } + } + public sealed class AetheriaRuntimeRenderSplatsViewportSession : IDisposable { private readonly CultMeshReactiveDocument _renderSplatsViewport; @@ -238,4 +310,130 @@ namespace GameCult.Aetheria.State.Verse _renderSplatsViewport.Dispose(); } } + + public sealed class AetheriaRuntimeGravityViewportSession : IDisposable + { + private readonly CultMeshReactiveDocument _gravityViewport; + + public AetheriaRuntimeGravityViewportSession( + CultMeshReactiveDocument gravityViewport) + { + _gravityViewport = gravityViewport ?? throw new ArgumentNullException(nameof(gravityViewport)); + } + + public AetheriaRuntimeGravityViewportDocument? Current => _gravityViewport.Current; + + public void Dispose() + { + _gravityViewport.Dispose(); + } + } + + public sealed class AetheriaRuntimeSelectedObjectSession : IDisposable + { + private readonly CultMeshReactiveDocument _selectedObject; + + public AetheriaRuntimeSelectedObjectSession( + CultMeshReactiveDocument selectedObject) + { + _selectedObject = selectedObject ?? throw new ArgumentNullException(nameof(selectedObject)); + } + + public AetheriaRuntimeSelectedObjectDocument? Current => _selectedObject.Current; + + public void Dispose() + { + _selectedObject.Dispose(); + } + } + + public sealed class AetheriaRuntimeLoadoutTemplatesSession : IDisposable + { + private readonly CultMeshReactiveDocument _loadoutTemplates; + + public AetheriaRuntimeLoadoutTemplatesSession( + CultMeshReactiveDocument loadoutTemplates) + { + _loadoutTemplates = loadoutTemplates ?? throw new ArgumentNullException(nameof(loadoutTemplates)); + } + + public AetheriaRuntimeLoadoutTemplatesDocument? Current => _loadoutTemplates.Current; + + public void Dispose() + { + _loadoutTemplates.Dispose(); + } + } + + public sealed class AetheriaRuntimeStarbridgeScenarioSession : IDisposable + { + private readonly CultMeshReactiveDocument _scenario; + + public AetheriaRuntimeStarbridgeScenarioSession( + CultMeshReactiveDocument scenario) + { + _scenario = scenario ?? throw new ArgumentNullException(nameof(scenario)); + } + + public AetheriaRuntimeStarbridgeScenarioDocument? Current => _scenario.Current; + + public void Dispose() + { + _scenario.Dispose(); + } + } + + public sealed class AetheriaRuntimeStarbridgeRunSession : IDisposable + { + private readonly CultMeshReactiveDocument _session; + + public AetheriaRuntimeStarbridgeRunSession( + CultMeshReactiveDocument session) + { + _session = session ?? throw new ArgumentNullException(nameof(session)); + } + + public AetheriaRuntimeStarbridgeSessionDocument? Current => _session.Current; + + public void Dispose() + { + _session.Dispose(); + } + } + + public sealed class AetheriaRuntimeStarbridgeSummarySession : IDisposable + { + private readonly CultMeshReactiveDocument _summary; + + public AetheriaRuntimeStarbridgeSummarySession( + CultMeshReactiveDocument summary) + { + _summary = summary ?? throw new ArgumentNullException(nameof(summary)); + } + + public AetheriaRuntimeStarbridgeSessionSummaryDocument? Current => _summary.Current; + + public void Dispose() + { + _summary.Dispose(); + } + } + + public sealed class AetheriaRuntimeStarbridgePlayerSeatSession : IDisposable + { + private readonly CultMeshReactiveDocument _playerSeat; + + public AetheriaRuntimeStarbridgePlayerSeatSession( + CultMeshReactiveDocument playerSeat) + { + _playerSeat = playerSeat ?? throw new ArgumentNullException(nameof(playerSeat)); + } + + public AetheriaRuntimeStarbridgePlayerSeatDocument? Current => _playerSeat.Current; + + public void Dispose() + { + _playerSeat.Dispose(); + } + } }