2 releases
0.1.1 | Oct 16, 2023 |
---|---|
0.1.0 | Oct 15, 2023 |
#1424 in Asynchronous
245KB
1K
SLoC
bevy_async_system
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 |
Dependencies
~21–32MB
~492K SLoC