yield
Coroutine wrappers that flatten callback APIs into sequential code
Work in Progress
This module is under active development and has not been battle-tested in production. The API may change between releases.
@gwigz/slua-modules/yield uses Lua coroutines to flatten SLua's callback-based
APIs into sequential code. Call spawn() to start a coroutine, then use
the wrapper functions inside it, they yield the coroutine until the result is
ready, then return [ok, value] where ok is false if the request timed out.
import { spawn, requestAgentData, sleep } from "@gwigz/slua-modules/yield"
spawn(() => {
const [ok, name] = requestAgentData(ll.GetOwner(), DATA_NAME, 10)
if (ok) {
ll.Say(0, `Hello, ${name}!`)
// note that this will not pause your script
// it will only pause this spawned coroutine
sleep(2)
ll.Say(0, "Done waiting.")
}
})Compile-time flags
Each wrapper category is gated by a compile-time flag set via the define
option on @gwigz/slua-tstl-plugin in your tsconfig. When a flag is false
(or omitted), the wrapper code is stripped from the Lua output via dead code
elimination.
{
"tstl": {
"luaPlugins": [
{
"name": "@gwigz/slua-tstl-plugin",
"define": {
"YIELD_DATASERVER_AGENT": true,
"YIELD_HTTP": true,
// omitted flags default to false, code is stripped
},
},
],
},
}API
Prop
Type
Examples
waitFor
spawn(() => {
const [channel, name, id, message] = waitFor("listen", (ch) => ch === -123)
ll.Say(0, `${name} said: ${message}`)
})dialog
spawn(() => {
const [ok, choice] = dialog(-99001, ll.GetOwner(), "Pick one:", ["Yes", "No"], 60)
if (ok) {
ll.Say(0, `You chose: ${choice}`)
}
})fetch
spawn(() => {
const [ok, res] = fetch("https://example.com/api", {
method: "GET",
timeout: 30,
})
if (ok) {
if (res.status === 200) {
ll.Say(0, res.body)
}
}
})sensor
spawn(() => {
const [ok, detected] = sensor("", NULL_KEY, AGENT, 20.0, PI, 10)
if (ok) {
if (detected) {
for (const d of detected) {
ll.Say(0, `Found: ${d.name}`)
}
} else {
ll.Say(0, "Nobody nearby.")
}
}
})