bevy_async_system

Crates.iobevy_async_system
lib.rsbevy_async_system
version0.1.1
sourcesrc
created_at2023-10-15 08:45:05.503819
updated_at2023-10-16 05:28:10.637934
descriptionProvides the ability to wait for game status asynchronously.
homepage
repositoryhttps://github.com/elmtw/bevy_async_system
max_upload_size
id1003583
size381,937
z4kuro (not-elm)

documentation

README

bevy_async_system

Crates.io MIT/Apache 2.0 Crates.io

This crate provides UniTask-like functionality to asynchronously await game state.

Usage

All examples are here.

once

The once is used to run the system only once.

In addition to simple system execution, it is also used to change state and send events.

use bevy::prelude::*;
use bevy_async_system::prelude::*;

#[derive(Eq, PartialEq, Copy, Clone, Debug, Default, States, Hash)]
enum ExampleState {
    #[default]
    First,
    Second,
}

#[derive(Resource, Eq, PartialEq, Default, Clone, Debug)]
struct Count(usize);

#[derive(Eq, PartialEq, Default, Clone, Debug)]
struct NonSendCount(usize);

fn setup(mut commands: Commands) {
    commands.spawn_async(|schedules| async move {
        schedules.add_system(Update, once::run(println_system)).await;
        schedules.add_system(Update, once::set_state(ExampleState::Second)).await;
        schedules.add_system(Update, once::init_resource::<Count>()).await;
        schedules.add_system(Update, once::init_non_send_resource::<NonSendCount>()).await;

        let count = schedules.add_system(Update, once::run(return_count)).await;
        schedules.add_system(Update, once::insert_resource(count)).await;
        schedules.add_system(Update, once::run(println_counts)).await;

        schedules.add_system(Update, once::send(AppExit)).await;
    });
}

fn println_system() {
    println!("hello!");
}


fn return_count() -> Count {
    Count(30)
}

fn println_counts(
    count: Res<Count>,
    non_send_count: NonSend<NonSendCount>
) {
    println!("{count:?}");
    println!("{non_send_count:?}");
}

wait

wait keeps the system running until a certain condition is met.

For example, you can easily write a process that waits until music playback ends, as shown below.

use bevy::prelude::*;
use bevy_async_system::prelude::*;

fn setup_async_systems(mut commands: Commands) {
    commands.spawn_async(|schedules| async move {
        schedules.add_system(Update, once::run(play_audio)).await;
        schedules.add_system(Update, wait::until(finished_audio)).await;
        info!("***** Finished audio *****");
        schedules.add_system(Update, once::send(AppExit)).await;
    });
}

fn play_audio(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
) {
    commands.spawn(AudioBundle {
        source: asset_server.load("audio/higurashi.ogg"),
        settings: PlaybackSettings::ONCE,
    });
}

fn finished_audio(
    mut commands: Commands,
    audio: Query<(Entity, &AudioSink)>,
) -> bool {
    let Ok((entity, audio)) = audio.get_single() else { return false; };
    if audio.empty() {
        commands.entity(entity).despawn();
        true
    } else {
        false
    }
}

delay

You can delay the task using Frames or Timer.

use bevy::prelude::*;
use bevy_async_system::prelude::*;

fn setup(
    mut commands: Commands,
    mut settings: ResMut<FramepaceSettings>,
) {
    settings.limiter = Limiter::from_framerate(30.);
    commands.spawn_async(|schedules| async move {
        println!("Wait 3 seconds...");
        schedules.add_system(Update, delay::timer(Duration::from_secs(3))).await;

        println!("Wait 90 frames...");
        schedules.add_system(Update, delay::frames(90)).await;
    });
}

repeat

The repeat is used to run the system multiple times.

use bevy::prelude::*;
use bevy_async_system::prelude::*;

fn setup(mut commands: Commands) {
    commands.spawn_async(|schedules| async move {
        schedules.add_system(Update, repeat::times(5, count_up)).await;

        let handle = schedules.add_system(Update, repeat::forever(count_up));
        schedules.add_system(Update, delay::timer(Duration::from_secs(3))).await;

        // task and system cancel.
        drop(handle);

        println!("task canceled. Exit the application after 3 seconds.");
        // Delay to make sure the system does not run.
        schedules.add_system(Update, delay::timer(Duration::from_secs(3))).await;
        println!("App exit");
        schedules.add_system(Update, once::app_exit()).await;
    });
}

fn count_up(mut count: Local<u32>) {
    *count += 1;
    println!("count = {}", *count);
}

Compatible Bevy versions

bevy_async_system bevy
0.1 0.11
Commit count: 47

cargo fmt