#[cfg(feature = "bevy_app")]
pub use app::*;
#[cfg(feature = "bevy_app")]
mod app {
use alloc::vec::Vec;
use bevy_app::{App, Plugin};
use super::*;
pub struct ResolveStatePlugin<S: State> {
after: Vec<InternedSystemSet>,
before: Vec<InternedSystemSet>,
_phantom: PhantomData<S>,
}
impl<S: State> Plugin for ResolveStatePlugin<S> {
fn build(&self, app: &mut App) {
schedule_resolve_state::<S>(
app.get_schedule_mut(crate::schedule::StateFlush).unwrap(),
&self.after,
&self.before,
);
}
}
impl<S: State> Default for ResolveStatePlugin<S> {
fn default() -> Self {
Self {
after: Vec::new(),
before: Vec::new(),
_phantom: PhantomData,
}
}
}
impl<S: State> ResolveStatePlugin<S> {
pub fn new(after: Vec<InternedSystemSet>, before: Vec<InternedSystemSet>) -> Self {
Self {
after,
before,
_phantom: PhantomData,
}
}
pub fn after<T: State>(mut self) -> Self {
self.after.push(ResolveStateSystems::<T>::Resolve.intern());
self
}
pub fn before<T: State>(mut self) -> Self {
self.before.push(ResolveStateSystems::<T>::Resolve.intern());
self
}
}
}
use core::{convert::Infallible, fmt::Debug, hash::Hash, marker::PhantomData};
use bevy_ecs::schedule::{
InternedSystemSet, IntoScheduleConfigs as _, Schedule, SystemCondition, SystemSet,
};
use crate::{schedule::ApplyFlushSystems, state::State};
#[derive(SystemSet)]
pub enum ResolveStateSystems<S: State> {
Resolve,
Compute,
Trigger,
Flush,
Exit,
Trans,
Enter,
AnyFlush,
AnyExit,
AnyTrans,
AnyEnter,
#[doc(hidden)]
_PhantomData(PhantomData<S>, Infallible),
}
impl<S: State> Clone for ResolveStateSystems<S> {
fn clone(&self) -> Self {
match self {
Self::Resolve => Self::Resolve,
Self::Compute => Self::Compute,
Self::Trigger => Self::Trigger,
Self::Flush => Self::Flush,
Self::Exit => Self::Exit,
Self::Trans => Self::Trans,
Self::Enter => Self::Enter,
Self::AnyFlush => Self::AnyFlush,
Self::AnyExit => Self::AnyExit,
Self::AnyTrans => Self::AnyTrans,
Self::AnyEnter => Self::AnyEnter,
Self::_PhantomData(..) => unreachable!(),
}
}
}
impl<S: State> PartialEq for ResolveStateSystems<S> {
fn eq(&self, other: &Self) -> bool {
core::mem::discriminant(self) == core::mem::discriminant(other)
}
}
impl<S: State> Eq for ResolveStateSystems<S> {}
impl<S: State> Hash for ResolveStateSystems<S> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
core::mem::discriminant(self).hash(state);
}
}
impl<S: State> Debug for ResolveStateSystems<S> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Resolve => write!(f, "Resolve"),
Self::Compute => write!(f, "Compute"),
Self::Trigger => write!(f, "Trigger"),
Self::Flush => write!(f, "Flush"),
Self::Exit => write!(f, "Exit"),
Self::Trans => write!(f, "Trans"),
Self::Enter => write!(f, "Enter"),
Self::AnyFlush => write!(f, "AnyFlush"),
Self::AnyExit => write!(f, "AnyExit"),
Self::AnyTrans => write!(f, "AnyTrans"),
Self::AnyEnter => write!(f, "AnyEnter"),
Self::_PhantomData(..) => unreachable!(),
}
}
}
pub fn schedule_resolve_state<S: State>(
schedule: &mut Schedule,
after: &[InternedSystemSet],
before: &[InternedSystemSet],
) {
for &system_set in after {
schedule.configure_sets(ResolveStateSystems::<S>::Resolve.after(system_set));
}
for &system_set in before {
schedule.configure_sets(ResolveStateSystems::<S>::Resolve.before(system_set));
}
schedule.configure_sets((
ResolveStateSystems::<S>::Resolve.before(ApplyFlushSystems),
(
ResolveStateSystems::<S>::Compute,
ResolveStateSystems::<S>::Trigger,
ResolveStateSystems::<S>::Flush,
)
.chain()
.in_set(ResolveStateSystems::<S>::Resolve),
(
ResolveStateSystems::<S>::Exit,
ResolveStateSystems::<S>::Trans,
ResolveStateSystems::<S>::Enter,
)
.chain()
.in_set(ResolveStateSystems::<S>::Flush),
ResolveStateSystems::<S>::AnyFlush
.run_if(S::is_triggered)
.in_set(ResolveStateSystems::<S>::Flush),
(
ResolveStateSystems::<S>::AnyExit
.run_if(S::is_enabled)
.in_set(ResolveStateSystems::<S>::Exit),
ResolveStateSystems::<S>::AnyTrans
.run_if(S::is_enabled.and(S::will_be_enabled))
.in_set(ResolveStateSystems::<S>::Trans),
ResolveStateSystems::<S>::AnyEnter
.run_if(S::will_be_enabled)
.in_set(ResolveStateSystems::<S>::Enter),
)
.in_set(ResolveStateSystems::<S>::AnyFlush),
));
}