ludic.ui: an unmounted component is mounted again rather than made again - its record renewed (a generated renew), its props and model kept; an action's call answers into a ring

A prompt that comes and goes as a player walks (co-op's netleak: in_get, cmp_*_new, bd_class, value_slot/put)
made a new record, props and model on every mount, and an action's call answered into a new Val (ev_call_with).
examples/library/ui_remount: two thousand comings and goings hold the heap at 0, and the counter starts at 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-28 15:25:55 +03:00
parent fc0f3d3790
commit 6cdef20cc2
14 changed files with 46052 additions and 45244 deletions

View file

@ -51,7 +51,7 @@ function ev_call_with(ui_st: mut UiState, x: UiExpr, e: UiEnv, args: Val) -> Val
var at = e
while at != null {
if at.inst != null {
let r = at.inst.cls.call(at.inst.ptr, x.s, args, uv_hold(ui_st))
let r = at.inst.cls.call(at.inst.ptr, x.s, args, ev_into(ui_st))
if Value.kind(r) != 99 { return r }
}
at = at.parent
@ -62,5 +62,17 @@ function ev_call_with(ui_st: mut UiState, x: UiExpr, e: UiEnv, args: Val) -> Val
}
return ui_st.ui_view.call(x.s, args)
}
# where a call writes its answer: this build's pool, or while an action runs (the pool is off) the next
# of EV_RING kept slots - an answer is read long before 64 more calls come round to it
function ev_into(ui_st: mut UiState) -> Val {
let v = uv_hold(ui_st)
if v != null { return v }
let ring = ui_st.ev_ring
if len(ring) < EV_RING { push(ring, Value.null()) }
let at = ui_st.ev_ring_at % len(ring)
ui_st.ev_ring_at = at + 1
return ring[at]
}
const EV_RING: int = 64
function ui_eval_text(ui_st: mut UiState, x: UiExpr, e: UiEnv) -> string { return vl_text(ui_eval(ui_st, x, e)) }
function ui_eval_bool(ui_st: mut UiState, x: UiExpr, e: UiEnv) -> bool { return vl_truthy(ui_eval(ui_st, x, e)) }