use bevy::{hierarchy::HierarchyQueryExt, prelude::*};
use crate::prelude::*;
pub mod commands;
pub mod components;
pub mod iter;
pub mod prelude;
pub mod state_aggregator;
fn set_child_working_system(
trigger: Trigger<OnEnterState<InChildSMState>>,
child_sm_query: Query<&RestingState>,
mut commands: Commands,
) {
let parent_sm_entity = trigger.entity();
let child_sm_entity = trigger.event().0.0;
if let Ok(resting_state) = child_sm_query.get(child_sm_entity) {
if resting_state.is_blocked() {
commands.entity(parent_sm_entity).transition(RestingState::new());
} else {
commands.entity(child_sm_entity).transition(WorkingState);
}
} else {
commands.entity(parent_sm_entity).transition(RestingState::new());
}
}
fn early_exit_child_state_trigger_system(
trigger: Trigger<OnExitState<InChildSMState>>,
parent_sm_query: Query<&InChildSMState>,
child_sm_query: Query<Entity, Without<RestingState>>,
mut commands: Commands,
) {
let parent_sm_entity = trigger.entity();
let Ok(in_child_sm) = parent_sm_query.get(parent_sm_entity) else {
return;
};
let Ok(child_sm_entity) = child_sm_query.get(in_child_sm.0) else {
return;
};
commands.entity(child_sm_entity).transition(FizzledState);
}
fn return_to_parent_sm_system(
trigger: Trigger<OnEnterState<RestingState>>,
parent_query: Query<&Parent>,
child_query: Query<&InChildSMState>,
mut commands: Commands,
) {
let child_sm_entity = trigger.entity();
for ancestor in parent_query.iter_ancestors(child_sm_entity) {
if let Ok(in_child_sm_state) = child_query.get(ancestor) {
if in_child_sm_state.0 == child_sm_entity {
commands.entity(ancestor).transition(FinishedChildSMState(child_sm_entity));
return;
}
}
}
}
pub struct GearboxPlugin;
impl Plugin for GearboxPlugin {
fn build(&self, app: &mut App) {
app
.add_observer(set_child_working_system)
.add_observer(return_to_parent_sm_system)
.add_observer(early_exit_child_state_trigger_system);
}
}