1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use bevy_ecs::{query::ReadOnlyWorldQuery, system::BoxedSystem};
use crate::*;
/// The [`Plugin`] for this library that must be added to [`App`] in order for everything to work.
///
/// This plugin adds a system that advances the action queue for each `agent`.
/// By default, the system is added to [`CoreSet::Last`].
/// For custom scheduling, see [`ActionHandler::check_actions`].
///
/// # Example
///
/// ```rust,no_run
/// # use bevy_ecs::prelude::*;
/// # use bevy_app::prelude::*;
/// # use bevy_sequential_actions::*;
/// # fn main() {
/// App::new()
/// .add_plugin(SequentialActionsPlugin)
/// .run();
/// # }
/// ```
pub struct SequentialActionsPlugin;
impl Plugin for SequentialActionsPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Last, check_actions::<()>);
}
}
impl ActionHandler {
/// The [`System`] used by [`SequentialActionsPlugin`].
/// It is responsible for checking all agents for finished actions
/// and advancing the action queue.
///
/// The query filter `F` is used for filtering agents.
/// Use the unit type `()` for no filtering.
///
/// # Example
///
/// ```rust,no_run
/// # use bevy_ecs::prelude::*;
/// # use bevy_app::prelude::*;
/// # use bevy_sequential_actions::*;
/// #
/// # fn main() {
/// App::new()
/// .add_systems(Last, ActionHandler::check_actions::<()>())
/// .run();
/// # }
/// ```
pub fn check_actions<F: ReadOnlyWorldQuery + 'static>() -> BoxedSystem {
Box::new(IntoSystem::into_system(check_actions::<F>))
}
}
fn check_actions<F: ReadOnlyWorldQuery>(
action_q: Query<(Entity, &CurrentAction), F>,
world: &World,
mut commands: Commands,
) {
action_q.for_each(|(agent, current_action)| {
if let Some(action) = current_action.as_ref() {
if action.is_finished(agent, world) {
commands.add(move |world: &mut World| {
ActionHandler::stop_current(agent, StopReason::Finished, world);
ActionHandler::start_next(agent, world);
});
}
}
});
}