#[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 BevyStatePlugin<S: StateMut + Clone + PartialEq + Eq + Hash + Debug>(PhantomData<S>);
impl<S: StateMut + Clone + PartialEq + Eq + Hash + Debug> Plugin for BevyStatePlugin<S> {
fn build(&self, app: &mut App) {
bevy::AppExtStates::init_state::<BevyState<S>>(app);
schedule_bevy_state::<S>(app.get_schedule_mut(StateFlush).unwrap());
}
}
impl<S: StateMut + Clone + PartialEq + Eq + Hash + Debug> Default for BevyStatePlugin<S> {
fn default() -> Self {
Self(PhantomData)
}
}
}
use core::{fmt::Debug, hash::Hash};
use bevy_ecs::{
schedule::{IntoScheduleConfigs as _, Schedule},
system::{Res, ResMut},
};
use bevy_state::prelude as bevy;
use crate::{
access::{NextMut, NextRef},
schedule::ResolveStateSystems,
state::{State, StateMut},
};
#[derive(bevy::States, Clone, PartialEq, Eq, Hash, Debug)]
pub struct BevyState<S: State + Clone + PartialEq + Eq + Hash + Debug>(
pub Option<S>,
);
impl<S: State + Clone + PartialEq + Eq + Hash + Debug> Default for BevyState<S> {
fn default() -> Self {
Self(None)
}
}
impl<S: State + Clone + PartialEq + Eq + Hash + Debug> From<S> for BevyState<S> {
fn from(value: S) -> Self {
Self(Some(value))
}
}
pub trait StateExtBevy: State + Clone + PartialEq + Eq + Hash + Debug {
fn bevy(self) -> BevyState<Self>;
}
impl<S: State + Clone + PartialEq + Eq + Hash + Debug> StateExtBevy for S {
fn bevy(self) -> BevyState<Self> {
self.into()
}
}
pub fn schedule_bevy_state<S: State + StateMut + Clone + PartialEq + Eq + Hash + Debug>(
schedule: &mut Schedule,
) {
let sync_pyri_state =
|mut pyri_state: NextMut<S>, bevy_state: Res<bevy::NextState<BevyState<S>>>| {
if let bevy::NextState::Pending(bevy_state) = bevy_state.as_ref() {
pyri_state.trigger().set(bevy_state.0.clone());
}
};
let sync_bevy_state =
|pyri_state: NextRef<S>, mut bevy_state: ResMut<bevy::NextState<BevyState<S>>>| {
bevy_state.set(BevyState(pyri_state.get().cloned()));
};
schedule.add_systems((
sync_pyri_state.in_set(ResolveStateSystems::<S>::Compute),
sync_bevy_state.in_set(ResolveStateSystems::<S>::AnyFlush),
));
}