An event was a tree of values encoded into a new string, a dropped line was never given back, and every batch and save joined the queue into another. Now: telemetry_props / telemetry_str / _int / _bool write the properties as JSON into a buffer the state keeps; the line is written beside it, its time worked out from the clock's seconds (TelemetryWorld.clock_s, was stamp); its bytes go into one ring (ring_bytes, at most queue_max lines), the oldest overwritten past either; a batch and the file are written into a third kept buffer and go as bytes (TelemetryTransport.send takes the bytes and their length; Http.body_bytes, Fs.write_bytes). The facts are pooled. tests/ring_test: ten thousand events past the cap in lines and in bytes, 0 bytes of heap; the line exact JSON, escaped, 2000-02-29 right; the batch puts the id in; the file round-trips. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52 lines
1.9 KiB
Text
52 lines
1.9 KiB
Text
# ports.ludic - the config, and what the ports answer when the game leaves them unbound
|
|
export function telemetry_config(telemetry_st: mut TelemetryState, c: TelemetryConfig) -> void {
|
|
telemetry_st.telemetry__cfg = c
|
|
telemetry_st.telemetry__url = c.host + c.path
|
|
}
|
|
|
|
function telemetry__conf(telemetry_st: TelemetryState) -> TelemetryConfig {
|
|
return telemetry_st.telemetry__cfg
|
|
}
|
|
|
|
function telemetry__yes() -> bool { return true }
|
|
function telemetry__wall_ms(telemetry_st: TelemetryState) -> int { return (Time.now() - telemetry_st.telemetry__t0) * 1000 }
|
|
function telemetry__wall_s() -> int { return Time.now() }
|
|
|
|
function telemetry__can_send(telemetry_st: TelemetryState) -> bool {
|
|
let c = telemetry__conf(telemetry_st)
|
|
if len(c.host) == 0 or len(c.key) == 0 { return false }
|
|
return TelemetryWorld.can_send()
|
|
}
|
|
|
|
function telemetry__enabled() -> bool { return TelemetryWorld.enabled() }
|
|
function telemetry__now() -> int { return TelemetryWorld.now_ms() }
|
|
|
|
function telemetry__http_send(url: string, body: []byte, n: int) -> int {
|
|
let h = Http.open("POST", url)
|
|
if h < 0 { return h }
|
|
Http.set(h, "Content-Type", "application/json")
|
|
Http.body_bytes(h, data_of(body), n)
|
|
Http.send(h)
|
|
return h
|
|
}
|
|
|
|
function telemetry__http_poll(h: int) -> int {
|
|
let st = Http.poll(h)
|
|
if st < 0 { return -1 }
|
|
var ok = 0
|
|
if st > 0 and Http.ok(h) { ok = 1 }
|
|
Http.free(h)
|
|
return ok
|
|
}
|
|
|
|
function telemetry__http_drop(h: int) -> void { Http.free(h) }
|
|
|
|
function telemetry__send(telemetry_st: TelemetryState, body: []byte, n: int) -> int { return TelemetryTransport.send(telemetry_st.telemetry__url, body, n) }
|
|
function telemetry__poll(h: int) -> int { return TelemetryTransport.poll(h) }
|
|
|
|
# a request abandoned (the player said no)
|
|
function telemetry__drop_request(telemetry_st: mut TelemetryState) -> void {
|
|
if telemetry_st.telemetry__h < 0 { return }
|
|
TelemetryTransport.drop(telemetry_st.telemetry__h)
|
|
telemetry_st.telemetry__h = -1
|
|
}
|