use crate::prelude::*;
use beet_core::prelude::*;
#[derive(Debug, Default, Component, Reflect)]
#[reflect(Component)]
pub struct NoInterrupt;
pub(crate) fn interrupt_on_run<T: RunEvent>(
ev: On<T>,
mut commands: Commands,
running: Populated<Entity, (With<Running>, Without<NoInterrupt>)>,
children: Populated<&Children>,
) {
let action = ev.target();
for child in children.iter_descendants(action) {
if running.contains(child) {
commands.entity(child).remove::<Running>();
}
}
}
pub(crate) fn interrupt_on_end<T: EndEvent>(
ev: On<T>,
mut commands: Commands,
children: Query<&Children>,
running: Populated<Entity, With<Running>>,
no_interrupt: Query<(), With<NoInterrupt>>,
) {
let action = ev.target();
if running.contains(action) {
commands.entity(action).remove::<Running>();
}
for child in children.iter_descendants(action) {
if running.contains(child) && !no_interrupt.contains(child) {
commands.entity(child).remove::<Running>();
}
}
}
#[cfg(test)]
mod test {
use crate::prelude::*;
use beet_core::prelude::*;
#[test]
fn interrupt_on_run() {
let mut world = ControlFlowPlugin::world();
world
.spawn(children![Running])
.trigger_target(GetOutcome)
.flush();
world.query_once::<&Running>().len().xpect_eq(0);
}
#[test]
fn no_interrupt_on_run() {
let mut world = ControlFlowPlugin::world();
world
.spawn(children![(NoInterrupt, Running)])
.trigger_target(GetOutcome)
.flush();
world.query_once::<&Running>().len().xpect_eq(1);
}
#[test]
fn interrupt_on_end() {
let mut world = ControlFlowPlugin::world();
world
.spawn((Running, children![Running, (NoInterrupt, Running)]))
.trigger_target(Outcome::Pass)
.flush();
world.query_once::<&Running>().len().xpect_eq(1);
}
#[test]
fn interrupt_on_end_with_no_interrupt() {
let mut world = ControlFlowPlugin::world();
world
.spawn((NoInterrupt, Running))
.trigger_target(Outcome::Pass)
.flush();
world.query_once::<&Running>().len().xpect_eq(0);
}
}