#[cfg(feature = "bevy_app")]
pub use app::*;
#[cfg(feature = "bevy_app")]
mod app {
use core::marker::PhantomData;
use bevy_app::{App, Plugin};
use crate::schedule::StateFlush;
use super::*;
pub struct DetectChangePlugin<S: State + Eq>(PhantomData<S>);
impl<S: State + Eq> Plugin for DetectChangePlugin<S> {
fn build(&self, app: &mut App) {
schedule_detect_change::<S>(app.get_schedule_mut(StateFlush).unwrap());
}
}
impl<S: State + Eq> Default for DetectChangePlugin<S> {
fn default() -> Self {
Self(PhantomData)
}
}
pub struct LocalDetectChangePlugin<S: LocalState + Eq>(PhantomData<S>);
impl<S: LocalState + Eq> Plugin for LocalDetectChangePlugin<S> {
fn build(&self, app: &mut App) {
schedule_local_detect_change::<S>(app.get_schedule_mut(StateFlush).unwrap());
}
}
impl<S: LocalState + Eq> Default for LocalDetectChangePlugin<S> {
fn default() -> Self {
Self(PhantomData)
}
}
}
use bevy_ecs::{
schedule::{IntoScheduleConfigs as _, Schedule, SystemCondition, common_conditions::not},
system::{Query, StaticSystemParam},
};
use crate::{
next_state::{NextState, TriggerStateFlush},
schedule::resolve_state::ResolveStateSystems,
state::{LocalState, State, StateExtEq as _},
};
pub fn schedule_detect_change<S: State + Eq>(schedule: &mut Schedule) {
schedule.add_systems(
S::trigger
.run_if(not(S::is_triggered).and(S::will_change))
.in_set(ResolveStateSystems::<S>::Trigger),
);
}
fn local_detect_change<S: LocalState + Eq>(
next_param: StaticSystemParam<<S::Next as NextState>::Param>,
mut state_query: Query<(Option<&S>, &S::Next, &mut TriggerStateFlush<S>)>,
) {
for (current, next, mut trigger) in &mut state_query {
if !trigger.0 && current != next.next_state(&next_param) {
trigger.0 = true;
}
}
}
pub fn schedule_local_detect_change<S: LocalState + Eq>(schedule: &mut Schedule) {
schedule.add_systems(local_detect_change::<S>.in_set(ResolveStateSystems::<S>::Trigger));
}