using AcDream.App.Input; using AcDream.App.Net; using AcDream.Core.Chat; using AcDream.Core.Items; using AcDream.Runtime; using AcDream.Runtime.Entities; using AcDream.Runtime.Gameplay; using AcDream.Runtime.Session; using AcDream.Runtime.World; namespace AcDream.App.Runtime; /// /// Read-only borrowed projections over the current App owners. Enumeration is /// synchronous and allocation-free; no mutable collection is copied or owned. /// internal sealed class CurrentGameRuntimeViewAdapter : IGameRuntimeView { private readonly LiveSessionController _session; private readonly LocalPlayerIdentityState _playerIdentity; private readonly IGameRuntimeClock _clock; private readonly IRuntimeEntityView _entityView; private readonly IRuntimeInventoryView _inventoryView; private readonly IRuntimeInventoryStateView _inventoryStateView; private readonly IRuntimeCharacterView _characterView; private readonly IRuntimeSocialView _socialView; private readonly IRuntimeChatView _chatView; private readonly IRuntimeActionView _actionView; private readonly IRuntimeMovementView _movementView; private readonly IRuntimeWorldEnvironmentView _environmentView; private readonly IRuntimePortalView _portalView; private bool _active = true; public CurrentGameRuntimeViewAdapter( LiveSessionController session, LocalPlayerIdentityState playerIdentity, RuntimeEntityObjectLifetime entityObjects, RuntimeInventoryState inventory, RuntimeCharacterState character, RuntimeCommunicationState communication, RuntimeActionState actions, RuntimeLocalPlayerMovementState movement, RuntimeWorldEnvironmentState environment, RuntimeWorldTransitState worldTransit, IGameRuntimeClock clock) { _session = session ?? throw new ArgumentNullException(nameof(session)); _playerIdentity = playerIdentity ?? throw new ArgumentNullException(nameof(playerIdentity)); ArgumentNullException.ThrowIfNull(entityObjects); ArgumentNullException.ThrowIfNull(communication); _clock = clock ?? throw new ArgumentNullException(nameof(clock)); _entityView = entityObjects.EntityView; _inventoryView = entityObjects.InventoryView; _inventoryStateView = ( inventory ?? throw new ArgumentNullException(nameof(inventory))).View; _characterView = ( character ?? throw new ArgumentNullException(nameof(character))).View; _chatView = communication.View; _socialView = communication.SocialView; _actionView = ( actions ?? throw new ArgumentNullException(nameof(actions))).View; _movementView = ( movement ?? throw new ArgumentNullException(nameof(movement))).View; _environmentView = environment ?? throw new ArgumentNullException(nameof(environment)); _portalView = worldTransit ?? throw new ArgumentNullException(nameof(worldTransit)); } internal bool IsActive => _active && !_session.IsDisposalComplete; public RuntimeGenerationToken Generation => _session.Generation; public RuntimeLifecycleSnapshot Lifecycle { get { RuntimeLifecycleState state; if (!IsActive) state = RuntimeLifecycleState.Disposed; else if (_session.IsInWorld) state = RuntimeLifecycleState.InWorld; else if (_session.CurrentSession is not null) state = RuntimeLifecycleState.Starting; else if (_session.SessionGeneration == 0UL) state = RuntimeLifecycleState.Constructed; else state = RuntimeLifecycleState.Stopped; return new RuntimeLifecycleSnapshot( Generation, state, _playerIdentity.ServerGuid, _session.CurrentSession is not null); } } public IGameRuntimeClock Clock => _clock; public IRuntimeEntityView Entities => _entityView; public IRuntimeInventoryView Inventory => _inventoryView; public IRuntimeInventoryStateView InventoryState => _inventoryStateView; public IRuntimeCharacterView Character => _characterView; public IRuntimeSocialView Social => _socialView; public IRuntimeChatView Chat => _chatView; public IRuntimeActionView Actions => _actionView; public IRuntimeMovementView Movement => _movementView; public IRuntimeWorldEnvironmentView Environment => _environmentView; public IRuntimePortalView Portal => _portalView; public RuntimeStateCheckpoint CaptureCheckpoint() => new( Generation, Lifecycle.State, _clock.FrameNumber, _entityView.Count, _entityView.MaterializedCount, _inventoryView.ObjectCount, _inventoryView.ContainerCount, _inventoryStateView.Snapshot, _characterView.Snapshot, _socialView.Snapshot, _chatView.Revision, _chatView.Count, _actionView.Snapshot, _movementView.Snapshot, _environmentView.Snapshot, _environmentView.Ownership, _portalView.Snapshot, _portalView.Ownership); internal void Deactivate() => _active = false; }