taao 0.1.3

A crate that bridges tao and async rust, and also supports winit.
Documentation

taao

Crates.io Version docs.rs Crates.io License Badge showing this repository's Rust code analysis

A crate for running Rust futures on a Tao or winit event-loop thread.

简体中文

Features

  • Run a Future on the selected backend's event-loop thread with the EventLoopBlockOn trait.
  • Enable the optional event feature 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 tracing feature for wakeup, submitted-operation, event-overwrite, and error diagnostics.

Installation

Use the default Tao backend:

[dependencies]

taao = "0.1"

Enable the event API with Tao:

[dependencies]

taao = { version = "0.1", features = ["event"] }

Select winit and enable the event API:

[dependencies]

taao = { version = "0.1", default-features = false, features = ["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 tao::event_loop::EventLoop;
use taao::EventLoopBlockOn;

let mut event_loop = EventLoop::new();
let value = event_loop.block_on(async { 42 })?;
assert_eq!(value, 42);

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 futures_lite::StreamExt;
use taao::EventLoopBlockOn;

event_loop.block_on_with_events(async |mut event| {
    while let Some(kind) = event.next().await {
        // Handle backend 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 taao::event::Submitter;

let window = event
    .submit(|target, _control_flow| {
        tao::window::WindowBuilder::new().build(target)
    })
    .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 taao::event::Submitter;

let submitter = event.submitter();
let executor = async_executor::Executor::new();
let window_task = executor.spawn(async move {
    submitter
        .submit(|target, _| tao::window::WindowBuilder::new().build(target))
        .await
        .expect("event loop stopped before creating the window")
        .expect("failed to create window")
});
let window = executor.run(async move {
    // Poll the stream while the other task submits window creation.
    let first_event = event.next().await;
    window_task.await
}).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.