fix(input): #87 key_pressed/key_released edges never fired under the frame loop
Since #83 the loop commits the device layer once per frame (input_drive), but a game that ALSO called Input.poll by hand committed a second time in the same frame; input_device_commit copies in_held into in_prev at the top of every commit, so the second commit left in_prev == in_held and the edges (held && !prev) could never see a transition. Fix: an in_have_frame_driver flag. The loop's input_drive sets it; a manual Input.poll under the loop then becomes a no-op returning the frame's key instead of re-committing. An entry-driven harness has no loop, so the flag stays false and each Input.poll commits a frame as before (the #7/#50 record/replay + device tests are unchanged). Frame loop now calls input_drive. Example input_edge (press edge on the down frame, release edge on the up frame). Full suite 110/0, goldens byte-identical, fixpoint holds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
bdf1a97550
commit
0497029dae
6 changed files with 64 additions and 12 deletions
27
examples/library/input_edge.ludic
Normal file
27
examples/library/input_edge.ludic
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# input_edge.ludic — Input.key_pressed / key_released edge detection (#87). A
|
||||
# handler game reads the press and release edges of a key in its Update phase; the
|
||||
# frame loop commits the device layer itself (#83), so the game does NOT call
|
||||
# Input.poll by hand, and the edges fire on exactly the transition frame. (The bug:
|
||||
# a manual Input.poll under the loop used to double-commit and copy in_held into
|
||||
# in_prev twice, so key_pressed/key_released never fired.)
|
||||
#
|
||||
# Driven headless by the keys on stdin, one char per frame. With "xkkxq":
|
||||
# x frame0 — nothing
|
||||
# k frame1 — pressed edge (down + just went down)
|
||||
# k frame2 — held (down, no edge)
|
||||
# x frame3 — released edge (was k, now not)
|
||||
# q frame4 — nothing, then quit
|
||||
#
|
||||
# Run: printf 'xkkxq' | bin/ludic examples/library/input_edge.ludic -> 0 11 1 100 0
|
||||
program InputEdge {
|
||||
property Tag { n: int = 0 }
|
||||
model P { Tag }
|
||||
|
||||
handler In phase Update {
|
||||
var v = 0
|
||||
if Input.key_down('k') { v = v + 1 } # held
|
||||
if Input.key_pressed('k') { v = v + 10 } # went down this frame
|
||||
if Input.key_released('k') { v = v + 100 } # went up this frame
|
||||
print(v)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue