# build_class.ludic - a Ludic component's instance built: the parent's attributes are its props (id, # class and style go on its root element instead, styled by the parent's sheet as well as its own), # its model is its props, state and fields, and its template reads nothing else function bd_class(ui_st: mut UiState, k: UiTpl, e: UiEnv, key: string, out: []UiNode) -> void { let cls = k.cls uc_load(ui_st, cls) let it = in_get(ui_st, key, cls) let ce = env_new(ui_st, null) if it.fresh { ce.model = bd_first_fill(ui_st, it, k, e) } else { ce.model = bd_fill(ui_st, it, k, e) } ce.inst = it ce.ctx = e.ctx ce.slot = k ce.slot_env = e ce.on_names = k.on_keys ce.on_acts = k.on_acts for i in 0 .. len(k.on_keys) { ui_kept(ce.on_envs, e) } lc_note(ui_st, key, k.on_keys, k.on_acts, e) let at = len(out) if cls.roots == null or len(cls.roots) != 1 or cls.roots[0] != cls.root { @alloc_ok("once per class, again after a reload") cls.roots = new []UiTpl # its template as a list of one, made once (again after a reload) ui_kept(cls.roots, cls.root) } let root = cls.roots bd_kids(ui_st, root, ce, key, out) if len(out) > at { bd_pass_down(ui_st, out[at], k, e) } } # an instance's props and model, filled in place into the objects it keeps (a reused one's are kept) function bd_fill(ui_st: mut UiState, it: UiInst, k: UiTpl, e: UiEnv) -> Val { if it.props == null { it.props = Value.object() } let props = it.props Value.clear(props) for i in 0 .. len(k.keys) { let a = k.keys[i] if a != "class" and a != "style" and a != "id" { Value.put(props, a, ui_eval(ui_st, k.vals[i], e)) } } it.cls.props(it.ptr, props) if it.model == null { it.model = Value.object() } return it.cls.model(it.ptr, it.model) } # a new instance's first fill makes its props and model objects and every Value in them - once per # instance, which in_reuse bounds (a prompt's key hint first shown mid-walk was judged as a frame's keep) @alloc_ok("a new component instance's first build: its props and model, then kept or reused") function bd_first_fill(ui_st: mut UiState, it: UiInst, k: UiTpl, e: UiEnv) -> Val { it.fresh = false return bd_fill(ui_st, it, k, e) } # puts those on the card's own root element; when that # root is itself a component, each user in turn adds theirs (the outermost's id wins) function bd_pass_down(ui_st: mut UiState, n: UiNode, k: UiTpl, e: UiEnv) -> void { let c = tpl_attr(k, "class") if c != null { let parts = mm_split(ui_st, ui_eval_text(ui_st, c, e), 32) for i in 0 .. len(parts) { if len(parts[i]) > 0 { ui_kept(n.classes, parts[i]) } } } let id = tpl_attr(k, "id") if id != null { n.id = ui_eval_text(ui_st, id, e) } let up = up_take(ui_st) up.sheet = k.sheet up.style = k.style up.env = e @alloc_ok("once per pooled node: its list is kept and cleared") if n.ups == null { n.ups = new []UiPass } ui_kept(n.ups, up) }