# rail.ludic - the rail: once a pass (a second by default) the most urgent true cards, up to a few, # muted ones left out; in a tie the registry's order decides export state HintsState { hn_mute: []bool = hn_mutes() hn_foreign: []string = new []string # muted keys with no card in this build, written back as read hn_shown: int = 3 # how many the rail holds hn_every: float = 1.0 # seconds between passes hn_top: []int = hn_slots(3) # the cards on the rail this pass hn_n: int = 0 hn_t: float = 0.0 # seconds to the next pass hn_pick: int = 0 # which chip the key would open hn_card: int = -1 # the card being read, or -1 hn_facts: Queue = hn_facts__new() } export function hints_facts(hints_st: HintsState) -> Queue { return hints_st.hn_facts } function hn_fact(hints_st: HintsState, what: int, card: int) -> void { var f = q_rec(hints_facts(hints_st)) if f == null { @alloc_ok("past the ring: more of these in a frame than its records, then kept in it") f = new HintsFact q_ring_add(hints_facts(hints_st), f) } f.what = what f.card = card q_push(hints_facts(hints_st), f) } # how many the rail holds and how often it is sorted export function hints_config(hints_st: mut HintsState, shown: int, every: float) -> void { hints_st.hn_shown = shown hints_st.hn_every = every hints_st.hn_top = hn_slots(shown) } # the next pass comes on the next tick rather than in a second export function hints_refresh(hints_st: mut HintsState) -> void { hints_st.hn_t = 0.0 } export function hints_tick(hints_st: mut HintsState, dt: float) -> void { hints_st.hn_t = hints_st.hn_t - dt if hints_st.hn_t > 0.0 { return } hints_st.hn_t = hints_st.hn_every hints_sort(hints_st) } # one pass now: the rail re-sorted, the pick kept in range, and the card following its subject # along the rail - or put down when what it was about stopped being true export function hints_sort(hints_st: mut HintsState) -> void { hints_st.hn_n = 0 let on = HintsWorld.showing() for u in 0 .. 4 { let want = HINTS_URGENT - u for id in 0 .. HINT_COUNT { if not on or hints_st.hn_n >= hints_st.hn_shown { break } if Hints[id].urgency != want or hints_muted(hints_st, id) { continue } if not HintsWorld.true_now(id) { continue } hints_st.hn_top[hints_st.hn_n] = id hints_st.hn_n += 1 } } if hints_st.hn_pick >= hints_st.hn_n { hints_st.hn_pick = 0 } if hints_st.hn_card < 0 { return } if not on or hints_muted(hints_st, hints_st.hn_card) or not HintsWorld.true_now(hints_st.hn_card) { hints_st.hn_card = -1 return } for k in 0 .. hints_st.hn_n { if hints_st.hn_top[k] == hints_st.hn_card { hints_st.hn_pick = k } } } # the cards on the rail, most urgent first (empty while the rail is not showing) export function hints_rail(hints_st: HintsState) -> []int { let out = new []int if not HintsWorld.showing() { return out } for k in 0 .. hints_st.hn_n { push(out, hints_st.hn_top[k]) } return out } export function hints_count(hints_st: HintsState) -> int { return hints_st.hn_n } export function hints_at(hints_st: HintsState, k: int) -> int { if k < 0 or k >= hints_st.hn_n { return -1 } return hints_st.hn_top[k] } export function hints_pick(hints_st: HintsState) -> int { return hints_st.hn_pick } export function hints_hot(hints_st: HintsState, k: int) -> bool { return k == hints_st.hn_pick } export function hints_reset(hints_st: mut HintsState) -> void { hn_empty(hints_st) hints_st.hn_n = 0 hints_st.hn_t = 0.0 hints_st.hn_pick = 0 hints_st.hn_card = -1 q_clear(hints_facts(hints_st)) } function hn_facts__new() -> Queue { return queue_new("hints.facts") }