# gather.ludic - a frame's marks: begin, every provider marks, end sorts and culls. While a # 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 { List.clear(compass_st.cmp_list) compass_st.cmp_used = 0 } # a provider's verb: a thing at (x, z), shown from compass `tier` up 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 { kept_push(compass_st.cmp_caught, cmp_catch(compass_st, x, z, icon, colour, tier, prio, label)) return } if CompassWorld.tier() < tier { return } 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 export function compass_end(compass_st: mut CompassState) -> void { if compass_st.cmp_list == null { compass_begin(compass_st) } let out = compass_st.cmp_back 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 { kept_push(out, compass_st.cmp_list[i]) } } } compass_st.cmp_back = compass_st.cmp_list compass_st.cmp_list = out } # the pool's next mark, filled (one made only when the pool is short) function cmp_take(compass_st: mut CompassState, x: float, z: float, icon: int, colour: int, tier: int, prio: int, label: string) -> CompassMark { if compass_st.cmp_used >= len(compass_st.cmp_pool) { @alloc_ok("past COMPASS_POOL marks in one frame only, then kept") push(compass_st.cmp_pool, new CompassMark) } compass_st.cmp_used += 1 return cmp_fill(compass_st.cmp_pool[compass_st.cmp_used - 1], x, z, icon, colour, tier, prio, label) } function cmp_band(p: int) -> int { return Math.clamp(p, COMPASS_PLAIN, COMPASS_TRACKED) } # once a frame: ask every registered provider, in the registry's order export function compass_gather(compass_st: mut CompassState) -> void { compass_begin(compass_st) if CompassWorld.tier() <= 0 { return } for i in 0 .. COMPASS_FROM_COUNT { let f = CompassProviders[i].gather if f != null { f() } } compass_end(compass_st) } export function compass_capturing(compass_st: CompassState) -> bool { return compass_st.cmp_capturing } # marks made at the start; a frame that takes more grows the pool (declared), up to its @max const COMPASS_POOL: int = 512 # made at start; @max(2048) on the pools is the most a frame may take function cmp_pool__new() -> []CompassMark { let xs = new []CompassMark for i in 0 .. COMPASS_POOL { push(xs, new CompassMark) } return xs }