Event & Task Utilities
Event & Task Utilities
Async building blocks: a cooperatively cancellable spawned task and a one-shot await/signal latch.
Original, compile-verified Verse by Bizanator (Biloxi Studios). Clean-room sample you can drop into a UEFN project and adapt.
# Event & Task Utilities — Biloxi Studios Inc.
#
# Lightweight building blocks for async coordination: a cooperatively cancellable
# task you can stop from the outside, and a tiny one-shot latch you can await and
# signal across concurrent code. Dependency-free.
#
# Teaches: spawn/await, the <suspends> effect, classes implementing awaitable(t),
# cooperative cancellation (tasks can't be force-killed — they check a flag), and
# Verse's `event` type for cross-task signalling.
#
# Example — cancellable task:
# Task := SpawnCancellable(MyWork) # MyWork(State)<suspends>:void
# Task.Cancel() # ask it to stop at its next check
#
# Example — one-shot latch:
# Latch := one_shot{}
# spawn{ Latch.Await(); DoSomethingOnce() }
# Latch.Signal() # releases the awaiter exactly once
using { /Verse.org/Simulation }
using { /Verse.org/Concurrency }
event_utils<public> := module:
# Shared cancellation flag handed to a task. Members are public so the class
# can be constructed from anywhere that uses the module.
cancel_state<public> := class<final>:
var Cancelled<public>:logic = false
# Has cancellation been requested?
IsCancelled<public>()<transacts>:logic =
Cancelled
# Request cancellation. The task observes this at its next check.
Request<public>()<transacts>:void =
set Cancelled = true
# A handle to a running cancellable task. Await it like any awaitable, or ask
# it to stop with Cancel().
cancellable<public>(t:type) := class<final>(awaitable(t)):
State<public>:cancel_state
Handle<public>:task(t)
Await<override>()<suspends>:t =
Handle.Await()
Cancel<public>()<transacts>:void =
State.Request()
# Spawn Work as a cancellable task. Work receives the cancel_state so it can
# poll IsCancelled() in its loop and exit cleanly when asked to stop.
SpawnCancellable<public>(Work(State:cancel_state)<suspends>:t where t:type):cancellable(t) =
SharedState := cancel_state{}
cancellable(t):
State := SharedState
Handle := spawn{ Work(SharedState) }
# A one-shot latch: Await() blocks until Signal() is called once. Built on the
# recurring `event()` (= event(tuple())); a single Signal releases waiters.
one_shot<public> := class<final>:
Gate<public>:event() = event(){}
Await<public>()<suspends>:void =
Gate.Await()
# Signal resumes suspended awaiters; it carries the `no_rollback` effect,
# so it is NOT <transacts>. The unit-payload event signals with no value.
Signal<public>():void =
Gate.Signal()