P6.1: lock input for the full in-flight animation window

A swipe that began while a move animation was playing could still commit:
mouse_down latched the drag unconditionally and the animation-active check
sat at mouse_up, so a press made mid-animation committed once the timeline
finished before release — against a board mid-transition.

Gate input at gesture START instead. Add a pure `accepts_input(anim)`
predicate (false while a timeline is active) and check it at mouse_down: a
press begun mid-animation is dropped and never latches a drag, so it cannot
commit when the animation later settles. The now-dead mouse_up gate is
removed. Animation visuals and the logical model are unchanged.

Extend tests/anim_plan.sx to assert accepts_input rejects for the whole
window (idle accept / busy reject / settled accept) and that press-gating
drops the exact failure gesture a release-gate would let through.
This commit is contained in:
swipelab
2026-06-05 01:23:12 +03:00
parent 0b858f7724
commit 5ec7247001
5 changed files with 59 additions and 3 deletions

View File

@@ -184,3 +184,13 @@ BoardAnim :: struct {
AnimPhase.{ kind = .done, round = 0, t = 1.0 }
}
}
// Input gate: the board accepts a new swipe/tap gesture only when no move
// animation is in flight. The view checks this at gesture START (mouse_down),
// not at commit (mouse_up), so a gesture begun while a timeline is playing never
// latches a drag and so cannot commit when the animation later settles. Input
// resumes once `tick` clears `active` at the end of the timeline. A null anim
// (no animation layer wired) always accepts.
accepts_input :: (anim: *BoardAnim) -> bool {
anim == null or !anim.active
}