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(Default)]
struct Done(bool);
#[derive(Clone, Hash, Debug, PartialEq, Eq, SystemLabel)]
pub enum PhysicsSystem {
UpdateVelocity,
Movement,
}
fn main() {
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
.label(PhysicsSystem::UpdateVelocity),
)
.with_system(
movement
.label(PhysicsSystem::Movement)
.after(PhysicsSystem::UpdateVelocity),
),
)
.add_system_set(
SystemSet::new()
.label(PostPhysics)
.after(Physics)
.with_run_criteria(RunCriteria::pipe("is_done_label", inverse.system()))
.with_system(collision)
.with_system(sfx),
)
.add_system(
exit.after(PostPhysics)
.with_run_criteria(is_done.label("is_done_label")),
)
.run();
}
fn run_for_a_second(time: Res<Time>, mut done: ResMut<Done>) -> ShouldRun {
let elapsed = time.seconds_since_startup();
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 {
if done.0 {
ShouldRun::Yes
} else {
ShouldRun::No
}
}
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);
}