use bevy_app::{AppExit, ScheduleRunnerPlugin, prelude::*};
use bevy_ecs::prelude::*;
use bevy_sequential_actions::*;
fn main() {
App::new()
.add_plugins((ScheduleRunnerPlugin::default(), SequentialActionsPlugin))
.add_systems(Startup, setup)
.add_systems(Update, countdown)
.run();
}
fn setup(mut commands: Commands) {
let agent = commands.spawn(SequentialActions).id();
commands
.actions(agent)
.add(DemoAction)
.add((
PrintAction("hello"),
PrintAction("there"),
CountdownAction::new(5),
))
.add(actions![
PrintAction("it is possible to commit no mistakes and still lose"),
PrintAction("that is not a weakness"),
PrintAction("that is life"),
CountdownAction::new(10),
])
.add(|_agent, world: &mut World| -> bool {
world.write_message(AppExit::Success);
true
});
}
struct DemoAction;
impl Action for DemoAction {
fn is_finished(&self, _agent: Entity, _world: &World) -> bool {
println!("is_finished: called every frame in the Last schedule");
true
}
fn on_start(&mut self, _agent: Entity, _world: &mut World) -> bool {
println!("on_start: called when an action is started");
false
}
fn on_stop(&mut self, _agent: Option<Entity>, _world: &mut World, _reason: StopReason) {
println!("on_stop: called when an action is stopped");
}
fn on_add(&mut self, _agent: Entity, _world: &mut World) {
println!("on_add: called when an action is added to the queue");
}
fn on_remove(&mut self, _agent: Option<Entity>, _world: &mut World) {
println!("on_remove: called when an action is removed from the queue");
}
fn on_drop(self: Box<Self>, _agent: Option<Entity>, _world: &mut World, _reason: DropReason) {
println!("on_drop: the last method to be called with full ownership");
}
}
struct PrintAction(&'static str);
impl Action for PrintAction {
fn is_finished(&self, _agent: Entity, _world: &World) -> bool {
true
}
fn on_start(&mut self, _agent: Entity, _world: &mut World) -> bool {
println!("{}", self.0);
true
}
fn on_stop(&mut self, _agent: Option<Entity>, _world: &mut World, _reason: StopReason) {}
}
struct CountdownAction {
count: u32,
remaining: Option<u32>,
}
impl CountdownAction {
const fn new(count: u32) -> Self {
Self {
count,
remaining: None,
}
}
}
impl Action for CountdownAction {
fn is_finished(&self, agent: Entity, world: &World) -> bool {
let current_count = world.get::<Countdown>(agent).unwrap().0;
println!("Countdown: {current_count}");
current_count == 0
}
fn on_start(&mut self, agent: Entity, world: &mut World) -> bool {
let count = self.remaining.take().unwrap_or(self.count);
world.entity_mut(agent).insert(Countdown(count));
self.is_finished(agent, world)
}
fn on_stop(&mut self, agent: Option<Entity>, world: &mut World, reason: StopReason) {
let Some(agent) = agent else { return };
let countdown = world.entity_mut(agent).take::<Countdown>();
if reason == StopReason::Paused {
self.remaining = countdown.unwrap().0.into();
}
}
}
#[derive(Component)]
struct Countdown(u32);
fn countdown(mut countdown_q: Query<&mut Countdown>) {
for mut countdown in &mut countdown_q {
countdown.0 -= 1;
}
}