diff --git a/packages/ludic.ui/backend.ludic b/packages/ludic.ui/backend.ludic index 9d59d10c..76d78f7e 100644 --- a/packages/ludic.ui/backend.ludic +++ b/packages/ludic.ui/backend.ludic @@ -45,6 +45,9 @@ export state UiState { ev_args: []Val = new []Val @max(64) ev_ring: []Val = ev_ring_new() # eval.ludic: calls' answers while an action runs, EV_RING of them, made with the state ev_ring_at: int = 0 + nt_evs: []Val = nt_evs_new() # native.ludic: fired events' objects, NT_EVS of them, made with the state + nt_ev_at: int = 0 + hd_ev: Val = hd_ev_new() # hold.ludic: the held control's event, filled in place cv_texts: []string = new []string # units_pieces.ludic: a value's var() pieces, kept tx_pieces: [][]string = new [][]string # eval_text.ludic: a text's pieces, a list a depth tx_depth: int = 0 diff --git a/packages/ludic.ui/controls.ludic b/packages/ludic.ui/controls.ludic index fcea9b18..fb145c35 100644 --- a/packages/ludic.ui/controls.ludic +++ b/packages/ludic.ui/controls.ludic @@ -25,7 +25,7 @@ function ct_activate(ui_st: mut UiState, n: UiNode) -> void { let t = ct_type(n) if t == "checkbox" { ct_change(ui_st, n, vl_bool(ui_st, not ui_attr_on(n, "checked"))) } else if t == "radio" { ct_change(ui_st, n, ui_attr(n, "value")) } else if t == "select" { ct_step(ui_st, n, 1) } else if t == "key" { ct_key_start(ui_st, n) } else if t == "number" { ct_num_commit(ui_st, n) } else if t == "text" { ct_submit(ui_st, n) } else if t == "" { ui_sound(ui_st, ct_sound(n)) - ui_fire(ui_st, n, "press", Value.null()) + ui_fire(ui_st, n, "press", ui_st.fc_none) } } function ct_step(ui_st: mut UiState, n: UiNode, d: int) -> void { diff --git a/packages/ludic.ui/focus.ludic b/packages/ludic.ui/focus.ludic index ce0aa339..939c9214 100644 --- a/packages/ludic.ui/focus.ludic +++ b/packages/ludic.ui/focus.ludic @@ -27,7 +27,7 @@ function fc_keys(ui_st: mut UiState, root: UiNode) -> void { let top = pp_top(root) if top != null { fc_collect(ui_st, top) } else { fc_collect(ui_st, root) } if ct_key_capture(ui_st, ui_st.fc_list) { return } - if top != null and ui_st.in_now.escape { ui_fire(ui_st, top, "close", Value.null()) } + if top != null and ui_st.in_now.escape { ui_fire(ui_st, top, "close", ui_st.fc_none) } let i = ui_st.in_now if fc_find(ui_st) < 0 { fc_autofocus(ui_st) } let at = fc_find(ui_st) diff --git a/packages/ludic.ui/hold.ludic b/packages/ludic.ui/hold.ludic index cf2dad52..3fbd78d2 100644 --- a/packages/ludic.ui/hold.ludic +++ b/packages/ludic.ui/hold.ludic @@ -1,6 +1,12 @@ # hold.ludic - on-hold: every frame a control is held down - by the pointer (wherever it goes until it # is let go), or by Enter or the pad's A on the focus - with event.dt, the seconds since the last # frame, and event.t, how long it has been held, on the ui clock +function hd_ev_new() -> Val { + let v = Value.object() + value_set_float(v, "dt", 0.0) # its keys made with the state, so a first hold grows nothing + value_set_float(v, "t", 0.0) + return v +} function hd_tick(ui_st: mut UiState, root: UiNode) -> void { var key = ui_st.fr_key_press if ui_st.fr_press_key != "" and ui_st.in_now.down { key = ui_st.fr_press_key } @@ -16,9 +22,9 @@ function hd_tick(ui_st: mut UiState, root: UiNode) -> void { } let n = fr_node(root, key) if n != null { - let v = Value.object() - Value.put(v, "dt", Value.float(now - ui_st.hd_last)) - Value.put(v, "t", Value.float(now - ui_st.hd_t0)) + let v = ui_st.hd_ev # one object kept with the state, filled in place each held frame + value_set_float(v, "dt", now - ui_st.hd_last) + value_set_float(v, "t", now - ui_st.hd_t0) ui_fire(ui_st, n, "hold", v) } ui_st.hd_last = now diff --git a/packages/ludic.ui/native.ludic b/packages/ludic.ui/native.ludic index 0a040561..cf36efb0 100644 --- a/packages/ludic.ui/native.ludic +++ b/packages/ludic.ui/native.ludic @@ -62,14 +62,32 @@ function nt_fired_run(ui_st: mut UiState) -> void { ui_st.nt_sp_names = names ui_st.nt_sp_vals = vals } +# an event's object, from NT_EVS kept with the state: an event is read by its handler long before +# NT_EVS more come round to its object +const NT_EVS: int = 16 +function nt_evs_new() -> []Val { + let l = new []Val + for i in 0 .. NT_EVS { + let o = Value.object() + value_set_str(o, "name", "") # its keys made now, so a first event grows nothing + Value.put(o, "value", Value.null()) + push(l, o) + } + return l +} +function nt_ev_next(ui_st: mut UiState) -> Val { + let at = ui_st.nt_ev_at % NT_EVS + ui_st.nt_ev_at = at + 1 + return ui_st.nt_evs[at] +} # the element's on-, with `event` bound to what happened function nt_run(ui_st: mut UiState, n: UiNode, name: string, value: Val) -> void { if n.on_names == null or not n.enabled { return } for i in 0 .. len(n.on_names) { if n.on_names[i] == name { - var ev = Value.object() + var ev = nt_ev_next(ui_st) if (lk_in(PE_NAMES, name) or name == "hold") and Value.kind(value) == 6 { ev = value } - Value.put(ev, "name", Value.str(name)) + value_set_str(ev, "name", name) Value.put(ev, "value", value) let e = env_new(ui_st, n.env) env_bind(e, "event", ev) diff --git a/packages/ludic.ui/pointer.ludic b/packages/ludic.ui/pointer.ludic index 1be91edd..eda02f83 100644 --- a/packages/ludic.ui/pointer.ludic +++ b/packages/ludic.ui/pointer.ludic @@ -21,7 +21,7 @@ function fr_pointer(ui_st: mut UiState, root: UiNode) -> void { if i.down and ui_st.fr_press_key != "" { ct_drag(ui_st, root, ui_st.fr_press_key, i.x, i.y) } if not i.down and ui_st.in_was_down { let was = fr_node(root, ui_st.fr_press_key) - if was != null { ui_fire(ui_st, was, "up", Value.null()) } + if was != null { ui_fire(ui_st, was, "up", ui_st.fc_none) } if hit != null and hit.key == ui_st.fr_press_key and hit.enabled { ct_activate(ui_st, hit) } ui_st.fr_press_key = "" } @@ -32,7 +32,7 @@ function fr_press(ui_st: mut UiState, hit: UiNode, x: float, y: float) -> void { if hit == null { return } ui_st.fr_press_key = hit.key if hit.focusable { ui_focus(ui_st, hit.key) } - if hit.enabled { ui_fire(ui_st, hit, "down", Value.null()) } + if hit.enabled { ui_fire(ui_st, hit, "down", ui_st.fc_none) } ct_press(ui_st, hit, x, y) } # :active - the press began on it, or inside it, and is still held (by the pointer, Enter or A) diff --git a/packages/ludic.ui/popover.ludic b/packages/ludic.ui/popover.ludic index 374ea5df..aa6ec1dc 100644 --- a/packages/ludic.ui/popover.ludic +++ b/packages/ludic.ui/popover.ludic @@ -25,7 +25,7 @@ function pp_pointer(ui_st: mut UiState, top: UiNode) -> bool { if not (i.down and not ui_st.in_was_down) { return false } if i.x >= top.x and i.y >= top.y and i.x < top.x + top.cw and i.y < top.y + top.ch { return false } ui_st.fr_press_key = "" - ui_fire(ui_st, top, "close", Value.null()) + ui_fire(ui_st, top, "close", ui_st.fc_none) return true } function pp_draw_top(ui_st: mut UiState) -> void {