refactor(camera): extract the update frame
Move fly/chase publication, combat target tracking, and local player projection behind typed runtime owners. Preserve the inbound-created projection/reconcile barrier while removing GameWindow callbacks and duplicate shadow helpers.
This commit is contained in:
parent
eeb0f6b45c
commit
947c61d2d7
19 changed files with 988 additions and 356 deletions
122
src/AcDream.App/Input/LocalPlayerFrameRuntime.cs
Normal file
122
src/AcDream.App/Input/LocalPlayerFrameRuntime.cs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
using AcDream.App.Net;
|
||||
using AcDream.App.Physics;
|
||||
using AcDream.App.Rendering;
|
||||
using AcDream.App.World;
|
||||
using AcDream.Core.Physics;
|
||||
|
||||
namespace AcDream.App.Input;
|
||||
|
||||
/// <summary>
|
||||
/// Focused runtime seam for the local player's retail object and command
|
||||
/// phases. The frame controller owns ordering; this seam resolves the current
|
||||
/// session-scoped owners without retaining callbacks into the window host.
|
||||
/// </summary>
|
||||
internal interface ILocalPlayerPresentationRuntime
|
||||
{
|
||||
bool CanPresentPlayer { get; }
|
||||
PlayerMovementController? Controller { get; }
|
||||
}
|
||||
|
||||
internal interface ILocalPlayerFrameRuntime : ILocalPlayerPresentationRuntime
|
||||
{
|
||||
uint ResolveLocalEntityId();
|
||||
void HandleTargeting();
|
||||
bool IsHidden { get; }
|
||||
RetailObjectClockDisposition ObjectClockDisposition { get; }
|
||||
void Project(PlayerMovementController controller, MovementResult movement, bool hidden);
|
||||
void SendPreNetwork(PlayerMovementController controller, MovementResult movement, bool hidden);
|
||||
void SendPostNetwork(PlayerMovementController controller, bool hidden);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Production local-player frame runtime composed from canonical typed owners.
|
||||
/// </summary>
|
||||
internal sealed class LiveLocalPlayerFrameRuntime : ILocalPlayerFrameRuntime
|
||||
{
|
||||
private readonly CameraController _camera;
|
||||
private readonly ILocalPlayerModeSource _mode;
|
||||
private readonly ILocalPlayerControllerSource _controller;
|
||||
private readonly IChaseCameraSource _chase;
|
||||
private readonly DispatcherMovementInputSource _input;
|
||||
private readonly IInputCaptureSource _capture;
|
||||
private readonly LiveEntityRuntime _liveEntities;
|
||||
private readonly ILocalPlayerIdentitySource _identity;
|
||||
private readonly ILocalPlayerPhysicsHostSource _physicsHost;
|
||||
private readonly LocalPlayerProjectionController _projection;
|
||||
private readonly LocalPlayerOutboundController _outbound;
|
||||
private readonly ILiveWorldSessionSource _session;
|
||||
|
||||
public LiveLocalPlayerFrameRuntime(
|
||||
CameraController camera,
|
||||
ILocalPlayerModeSource mode,
|
||||
ILocalPlayerControllerSource controller,
|
||||
IChaseCameraSource chase,
|
||||
DispatcherMovementInputSource input,
|
||||
IInputCaptureSource capture,
|
||||
LiveEntityRuntime liveEntities,
|
||||
ILocalPlayerIdentitySource identity,
|
||||
ILocalPlayerPhysicsHostSource physicsHost,
|
||||
LocalPlayerProjectionController projection,
|
||||
LocalPlayerOutboundController outbound,
|
||||
ILiveWorldSessionSource session)
|
||||
{
|
||||
_camera = camera ?? throw new ArgumentNullException(nameof(camera));
|
||||
_mode = mode ?? throw new ArgumentNullException(nameof(mode));
|
||||
_controller = controller ?? throw new ArgumentNullException(nameof(controller));
|
||||
_chase = chase ?? throw new ArgumentNullException(nameof(chase));
|
||||
_input = input ?? throw new ArgumentNullException(nameof(input));
|
||||
_capture = capture ?? throw new ArgumentNullException(nameof(capture));
|
||||
_liveEntities = liveEntities ?? throw new ArgumentNullException(nameof(liveEntities));
|
||||
_identity = identity ?? throw new ArgumentNullException(nameof(identity));
|
||||
_physicsHost = physicsHost ?? throw new ArgumentNullException(nameof(physicsHost));
|
||||
_projection = projection ?? throw new ArgumentNullException(nameof(projection));
|
||||
_outbound = outbound ?? throw new ArgumentNullException(nameof(outbound));
|
||||
_session = session ?? throw new ArgumentNullException(nameof(session));
|
||||
}
|
||||
|
||||
public bool CanPresentPlayer =>
|
||||
!_camera.IsFlyMode
|
||||
&& _mode.IsPlayerMode
|
||||
&& _controller.Controller is not null
|
||||
&& _chase.Legacy is not null
|
||||
&& _input.IsAvailable
|
||||
&& !_capture.DevToolsWantCaptureKeyboard;
|
||||
|
||||
public PlayerMovementController? Controller => _controller.Controller;
|
||||
|
||||
public uint ResolveLocalEntityId() =>
|
||||
_liveEntities.TryGetWorldEntity(_identity.ServerGuid, out var entity)
|
||||
? entity.Id
|
||||
: 0u;
|
||||
|
||||
public void HandleTargeting() => _physicsHost.Host?.HandleTargetting();
|
||||
|
||||
public bool IsHidden => _liveEntities.IsHidden(_identity.ServerGuid);
|
||||
|
||||
public RetailObjectClockDisposition ObjectClockDisposition =>
|
||||
_liveEntities.GetRootObjectClockDisposition(_identity.ServerGuid);
|
||||
|
||||
public void Project(
|
||||
PlayerMovementController controller,
|
||||
MovementResult movement,
|
||||
bool hidden) =>
|
||||
_projection.Project(controller, movement, hidden);
|
||||
|
||||
public void SendPreNetwork(
|
||||
PlayerMovementController controller,
|
||||
MovementResult movement,
|
||||
bool hidden) =>
|
||||
_outbound.SendPreNetworkActions(
|
||||
_session.CurrentSession,
|
||||
controller,
|
||||
movement,
|
||||
hidden);
|
||||
|
||||
public void SendPostNetwork(
|
||||
PlayerMovementController controller,
|
||||
bool hidden) =>
|
||||
_outbound.SendPostNetworkPosition(
|
||||
_session.CurrentSession,
|
||||
controller,
|
||||
hidden);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue