Skip to main content

AsyncExt

Trait AsyncExt 

Source
pub trait AsyncExt<Marker> {
    type System: System;

    // Required method
    fn detach(self) -> Self::System;
}
Expand description

Adds .detach() to a function/closure whose parameters are valid SystemParams and which returns a Future<Output = ()> + Send + 'static, registering it as a system.

Each tick, the wrapped function is called synchronously like any other system — its SystemParams (Res, Query, …) are fetched and borrowed exactly as usual — but instead of doing work directly, it builds and returns a future (typically an async move { .. } block that has cloned or copied out whatever owned data it needs from those borrows). The scheduler then hands that future to BackgroundTasks::spawn_async and moves on immediately — the future runs to completion on a worker thread, off the main loop, with no access to the World/Resources (which is exactly why it has to be 'static: nothing borrowed from this tick is valid once the future outlives it).

A real async fn can’t be used directly as the wrapped function here: its returned future borrows every one of its parameters by construction, so it’s never 'static on its own. Extract the owned pieces you need in the ordinary (synchronous) function body, then move only those into the async move block you return.

Fire-and-forget: nothing delivers the future’s result back automatically, and a system that unconditionally detaches a new future every tick will spawn a new one every tick. If you need the result, or want to send only once, call BackgroundTasks::spawn_async yourself inside an ordinary system (guarding with Local<bool> or OnceExt::once as needed) and poll the returned TaskHandle — same pattern already used for the async GPU backend init.

fn load_level(tasks: Res<BackgroundTasks>) -> impl Future<Output = ()> + Send + 'static {
    let tasks = tasks.clone();
    async move {
        let bytes = std::fs::read("level.bin").unwrap();
        // ... process `bytes`, maybe tasks.spawn_blocking(...) more work ...
    }
}

app.add_system(SystemStage::Update, load_level.detach());

Required Associated Types§

Required Methods§

Source

fn detach(self) -> Self::System

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<T, Fut, A, B, C, D, E, F, G, H, I, J, K, L> AsyncExt<(A, B, C, D, E, F, G, H, I, J, K, L)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>, F::Item<'a>, G::Item<'a>, H::Item<'a>, I::Item<'a>, J::Item<'a>, K::Item<'a>, L::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E, F, G, H, I, J, K, L) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static, F: SystemParam + 'static, G: SystemParam + 'static, H: SystemParam + 'static, I: SystemParam + 'static, J: SystemParam + 'static, K: SystemParam + 'static, L: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D, E, F, G, H, I, J, K> AsyncExt<(A, B, C, D, E, F, G, H, I, J, K)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>, F::Item<'a>, G::Item<'a>, H::Item<'a>, I::Item<'a>, J::Item<'a>, K::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E, F, G, H, I, J, K) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static, F: SystemParam + 'static, G: SystemParam + 'static, H: SystemParam + 'static, I: SystemParam + 'static, J: SystemParam + 'static, K: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D, E, F, G, H, I, J> AsyncExt<(A, B, C, D, E, F, G, H, I, J)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>, F::Item<'a>, G::Item<'a>, H::Item<'a>, I::Item<'a>, J::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E, F, G, H, I, J) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static, F: SystemParam + 'static, G: SystemParam + 'static, H: SystemParam + 'static, I: SystemParam + 'static, J: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D, E, F, G, H, I> AsyncExt<(A, B, C, D, E, F, G, H, I)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>, F::Item<'a>, G::Item<'a>, H::Item<'a>, I::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E, F, G, H, I) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static, F: SystemParam + 'static, G: SystemParam + 'static, H: SystemParam + 'static, I: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D, E, F, G, H> AsyncExt<(A, B, C, D, E, F, G, H)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>, F::Item<'a>, G::Item<'a>, H::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E, F, G, H) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static, F: SystemParam + 'static, G: SystemParam + 'static, H: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D, E, F, G> AsyncExt<(A, B, C, D, E, F, G)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>, F::Item<'a>, G::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E, F, G) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static, F: SystemParam + 'static, G: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D, E, F> AsyncExt<(A, B, C, D, E, F)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>, F::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E, F) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static, F: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D, E> AsyncExt<(A, B, C, D, E)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>, E::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D, E) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static, E: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C, D> AsyncExt<(A, B, C, D)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>, D::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C, D) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static, D: SystemParam + 'static,

Source§

impl<T, Fut, A, B, C> AsyncExt<(A, B, C)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>, C::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B, C) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static, C: SystemParam + 'static,

Source§

impl<T, Fut, A, B> AsyncExt<(A, B)> for T
where T: for<'a> FnMut(A::Item<'a>, B::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A, B) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static, B: SystemParam + 'static,

Source§

impl<T, Fut, A> AsyncExt<(A,)> for T
where T: for<'a> FnMut(A::Item<'a>) -> Fut + 'static, for<'a> &'a mut T: FnMut(A) -> Fut, Fut: SpawnableFuture<()>, A: SystemParam + 'static,

Source§

impl<T, Fut> AsyncExt<()> for T
where T: for<'a> FnMut() -> Fut + 'static, for<'a> &'a mut T: FnMut() -> Fut, Fut: SpawnableFuture<()>,