ludic.things: a removed Thing's record placed again, oldest first past a lag of 32; things_reserve sizes the grid once
thing_put and thing_spawn made a new record for every Thing placed, and the world places and removes them all day (an animal's sign and bed, a drop, a fish), so play grew by a record per placement. Removed records wait in a queue compacted in place; once 32 wait, the oldest is set back as new with a new uid. ludic.base's grid_reserve makes the buckets for n rows now, since a rehash in play leaves the old bucket array behind. Tests: a record comes back only past the lag, as new, with a new uid, the indexes agree, and the spare queue stays bounded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5d71892b7c
commit
1af62d0879
7 changed files with 101 additions and 2 deletions
57
packages/ludic.things/spare.ludic
Normal file
57
packages/ludic.things/spare.ludic
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# spare.ludic - a removed Thing's record is made again rather than a new one: Ludic frees nothing,
|
||||
# and the world places and takes away Things all day (a sign an animal leaves, a bed, a drop).
|
||||
# Oldest first, and only once TH_SPARE_LAG are waiting, so anything still holding one sees its
|
||||
# uid change long after the removal; everything else about it is set back as new
|
||||
const TH_SPARE_LAG: int = 32
|
||||
|
||||
function th_spare_put(things_st: mut ThingsState, t: Thing) -> void { push(things_st.th_spare, t) }
|
||||
|
||||
# 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 }
|
||||
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) }
|
||||
return th_clean(t)
|
||||
}
|
||||
|
||||
# the waiting ones moved to the front, in place
|
||||
function th_spare_pack(things_st: mut ThingsState) -> void {
|
||||
let l = things_st.th_spare
|
||||
let at = things_st.th_spare_at
|
||||
let n = len(l) - at
|
||||
for i in 0 .. n { l[i] = l[i + at] }
|
||||
for i in 0 .. at { List.pop(l) }
|
||||
things_st.th_spare_at = 0
|
||||
}
|
||||
|
||||
function th_clean(t: Thing) -> Thing {
|
||||
t.uid = 0
|
||||
t.kind = 0
|
||||
t.id = 0
|
||||
t.look = ""
|
||||
t.x = 0.0
|
||||
t.y = 0.0
|
||||
t.z = 0.0
|
||||
t.yaw = 0.0
|
||||
t.owner = -1
|
||||
t.active = true
|
||||
t.reach = 0.0
|
||||
t.timer = 0.0
|
||||
t.used = 0
|
||||
t.n = 0
|
||||
t.sx = 0.0
|
||||
t.sz = 0.0
|
||||
t.syaw = 0.0
|
||||
t.shared = false
|
||||
t.ent = -1
|
||||
t.tab = null
|
||||
return t
|
||||
}
|
||||
|
||||
# room for `n` Things in the grid before it has to grow: a world that will place more in play
|
||||
# than it placed at the start sizes it once, at the start
|
||||
export function things_reserve(things_st: mut ThingsState, n: int) -> void { grid_reserve(things_st.th.grid, n) }
|
||||
|
||||
export function things_spare_count(things_st: ThingsState) -> int { return len(things_st.th_spare) - things_st.th_spare_at }
|
||||
Loading…
Add table
Add a link
Reference in a new issue