ludic/packages/ludic.base/queue.ludic
Orkuncakilkaya dd6a449921 feat(ludic.base): the vocabulary mechanic packages share - Tick, phases, Queue<T>, rng streams, the save tree, the system runner
A mechanic package depends on ludic.base and nothing else: ports (records of
function values for now) for questions, queues for facts, verbs for changes,
phases for order and its own versioned save section. The runner inits, resets,
saves and loads systems in the order added and ticks them phase by phase; a
missing save section is a reset. Tests for each piece and a worked route
between two toy mechanics live under tests/. The old ludic.core (engine ECS
components) is used by examples/library and stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 04:01:16 +03:00

58 lines
1.5 KiB
Text

# ludic.base/queue.ludic - a mechanic reports what HAPPENED as facts in a queue it owns, and the
# game drains it in a later phase. First in, first out; nothing here rolls dice or reorders.
export property Queue<T> {
items: []T = null
id: int = -1
}
# every named queue's pending count, so a frame's end can say which facts nobody read
var qb_names: []string = null
var qb_pending: []int = null
function qb_init() -> void {
if qb_names != null { return }
qb_names = new []string
qb_pending = new []int
}
# a queue; the name is only for core_undrained
export function q_new<T>(name: string) -> Queue<T> {
qb_init()
let q = new Queue<T>
q.items = new []T
q.id = len(qb_names)
push(qb_names, name)
push(qb_pending, 0)
return q
}
export function q_push<T>(q: Queue<T>, v: T) -> void {
push(q.items, v)
qb_pending[q.id] = len(q.items)
}
# the facts in the order they were pushed; the queue is empty afterwards
export function q_drain<T>(q: Queue<T>) -> []T {
let out = q.items
q.items = new []T
qb_pending[q.id] = 0
return out
}
export function q_len<T>(q: Queue<T>) -> int { return len(q.items) }
export function q_clear<T>(q: Queue<T>) -> void {
q.items = new []T
qb_pending[q.id] = 0
}
# the names of the queues still holding facts; call it at the end of a frame, where a fact
# left behind is a route nobody wrote
export function core_undrained() -> []string {
qb_init()
let out = new []string
for i in 0 .. len(qb_names) {
if qb_pending[i] > 0 { push(out, qb_names[i]) }
}
return out
}