scripts/.lune/lib/channel.luau
Erica Marigold ca5f2d53c8
chore(lune): restructure util libraries and include dev scripts
* Moved all util libs like `channel` into a `lib/` directory within
  `.lune`. Also includes a builder-pattern exec lib.
* Added dev scripts for fmt (stylua) and typecheck (luau-lsp).
2024-12-04 05:49:01 +00:00

48 lines
No EOL
1.1 KiB
Text

--- An MPSC synchronization primitive powered by Lua upvalues which retains only
--- one value at a time.
--- ## Usage
--- ```luau
--- local send, recv = watch((nil :: any) :: string)
--- task.delay(5, send, "hello, world!")
--- task.spawn(function()
--- local value = recv()
--- print("received value:", value)
--- end)
--- ```
type Watch<T> = {
value: T?,
receivers: { thread },
}
--- Crates a new `Watch` channel, returning its send and receive handles.
local function chan<T>(_phantom: T): ((T) -> (), () -> T?)
local watch: Watch<T> = {
value = nil,
receivers = {},
}
local function send(value: T)
watch.value = value
for _, receiver in watch.receivers do
coroutine.resume(receiver, value)
end
end
local function recv(): T
local value = watch.value
watch.value = nil
if value == nil then
table.insert(watch.receivers, coroutine.running())
return coroutine.yield()
end
return value :: T
end
return send, recv
end
return chan