feat(base): 0.R4 - a queue keeps its own count, so every package verb takes only its own state; ludic migrate state --prune
ludic.base's Queue<T> carries a QueueTag (its name and pending count): queue_new(name), q_push(q, v), q_drain(q), q_clear(q) take no BaseState, and core_undrained(tags) names the given queues still holding facts. A reducer on a package's state can now call that package's verbs (wallet_earn(wallet_st, n)). ludic migrate state --prune (ludicc --migrate-prune) takes out each state parameter a function no longer uses, nor anything it calls, and the argument that fills it - including an argument for a parameter the callee has dropped, which is taken out before the call is checked, so a generic's T is told by the argument that says it. A reducer keeps its state. --dry-run now counts the edits it would make. Every package was moved with it: 608 base_st parameters and their arguments, 1889 edits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8cf4b3fed6
commit
71735b10a2
151 changed files with 58668 additions and 54719 deletions
|
|
@ -21,10 +21,10 @@ export function thing_prompt(t: Thing) -> string {
|
|||
}
|
||||
|
||||
# the kind does what using it does; the use is a fact whatever the kind made of it
|
||||
export function thing_use(base_st: mut BaseState, things_st: mut ThingsState, t: Thing) -> void {
|
||||
export function thing_use(things_st: mut ThingsState, t: Thing) -> void {
|
||||
if t == null or not thing_kind_ok(t.kind) { return }
|
||||
let k = ThingKinds[t.kind]
|
||||
th_fact(base_st, things_st, THING_USED, t)
|
||||
th_fact(things_st, THING_USED, t)
|
||||
if k.use != null { k.use(t) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ export state ThingsState {
|
|||
th_marked: int = -1
|
||||
}
|
||||
|
||||
export function things_facts(base_st: mut BaseState, things_st: mut ThingsState) -> Queue<ThingFact> {
|
||||
if things_st.th_facts == null { things_st.th_facts = queue_new(base_st, "things.facts") }
|
||||
export function things_facts(things_st: mut ThingsState) -> Queue<ThingFact> {
|
||||
if things_st.th_facts == null { things_st.th_facts = queue_new("things.facts") }
|
||||
return things_st.th_facts
|
||||
}
|
||||
|
||||
function th_fact(base_st: mut BaseState, things_st: mut ThingsState, what: int, t: Thing) -> void {
|
||||
function th_fact(things_st: mut ThingsState, what: int, t: Thing) -> void {
|
||||
let f = new ThingFact
|
||||
f.what = what
|
||||
f.uid = t.uid
|
||||
|
|
@ -21,7 +21,7 @@ function th_fact(base_st: mut BaseState, things_st: mut ThingsState, what: int,
|
|||
f.owner = t.owner
|
||||
f.x = t.x
|
||||
f.z = t.z
|
||||
q_push(base_st, things_facts(base_st, things_st), f)
|
||||
q_push(things_facts(things_st), f)
|
||||
}
|
||||
|
||||
# whether a world has been set out (things_clear) since the program began
|
||||
|
|
@ -38,11 +38,11 @@ export function things_count(things_st: mut ThingsState) -> int { return len(thi
|
|||
# a new world: every Thing forgotten, quietly (the game has already dropped its drawings)
|
||||
export function things_clear(things_st: mut ThingsState) -> void { things_st.th_list = new []Thing }
|
||||
|
||||
export function thing_spawn(base_st: mut BaseState, things_st: mut ThingsState, kind: int, look: string, x: float, y: float, z: float, yaw: float, id: int) -> Thing {
|
||||
return th_place(base_st, things_st, new Thing, kind, look, x, y, z, yaw, id)
|
||||
export function thing_spawn(things_st: mut ThingsState, kind: int, look: string, x: float, y: float, z: float, yaw: float, id: int) -> Thing {
|
||||
return th_place(things_st, new Thing, kind, look, x, y, z, yaw, id)
|
||||
}
|
||||
|
||||
function th_place(base_st: mut BaseState, things_st: mut ThingsState, t: Thing, kind: int, look: string, x: float, y: float, z: float, yaw: float, id: int) -> Thing {
|
||||
function th_place(things_st: mut ThingsState, t: Thing, kind: int, look: string, x: float, y: float, z: float, yaw: float, id: int) -> Thing {
|
||||
t.kind = kind
|
||||
t.look = look
|
||||
t.x = x
|
||||
|
|
@ -54,36 +54,36 @@ function th_place(base_st: mut BaseState, things_st: mut ThingsState, t: Thing,
|
|||
t.uid = things_st.th_uid
|
||||
push(things_all(things_st), t)
|
||||
ThingsWorld.placed(t)
|
||||
th_fact(base_st, things_st, THING_PLACED, t)
|
||||
th_fact(things_st, THING_PLACED, t)
|
||||
return t
|
||||
}
|
||||
|
||||
# a Thing on the ground (the port's), set into it by `sink`, used from `reach`
|
||||
export function thing_put(base_st: mut BaseState, things_st: mut ThingsState, kind: int, look: string, x: float, z: float, yaw: float, sink: float, reach: float, id: int) -> Thing {
|
||||
export function thing_put(things_st: mut ThingsState, kind: int, look: string, x: float, z: float, yaw: float, sink: float, reach: float, id: int) -> Thing {
|
||||
let t = new Thing
|
||||
t.reach = reach
|
||||
return th_place(base_st, things_st, t, kind, look, x, ThingsWorld.ground(x, z) - sink, z, yaw, id)
|
||||
return th_place(things_st, t, kind, look, x, ThingsWorld.ground(x, z) - sink, z, yaw, id)
|
||||
}
|
||||
|
||||
# gone for good
|
||||
export function thing_remove(base_st: mut BaseState, things_st: mut ThingsState, t: Thing) -> void {
|
||||
export function thing_remove(things_st: mut ThingsState, t: Thing) -> void {
|
||||
if t == null { return }
|
||||
things_st.th_marked = t.uid
|
||||
things_drop(base_st, things_st, fn th_is_marked)
|
||||
things_drop(things_st, fn th_is_marked)
|
||||
things_st.th_marked = -1
|
||||
}
|
||||
|
||||
function th_is_marked(things_st: ThingsState, t: Thing) -> bool { return t.uid == things_st.th_marked }
|
||||
|
||||
# every Thing `gone` says so is removed for good
|
||||
export function things_drop(base_st: mut BaseState, things_st: mut ThingsState, gone: fn(Thing) -> bool) -> void {
|
||||
export function things_drop(things_st: mut ThingsState, gone: fn(Thing) -> bool) -> void {
|
||||
let keep = new []Thing
|
||||
let all = things_all(things_st)
|
||||
for i in 0 .. len(all) {
|
||||
let t = all[i]
|
||||
if gone(t) {
|
||||
ThingsWorld.removed(t)
|
||||
th_fact(base_st, things_st, THING_REMOVED, t)
|
||||
th_fact(things_st, THING_REMOVED, t)
|
||||
} else {
|
||||
push(keep, t)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,18 +33,18 @@ function th_to_json(t: Thing) -> Val {
|
|||
}
|
||||
|
||||
# every kept Thing removed for good: what a load or a new trip is about to put back
|
||||
export function things_reset(base_st: mut BaseState, things_st: mut ThingsState) -> void { things_drop(base_st, things_st, fn th_kept) }
|
||||
export function things_reset(things_st: mut ThingsState) -> void { things_drop(things_st, fn th_kept) }
|
||||
function th_kept(t: Thing) -> bool { return ThingsWorld.keeps(t) }
|
||||
|
||||
# a kind this build does not know is dropped
|
||||
export function things_load(base_st: mut BaseState, things_st: mut ThingsState, v: Val, version: int) -> void {
|
||||
things_reset(base_st, things_st)
|
||||
export function things_load(things_st: mut ThingsState, v: Val, version: int) -> void {
|
||||
things_reset(things_st)
|
||||
if v == null or Value.kind(v) != 6 or Value.has(v, "placed") == 0 { return }
|
||||
let l = Value.get(v, "placed")
|
||||
for i in 0 .. Value.count(l) { th_from_json(base_st, things_st, Value.at(l, i)) }
|
||||
for i in 0 .. Value.count(l) { th_from_json(things_st, Value.at(l, i)) }
|
||||
}
|
||||
|
||||
function th_from_json(base_st: mut BaseState, things_st: mut ThingsState, o: Val) -> void {
|
||||
function th_from_json(things_st: mut ThingsState, o: Val) -> void {
|
||||
let k = thing_kind_by_key(sv_str(o, "kind", ""))
|
||||
if k < 0 { return }
|
||||
let t = new Thing
|
||||
|
|
@ -59,7 +59,7 @@ function th_from_json(base_st: mut BaseState, things_st: mut ThingsState, o: Val
|
|||
let x = sv_float(o, "x", 0.0)
|
||||
let z = sv_float(o, "z", 0.0)
|
||||
let y = sv_float(o, "y", ThingsWorld.ground(x, z))
|
||||
th_place(base_st, things_st, t, k, sv_str(o, "look", ""), x, y, z, sv_float(o, "yaw", 0.0), sv_int(o, "id", 0))
|
||||
th_place(things_st, t, k, sv_str(o, "look", ""), x, y, z, sv_float(o, "yaw", 0.0), sv_int(o, "id", 0))
|
||||
ThingsWorld.restored(t)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,28 +44,28 @@ program ThingsTest {
|
|||
function on_restored(things_test_st: mut ThingsTestState, t: Thing) -> void { things_test_st.back += 1 }
|
||||
bind ThingsWorld { ground: fn hill, placed: fn on_placed, removed: fn on_removed, shown: fn on_shown, restored: fn on_restored }
|
||||
|
||||
function put(base_st: mut BaseState, things_st: mut ThingsState, kind: int, x: float, z: float) -> Thing { return thing_spawn(base_st, things_st, kind, "m", x, 0.0, z, 0.0, 0) }
|
||||
function facts(base_st: mut BaseState, things_st: mut ThingsState) -> []ThingFact { return q_drain(base_st, things_facts(base_st, things_st)) }
|
||||
function put(things_st: mut ThingsState, kind: int, x: float, z: float) -> Thing { return thing_spawn(things_st, kind, "m", x, 0.0, z, 0.0, 0) }
|
||||
function facts(things_st: mut ThingsState) -> []ThingFact { return q_drain(things_facts(things_st)) }
|
||||
|
||||
test "a spawn is drawn, numbered and said" (base_st: mut BaseState, things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
test "a spawn is drawn, numbered and said" (things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
things_clear(things_st)
|
||||
let a = put(base_st, things_st, TH_TENT, 1.0, 1.0)
|
||||
let b = put(base_st, things_st, TH_FIRE, 2.0, 2.0)
|
||||
let a = put(things_st, TH_TENT, 1.0, 1.0)
|
||||
let b = put(things_st, TH_FIRE, 2.0, 2.0)
|
||||
expect_eq(things_test_st.drawn, 2)
|
||||
expect(a.uid != b.uid)
|
||||
expect_eq(things_count(things_st), 2)
|
||||
let fs = facts(base_st, things_st)
|
||||
let fs = facts(things_st)
|
||||
expect_eq(len(fs), 2)
|
||||
expect_eq(fs[1].what, THING_PLACED)
|
||||
expect_eq(fs[1].kind, TH_FIRE)
|
||||
expect(thing_by_uid(things_st, b.uid) == b)
|
||||
}
|
||||
|
||||
test "the spatial questions see only what is active" (base_st: mut BaseState, things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
test "the spatial questions see only what is active" (things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
things_clear(things_st)
|
||||
let near = put(base_st, things_st, TH_BRANCH, 1.0, 0.0)
|
||||
let far = put(base_st, things_st, TH_BRANCH, 5.0, 0.0)
|
||||
put(base_st, things_st, TH_FIRE, 3.0, 0.0)
|
||||
let near = put(things_st, TH_BRANCH, 1.0, 0.0)
|
||||
let far = put(things_st, TH_BRANCH, 5.0, 0.0)
|
||||
put(things_st, TH_FIRE, 3.0, 0.0)
|
||||
expect(thing_nearest(things_st, TH_BRANCH, 0.0, 0.0) == near)
|
||||
expect(thing_nearest(things_st, -1, 3.2, 0.0).kind == TH_FIRE)
|
||||
expect_eq(len(things_within(things_st, 0.0, 0.0, 3.5)), 2)
|
||||
|
|
@ -79,51 +79,51 @@ program ThingsTest {
|
|||
expect_eq(things_test_st.shows, 1)
|
||||
}
|
||||
|
||||
test "remove and move tell the port" (base_st: mut BaseState, things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
test "remove and move tell the port" (things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
things_clear(things_st)
|
||||
let a = put(base_st, things_st, TH_TENT, 1.0, 1.0)
|
||||
put(base_st, things_st, TH_TENT, 2.0, 2.0)
|
||||
facts(base_st, things_st)
|
||||
thing_remove(base_st, things_st, a)
|
||||
let a = put(things_st, TH_TENT, 1.0, 1.0)
|
||||
put(things_st, TH_TENT, 2.0, 2.0)
|
||||
facts(things_st)
|
||||
thing_remove(things_st, a)
|
||||
expect_eq(things_test_st.gone, 1)
|
||||
expect_eq(things_count(things_st), 1)
|
||||
expect_eq(facts(base_st, things_st)[0].what, THING_REMOVED)
|
||||
expect_eq(facts(things_st)[0].what, THING_REMOVED)
|
||||
let b = thing_find(things_st, TH_TENT, -1)
|
||||
thing_move(b, 4.0, 0.0, 1.0)
|
||||
expect_near(b.y, 2.0, 0.001)
|
||||
let c = thing_put(base_st, things_st, TH_BRANCH, "stick", 2.0, 0.0, 0.0, 0.25, 1.9, 7)
|
||||
let c = thing_put(things_st, TH_BRANCH, "stick", 2.0, 0.0, 0.0, 0.25, 1.9, 7)
|
||||
expect_near(c.y, 0.75, 0.001)
|
||||
expect_near(thing_reach(c), 1.9, 0.001)
|
||||
expect_eq(c.id, 7)
|
||||
}
|
||||
|
||||
test "the kind answers: name, prompt, use, reach" (base_st: mut BaseState, things_st: mut ThingsState) {
|
||||
test "the kind answers: name, prompt, use, reach" (things_st: mut ThingsState) {
|
||||
things_clear(things_st)
|
||||
let t = put(base_st, things_st, TH_TENT, 0.0, 0.0)
|
||||
let t = put(things_st, TH_TENT, 0.0, 0.0)
|
||||
expect(thing_name(t) == "A tent")
|
||||
t.owner = 0
|
||||
expect(thing_name(t) == "Your tent")
|
||||
let f = put(base_st, things_st, TH_FIRE, 0.0, 0.0)
|
||||
let f = put(things_st, TH_FIRE, 0.0, 0.0)
|
||||
expect(thing_prompt(f) == "Light it")
|
||||
thing_use(base_st, things_st, f)
|
||||
thing_use(things_st, f)
|
||||
expect(thing_prompt(f) == "Add wood")
|
||||
expect(thing_prompt(t) == "")
|
||||
expect(not thing_can_use(t))
|
||||
expect_near(thing_reach(f), 2.2, 0.001)
|
||||
expect_near(thing_reach(put(base_st, things_st, TH_BRANCH, 0.0, 0.0)), 1.5, 0.001)
|
||||
expect_near(thing_reach(put(base_st, things_st, TH_SIGN, 0.0, 0.0)), 9.0, 0.001)
|
||||
let fs = facts(base_st, things_st)
|
||||
expect_near(thing_reach(put(things_st, TH_BRANCH, 0.0, 0.0)), 1.5, 0.001)
|
||||
expect_near(thing_reach(put(things_st, TH_SIGN, 0.0, 0.0)), 9.0, 0.001)
|
||||
let fs = facts(things_st)
|
||||
expect_eq(fs[len(fs) - 3].what, THING_USED)
|
||||
}
|
||||
|
||||
test "ticks and a restock" (base_st: mut BaseState, things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
test "ticks and a restock" (things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
things_clear(things_st)
|
||||
let l = put(base_st, things_st, TH_LURE, 0.0, 0.0)
|
||||
let l = put(things_st, TH_LURE, 0.0, 0.0)
|
||||
l.timer = 1.0
|
||||
let b = put(base_st, things_st, TH_BRANCH, 0.0, 0.0)
|
||||
let f = put(base_st, things_st, TH_FIRE, 0.0, 0.0)
|
||||
thing_use(base_st, things_st, b)
|
||||
thing_use(base_st, things_st, f)
|
||||
let b = put(things_st, TH_BRANCH, 0.0, 0.0)
|
||||
let f = put(things_st, TH_FIRE, 0.0, 0.0)
|
||||
thing_use(things_st, b)
|
||||
thing_use(things_st, f)
|
||||
expect_eq(things_test_st.wood, 1)
|
||||
things_tick(things_st, 0.6)
|
||||
expect(l.active)
|
||||
|
|
@ -135,19 +135,19 @@ program ThingsTest {
|
|||
expect_eq(f.used, 1)
|
||||
}
|
||||
|
||||
test "the save keeps what the port keeps, by the kind's key" (base_st: mut BaseState, things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
test "the save keeps what the port keeps, by the kind's key" (things_st: mut ThingsState, things_test_st: ThingsTestState) {
|
||||
things_clear(things_st)
|
||||
let l = put(base_st, things_st, TH_LURE, 3.0, 4.0)
|
||||
let l = put(things_st, TH_LURE, 3.0, 4.0)
|
||||
l.owner = 0
|
||||
l.timer = 2.5
|
||||
put(base_st, things_st, TH_TENT, 0.0, 0.0)
|
||||
put(things_st, TH_TENT, 0.0, 0.0)
|
||||
let root = save_tree()
|
||||
save_section(root, "things", 1, things_save(things_st))
|
||||
let text = save_encode(root)
|
||||
things_clear(things_st)
|
||||
put(base_st, things_st, TH_LURE, 9.0, 9.0)
|
||||
put(things_st, TH_LURE, 9.0, 9.0)
|
||||
let n = load_section(save_decode(text), "things")
|
||||
things_load(base_st, things_st, n.data, n.version)
|
||||
things_load(things_st, n.data, n.version)
|
||||
expect_eq(things_count(things_st), 1)
|
||||
let t = thing_find(things_st, TH_LURE, -1)
|
||||
expect_near(t.x, 3.0, 0.001)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue