taao
A crate for running Rust futures on a Tao or winit event-loop thread.
Features
- Run a
Futureon the selected backend's event-loop thread with theEventLoopBlockOntrait. - Enable the optional
eventfeature to receive backend events as a stream and submit operations to the event-loop thread. - Select Tao or winit with Cargo features. Tao is the default backend; the two backends are mutually exclusive.
- Enable the optional
tracingfeature for wakeup, submitted-operation, event-overwrite, and error diagnostics.
Installation
Use the default Tao backend:
[]
= "0.1"
Enable the event API with Tao:
[]
= { = "0.1", = ["event"] }
Select winit and enable the event API:
[]
= { = "0.1", = false, = ["winit", "event"] }
Exactly one of tao and winit must be enabled. To collect tracing output, the application must install a tracing
subscriber.
Running a Future
use EventLoop;
use EventLoopBlockOn;
let mut event_loop = new;
let value = event_loop.block_on?;
assert_eq!;
block_on drives the event loop and returns when the future completes. When the future is woken, taao uses the
event-loop proxy to notify the event-loop thread to poll it again.
Receiving Events and Submitting Operations
With the event feature enabled, block_on_with_events provides a stream of events. Use futures_lite::StreamExt to
read them; the caller is responsible for handling received events.
use StreamExt;
use EventLoopBlockOn;
event_loop.block_on_with_events?;
The stream carries backend-specific event values; Tao and winit do not expose identical event sets. Internal user events
used to wake the future are consumed by the driver and are not included. Tao also omits loop-phase events such as
NewEvents, MainEventsCleared, RedrawEventsCleared, and LoopDestroyed.
Import taao::event::Submitter to call .submit(...) on either Event or EventSubmitter.
Both types implement this trait, so helpers can accept &impl Submitter.
Submitter::submit runs an operation on the event-loop thread and asynchronously returns its result. Tao passes an
EventLoopWindowTarget and mutable ControlFlow to the closure; winit passes an ActiveEventLoop. For example, create
a window with the Tao backend like this:
use Submitter;
let window = event
.submit
.await??;
Use let submitter = event.submitter() before moving the stream into an event-handling task. It returns an owned,
cloneable EventSubmitter with the same submit API, so other tasks or threads can submit operations while the stream
is being polled. The handle remains usable after the stream is dropped, until the current block_on_with_events run
ends. Submitting through a retained handle after that returns SubmitError.
use Submitter;
let submitter = event.submitter;
let executor = new;
let window_task = executor.spawn;
let window = executor.run.await;
The event stream has a bounded capacity of 256. When full, a new event replaces the oldest queued event.
Event::dropped_events() returns the number of events overwritten so far.
If the event loop exits before the future completes, block_on and block_on_with_events return
BlockOnError::EventLoopExited. If winit rejects the request to run its event loop, the method returns
BlockOnError::Backend. If the event loop has stopped before a submitted operation can complete, Submitter::submit
returns SubmitError.
Features
| Feature | Description | Default |
|---|---|---|
tao |
Use the Tao backend | Yes |
winit |
Use the winit backend | No |
event |
Enable the event stream and Submitter::submit |
No |
tracing |
Enable diagnostic logging | No |
License
Licensed under either MIT or Apache-2.0, at your option.