diff --git a/packages/ludic.base/ecs_map.ludic b/packages/ludic.base/ecs_map.ludic index ca8e9c8c..2630fccf 100644 --- a/packages/ludic.base/ecs_map.ludic +++ b/packages/ludic.base/ecs_map.ludic @@ -75,6 +75,7 @@ export function imap_clear(m: IntMap) -> void { } # room for `n` keys before the map grows, made now +@alloc_ok("at a world's start: the keys it will need") export function imap_reserve(m: IntMap, n: int) -> void { if (m.mask + 1) * 3 >= n * 4 { return } var cap = m.mask + 1 diff --git a/packages/ludic.base/ecs_table_reserve.ludic b/packages/ludic.base/ecs_table_reserve.ludic index d3a20d4e..8c0ae0f0 100644 --- a/packages/ludic.base/ecs_table_reserve.ludic +++ b/packages/ludic.base/ecs_table_reserve.ludic @@ -1,5 +1,6 @@ # ludic.base/ecs_table_reserve.ludic - room made at the start: a table sized for its busiest moment # never grows in play, and nothing that grows is ever given back. What does grow past it is here +@alloc_ok("at a world's start: the rows it will need") export function tb_reserve(tb: Table, rows: int) -> void { let k = rows - tb.n if k <= 0 { return } diff --git a/packages/ludic.base/save.ludic b/packages/ludic.base/save.ludic index 2510ff07..4e77620e 100644 --- a/packages/ludic.base/save.ludic +++ b/packages/ludic.base/save.ludic @@ -29,6 +29,7 @@ export function save_section(root: Val, key: string, version: int, v: Val) -> vo } # the section at root[key]: found false (and an empty object) when there is none +@alloc_ok("on load: a section read from the file") export function load_section(root: Val, key: string) -> SaveNode { let n = new SaveNode n.data = Value.object() diff --git a/packages/ludic.base/save_fields.ludic b/packages/ludic.base/save_fields.ludic index 1621b231..e9ab7811 100644 --- a/packages/ludic.base/save_fields.ludic +++ b/packages/ludic.base/save_fields.ludic @@ -31,6 +31,7 @@ export function sv_str(v: Val, key: string, fallback: string) -> string { } # a list of ints; a missing key or a non-list is the empty list +@alloc_ok("on load: a saved list read back") export function sv_ints(v: Val, key: string) -> []int { let out = new []int if not sv_has(v, key) { return out } diff --git a/packages/ludic.base/system.ludic b/packages/ludic.base/system.ludic index 2796bd6d..72822b98 100644 --- a/packages/ludic.base/system.ludic +++ b/packages/ludic.base/system.ludic @@ -27,6 +27,7 @@ function cs_all(base_st: mut BaseState) -> []System { return base_st.cs_list } +@alloc_ok("at start: a system made for the runner") export function system_new(key: string, phase: int) -> System { let s = new System s.key = key @@ -35,6 +36,7 @@ export function system_new(key: string, phase: int) -> System { } # a key is a save section's name, so two systems may not share one +@alloc_ok("at start: a system added to the runner") export function core_add(base_st: mut BaseState, s: System) -> void { let all = cs_all(base_st) for i in 0 .. len(all) { diff --git a/packages/ludic.compass/gather.ludic b/packages/ludic.compass/gather.ludic index fdedfe57..d9aebbfa 100644 --- a/packages/ludic.compass/gather.ludic +++ b/packages/ludic.compass/gather.ludic @@ -2,10 +2,6 @@ # capture is open the marks go to whoever is listening instead, whatever the tier. # a frame's list and marks are the state's own, emptied and reused rather than made again export function compass_begin(compass_st: mut CompassState) -> void { - if compass_st.cmp_list == null { - compass_st.cmp_list = new []CompassMark - compass_st.cmp_back = new []CompassMark - } List.clear(compass_st.cmp_list) compass_st.cmp_used = 0 } @@ -14,11 +10,11 @@ export function compass_begin(compass_st: mut CompassState) -> void { export function compass_mark(compass_st: mut CompassState, x: float, z: float, icon: int, colour: int, tier: int, prio: int, label: string) -> void { if compass_st.cmp_list == null { compass_begin(compass_st) } if compass_st.cmp_capturing { - push(compass_st.cmp_caught, cmp_catch(compass_st, x, z, icon, colour, tier, prio, label)) + kept_push(compass_st.cmp_caught, cmp_catch(compass_st, x, z, icon, colour, tier, prio, label)) return } if CompassWorld.tier() < tier { return } - push(compass_st.cmp_list, cmp_take(compass_st, x, z, icon, colour, tier, prio, label)) + kept_push(compass_st.cmp_list, cmp_take(compass_st, x, z, icon, colour, tier, prio, label)) } # highest priority first, the providers' order kept within one; then the cap @@ -28,7 +24,7 @@ export function compass_end(compass_st: mut CompassState) -> void { List.clear(out) for p in 0 .. 3 { let want = COMPASS_TRACKED - p - for i in 0 .. len(compass_st.cmp_list) { if cmp_band(compass_st.cmp_list[i].prio) == want and len(out) < compass_st.cmp_cap { push(out, compass_st.cmp_list[i]) } } + for i in 0 .. len(compass_st.cmp_list) { if cmp_band(compass_st.cmp_list[i].prio) == want and len(out) < compass_st.cmp_cap { kept_push(out, compass_st.cmp_list[i]) } } } compass_st.cmp_back = compass_st.cmp_list compass_st.cmp_list = out diff --git a/packages/ludic.compass/marks.ludic b/packages/ludic.compass/marks.ludic index 23bc5046..3c2af042 100644 --- a/packages/ludic.compass/marks.ludic +++ b/packages/ludic.compass/marks.ludic @@ -24,8 +24,8 @@ export open registry CompassProviders of CompassProvider as COMPASS_FROM export state CompassState { cmp_cap: int = 64 - cmp_list: []CompassMark = null # this frame's, sorted and culled - cmp_back: []CompassMark = null # the list the sort fills, then swapped with cmp_list + cmp_list: []CompassMark = new []CompassMark # this frame's, sorted and culled + cmp_back: []CompassMark = new []CompassMark # the list the sort fills, then swapped with cmp_list cmp_pool: []CompassMark = cmp_pool__new() # a frame's marks, made with the state and reused: Ludic frees nothing cmp_used: int = 0 cmp_capturing: bool = false diff --git a/packages/ludic.compass/radar.ludic b/packages/ludic.compass/radar.ludic index b4a5145c..65ca2b2a 100644 --- a/packages/ludic.compass/radar.ludic +++ b/packages/ludic.compass/radar.ludic @@ -1,6 +1,7 @@ # radar.ludic - the radar's tiers: a range for each compass tier (0 is no radar), which marks it # shows, and where each falls on a unit disc with ahead at the top +@alloc_ok("at start: the radar's rings, once") export function compass_config_radar(compass_st: mut CompassState, ranges: []float, from_tier: int) -> void { compass_st.cmp_ranges = new []float for i in 0 .. len(ranges) { push(compass_st.cmp_ranges, ranges[i]) } diff --git a/packages/ludic.inventory/state.ludic b/packages/ludic.inventory/state.ludic index 05434235..bc0fdc66 100644 --- a/packages/ludic.inventory/state.ludic +++ b/packages/ludic.inventory/state.ludic @@ -23,6 +23,7 @@ export state InventoryState { } # the kinds, by the name each is saved under; the pack starts empty +@alloc_ok("once: the pack's kinds are bound at start") export function inv_config(inventory_st: mut InventoryState, keys: []string) -> void { inventory_st.iv_keys = keys if len(inventory_st.iv_pool) == 0 { for i in 0 .. IV_POOL { push(inventory_st.iv_pool, new ItemChanged) } } diff --git a/packages/ludic.inventory/verbs.ludic b/packages/ludic.inventory/verbs.ludic index 392702e9..1197be27 100644 --- a/packages/ludic.inventory/verbs.ludic +++ b/packages/ludic.inventory/verbs.ludic @@ -37,6 +37,10 @@ export function inv_set(inventory_st: mut InventoryState, it: int, n: int) -> vo # everything gone, silently: a new trip, or before a load export function inv_clear(inventory_st: mut InventoryState) -> void { - inventory_st.iv_counts = new []int - for i in 0 .. inv_kinds(inventory_st) { push(inventory_st.iv_counts, 0) } + if inventory_st.iv_counts == null { + @alloc_ok("once: the counts are made the first time the pack is cleared") + inventory_st.iv_counts = new []int + } + List.clear(inventory_st.iv_counts) + for i in 0 .. inv_kinds(inventory_st) { kept_push(inventory_st.iv_counts, 0) } } diff --git a/packages/ludic.shop/state.ludic b/packages/ludic.shop/state.ludic index 2a3aab4d..d57c0589 100644 --- a/packages/ludic.shop/state.ludic +++ b/packages/ludic.shop/state.ludic @@ -68,9 +68,11 @@ export function shop_config_curve(shop_st: mut ShopState, buy_new: float, buy_be shop_st.shop_sell_best = sell_best } +@alloc_ok("at start: the vendors are bound once") export function shop_clear_vendors(shop_st: mut ShopState) -> void { shop_st.shop_vendor_list = new []ShopVendor } # a vendor; its number is the order added +@alloc_ok("at start: the vendors are bound once") export function shop_add_vendor(shop_st: mut ShopState, stock: []int, buys: []int, refuses: int) -> int { if shop_st.shop_vendor_list == null { shop_clear_vendors(shop_st) } let v = new ShopVendor diff --git a/packages/ludic.things/spare.ludic b/packages/ludic.things/spare.ludic index aa3be26a..0383d776 100644 --- a/packages/ludic.things/spare.ludic +++ b/packages/ludic.things/spare.ludic @@ -9,7 +9,10 @@ function th_spare_put(things_st: mut ThingsState, t: Thing) -> void { kept_push( # a record for a Thing about to be placed: the oldest spare past the lag, or a new one function th_record(things_st: mut ThingsState) -> Thing { let l = things_st.th_spare - if len(l) - things_st.th_spare_at <= TH_SPARE_LAG { return new Thing } + if len(l) - things_st.th_spare_at <= TH_SPARE_LAG { + @alloc_ok("a spare miss: only until things_spare_warm's records and the removed ones come round") + return new Thing + } let t = l[things_st.th_spare_at] things_st.th_spare_at += 1 if things_st.th_spare_at >= 64 { th_spare_pack(things_st) } diff --git a/packages/ludic.things/system.ludic b/packages/ludic.things/system.ludic index 1aeb22f9..40ffe568 100644 --- a/packages/ludic.things/system.ludic +++ b/packages/ludic.things/system.ludic @@ -44,6 +44,7 @@ export function things_load(things_st: mut ThingsState, v: Val, version: int) -> for i in 0 .. Value.count(l) { th_from_json(things_st, Value.at(l, i)) } } +@alloc_ok("on load: a saved Thing read back") function th_from_json(things_st: mut ThingsState, o: Val) -> void { let k = thing_kind_by_key(sv_str(o, "kind", "")) if k < 0 { return }