fix(ui): 0.R4 - an action a UI button dispatches is reduced before the frame is presented

ludic.ui runs a frame's presses after drawing it, and what they dispatched waited for the end of the
phase - after the host had presented - so a button's change showed a frame late. Decided: drain, not a
phase per action. ui_show and ui_press drain the queue once the presses have run, so the code after
them and the frame presented next see the change; a host that runs presses some other way calls
drain_actions() before it presents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-26 07:08:26 +03:00
parent d46f0adb5e
commit 259b4d9b35
7 changed files with 46 additions and 3 deletions

View file

@ -0,0 +1,22 @@
# ui_press.ludic - 0.R4: an action a UI control dispatches is reduced before the UI hands control
# back, so the code after it - and the frame the host presents - already sees the change
import "ludic.ui"
program UiPress {
numbers float
state Score { points: int = 0 }
action Scored { n: int = 1 }
reducer Score on Scored(s: mut Score, a: Scored) { s.points += a.n }
import "ui_press_parts/Adder.ludic"
function frame(ui_st: mut UiState) -> UiNode {
let root: UiNode = ui_nodes(ui_st, "Adder", null)
ui_place(ui_st, root, 0.0, 0.0, 300.0, 200.0)
return root
}
entry (ui_st: mut UiState, score: Score) {
let root = frame(ui_st)
ui_press(ui_st, root.children[0].children[0])
let after_one = score.points
ui_press(ui_st, root.children[0].children[0])
print(`{after_one} {score.points}`)
}
}

View file

@ -0,0 +1,4 @@
# Adder.ludic - a button that says what happened and changes nothing itself
component Adder {
on add(n: int) { dispatch Scored { n: n } }
}

View file

@ -0,0 +1,3 @@
<div>
<button on-click="add(5)">+5</button>
</div>