ludic/packages/ludic.devlink/late.ludic
Orkuncakilkaya 18755d9057 ludic.devlink: an editor's live link into a running dev build (protocol v1, stage 1)
A package on ludic.base alone. DevlinkNet is the transport (a game binds Udp, the test a fake);
DevlinkWorld's members are the verbs, each defaulting to "not offered" (err unbound): ping, hello (with
Build.schema_hash as 16 hex digits), cam_get / cam_set / cam_release, goto, map_load, time, weather, shot,
pause / resume / step. One request a frame, parsed in place from a fixed 8 KB buffer and answered into
another; map_load, shot and step answer later by id, one at a time, 5 s at most. Loopback senders only,
opened only when enabled() (dev_tools), co-op refuses everything but ping and hello. tests/devlink_test:
each answer byte for byte, bad arguments, a stranger dropped, co-op, the late answers and their timeout,
a closed build that never opens. Compiles; not run (the Master runs the package tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 19:09:59 +03:00

57 lines
1.8 KiB
Text

# late.ludic - one slow request at a time (a map load, a shot, steps), answered by id when it is done or 5 s on
function dl_busy(st: mut DevlinkState, id: int) -> bool {
if st.dl_pend == DL_NONE { return false }
dl_err(st, id, "refused", "busy with an earlier request")
return true
}
function dl_park(st: mut DevlinkState, id: int, kind: int) -> void {
st.dl_pend = kind
st.dl_pend_id = id
st.dl_pend_ip = st.dl_ip
st.dl_pend_port = st.dl_port
st.dl_pend_t = 0.0
st.dl_o = 0 # nothing now: the answer comes when it is done
}
# the waiting request's answer into dl_out once it is done: true when there is one to send
export function devlink_late(st: mut DevlinkState, dt: float) -> bool {
if st.dl_pend == DL_NONE { return false }
st.dl_pend_t = st.dl_pend_t + dt
let id = st.dl_pend_id
var done = true
if st.dl_pend == DL_MAP { done = dl_late_map(st, id) }
else if st.dl_pend == DL_SHOT { done = dl_late_shot(st, id) }
else if DevlinkWorld.steps_left() <= 0 { dl_ok(st, id) }
else { done = false }
if not done and st.dl_pend_t >= DL_LATE_S {
dl_err(st, id, "failed", "timed out")
done = true
}
if done { st.dl_pend = DL_NONE }
return done
}
function dl_late_map(st: mut DevlinkState, id: int) -> bool {
let s = DevlinkWorld.map_state()
if s == 0 { return false }
if s > 0 { dl_ok(st, id) } else { dl_err(st, id, "failed", "the map did not load") }
return true
}
function dl_late_shot(st: mut DevlinkState, id: int) -> bool {
let s = DevlinkWorld.shot_state()
if s == 0 { return false }
if s < 0 {
dl_err(st, id, "failed", "the shot was not written")
return true
}
dl_ok(st, id)
dl_b(st, 32)
dl_q_bytes(st, st.dl_path, st.dl_path_n)
dl_b(st, 32)
dl_i(st, DevlinkWorld.shot_w())
dl_b(st, 32)
dl_i(st, DevlinkWorld.shot_h())
return true
}