91 lines
3.2 KiB
Text
91 lines
3.2 KiB
Text
# ludic.base/system.ludic - a system is a record of what it does at each verb, and the runner
|
|
# calls them: init, reset, save and load in the order added, tick phase by phase. A null
|
|
# function is a verb the system does not have. The game's list is the order co-op's dice need.
|
|
export property System {
|
|
key: string = ""
|
|
phase: int = 2
|
|
version: int = 1
|
|
init: fn() -> void = null
|
|
reset: fn() -> void = null
|
|
tick: fn(Tick) -> void = null
|
|
save: fn() -> Val = null
|
|
load: fn(Val, int) -> void = null
|
|
}
|
|
|
|
# the declared list: a mechanic or the game writes `def Systems fishing { phase: PH_ACT, tick: fn
|
|
# fishing_tick }` from its own module; the runner starts from these, then core_add appends
|
|
export open registry Systems of System as SYS
|
|
|
|
|
|
# the declared systems; a registry is not filled when a state's defaults are made, so on first ask
|
|
@alloc_ok("once: the runner's list is made the first time it is asked, and kept")
|
|
function cs_all(base_st: mut BaseState) -> []System {
|
|
if base_st.cs_list == null {
|
|
base_st.cs_list = new []System
|
|
for i in 0 .. SYS_COUNT { push(base_st.cs_list, Systems[i]) }
|
|
}
|
|
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
|
|
s.phase = phase
|
|
return s
|
|
}
|
|
|
|
# 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) {
|
|
if all[i].key == s.key {
|
|
print(`ludic.base: two systems are keyed "{s.key}"`)
|
|
exit(1)
|
|
}
|
|
}
|
|
push(all, s)
|
|
}
|
|
|
|
export function core_clear(base_st: mut BaseState) -> void { base_st.cs_list = new []System }
|
|
export function core_count(base_st: mut BaseState) -> int { return len(cs_all(base_st)) }
|
|
|
|
export function core_init_all(base_st: mut BaseState) -> void {
|
|
let all = cs_all(base_st)
|
|
for i in 0 .. len(all) { if all[i].init != null { all[i].init() } }
|
|
}
|
|
|
|
export function core_reset_all(base_st: mut BaseState) -> void {
|
|
let all = cs_all(base_st)
|
|
for i in 0 .. len(all) { if all[i].reset != null { all[i].reset() } }
|
|
}
|
|
|
|
export function core_tick_all(base_st: mut BaseState, t: Tick) -> void {
|
|
let all = cs_all(base_st)
|
|
for ph in 0 .. PH_COUNT {
|
|
for i in 0 .. len(all) {
|
|
if all[i].phase == ph and all[i].tick != null { all[i].tick(t) }
|
|
}
|
|
drain_actions() # 0.R: the phase's actions, reduced before the next
|
|
}
|
|
}
|
|
|
|
# every system that saves, under its key with its version
|
|
export function core_save_all(base_st: mut BaseState) -> Val {
|
|
let root = save_tree()
|
|
let all = cs_all(base_st)
|
|
for i in 0 .. len(all) {
|
|
if all[i].save != null { save_section(root, all[i].key, all[i].version, all[i].save()) }
|
|
}
|
|
return root
|
|
}
|
|
|
|
# each system its own section; one with no section (or no load) is reset instead
|
|
export function core_load_all(base_st: mut BaseState, root: Val) -> void {
|
|
let all = cs_all(base_st)
|
|
for i in 0 .. len(all) {
|
|
let n = load_section(root, all[i].key)
|
|
if n.found and all[i].load != null { all[i].load(n.data, n.version) } else if all[i].reset != null { all[i].reset() }
|
|
}
|
|
}
|