refactor(input): extract the gameplay frame

This commit is contained in:
Erik 2026-07-22 01:38:40 +02:00
parent 0bc9fda9de
commit c557038353
24 changed files with 2433 additions and 559 deletions

View file

@ -0,0 +1,87 @@
using AcDream.App.Combat;
using AcDream.App.Update;
using AcDream.UI.Abstractions.Input;
namespace AcDream.App.Input;
internal interface ICombatInputFrameController
{
void Tick();
void HandleMovementInput(InputAction action, ActivationType activation);
bool HandleInputAction(InputAction action, ActivationType activation);
}
internal sealed class CombatAttackInputFrameAdapter : ICombatInputFrameController
{
private readonly CombatAttackController _owner;
public CombatAttackInputFrameAdapter(CombatAttackController owner) =>
_owner = owner ?? throw new ArgumentNullException(nameof(owner));
public void Tick() => _owner.Tick();
public void HandleMovementInput(InputAction action, ActivationType activation) =>
_owner.HandleMovementInput(action, activation);
public bool HandleInputAction(InputAction action, ActivationType activation) =>
_owner.HandleInputAction(action, activation);
}
/// <summary>
/// Owns the complete pre-object input frame: held semantic dispatch, one raw
/// mouse-look sample, and combat attack intent.
/// </summary>
internal sealed class GameplayInputFrameController : IGameplayInputFramePhase
{
private readonly InputDispatcher? _dispatcher;
private readonly DispatcherMovementInputSource _movement;
private readonly IMouseLookInputFrameController? _mouseLook;
private readonly ICombatInputFrameController _combat;
public GameplayInputFrameController(
InputDispatcher? dispatcher,
DispatcherMovementInputSource movement,
IMouseLookInputFrameController? mouseLook,
ICombatInputFrameController combat)
{
_dispatcher = dispatcher;
_movement = movement ?? throw new ArgumentNullException(nameof(movement));
_mouseLook = mouseLook;
_combat = combat ?? throw new ArgumentNullException(nameof(combat));
}
public bool MouseLookActive => _mouseLook?.Active == true;
public void Tick(UpdateFrameTiming timing)
{
_ = timing;
_dispatcher?.Tick();
_mouseLook?.Tick();
_combat.Tick();
}
public bool HandlePointerAction(InputAction action, ActivationType activation) =>
_mouseLook?.HandlePointerAction(action, activation) == true;
public bool HandleCombatAction(InputAction action, ActivationType activation)
{
// ACCmdInterp::HandleNewForwardMovement @ 0x0058B1F0 aborts
// automatic combat before the movement command enters the interpreter.
_combat.HandleMovementInput(action, activation);
return _combat.HandleInputAction(action, activation);
}
public bool HandlePressedMovementAction(InputAction action) =>
_movement.HandlePressedAction(action);
public void QueueRawMouseDelta(float dx, float dy) =>
_mouseLook?.QueueRawDelta(dx, dy);
public void EndMouseLook() => _mouseLook?.EndForLifecycle();
public void ResetSession()
{
_mouseLook?.ResetSession();
_movement.ResetSession();
}
}