use bevy::{app::AppExit, ecs::schedule::ShouldRun, prelude::*};
#[derive(Clone, Hash, Debug, PartialEq, Eq, SystemLabel)]
struct Physics;
#[derive(Clone, Hash, Debug, PartialEq, Eq, SystemLabel)]
struct PostPhysics;
#[derive(Resource, Default)]
struct Done(bool);
fn main() {
#[derive(RunCriteriaLabel)]
struct IsDone;
App::new()
.add_plugins(DefaultPlugins)
.init_resource::<Done>()
.add_system_set(
SystemSet::new()
.label(Physics)
.with_run_criteria(run_for_a_second)
.with_system(update_velocity)
.with_system(movement.after(update_velocity)),
)
.add_system_set(
SystemSet::new()
.label(PostPhysics)
.after(Physics)
.with_run_criteria(RunCriteria::pipe(IsDone, inverse))
.with_system(collision)
.with_system(sfx),
)
.add_system(
exit.after(PostPhysics)
.with_run_criteria(is_done.label(IsDone)),
)
.run();
}
fn run_for_a_second(time: Res<Time>, mut done: ResMut<Done>) -> ShouldRun {
let elapsed = time.elapsed_seconds();
if elapsed < 1.0 {
info!(
"We should run again. Elapsed/remaining: {:.2}s/{:.2}s",
elapsed,
1.0 - elapsed
);
ShouldRun::Yes
} else {
done.0 = true;
ShouldRun::No
}
}
fn is_done(done: Res<Done>) -> ShouldRun {
done.0.into()
}
fn inverse(input: In<ShouldRun>) -> ShouldRun {
match input.0 {
ShouldRun::No => ShouldRun::Yes,
ShouldRun::Yes => ShouldRun::No,
_ => unreachable!(),
}
}
fn update_velocity() {
info!("Updating velocity");
}
fn movement() {
info!("Updating movement");
}
fn collision() {
info!("Physics done- checking collisions");
}
fn sfx() {
info!("Physics done- playing some sfx");
}
fn exit(mut app_exit_events: EventWriter<AppExit>) {
info!("Exiting...");
app_exit_events.send(AppExit);
}