use bevy::{
ecs::system::SystemParamItem, input::common_conditions::input_just_pressed, prelude::*,
};
use pyri_state::{
next_state::{NextState, NextStateMut},
prelude::*,
};
fn main() -> AppExit {
App::new()
.add_plugins((DefaultPlugins, StatePlugin))
.insert_resource(StateDebugSettings {
log_flush: true,
..default()
})
.init_state::<MyBufferedState>()
.init_state::<MyStackedState>()
.insert_state(NextStatePair([
Some(MyPairedState::X),
Some(MyPairedState::Y),
]))
.add_systems(
Update,
(
MyStackedState::A
.push()
.run_if(input_just_pressed(KeyCode::KeyA)),
MyStackedState::B
.push()
.run_if(input_just_pressed(KeyCode::KeyB)),
MyStackedState::pop.run_if(input_just_pressed(KeyCode::Escape)),
MyPairedState::swap.run_if(input_just_pressed(KeyCode::Space)),
),
)
.run()
}
#[derive(State, Reflect, Clone, PartialEq, Eq, Default)]
#[reflect(Resource)]
struct MyBufferedState;
#[derive(State, Reflect, Clone, PartialEq, Eq, Debug, Default)]
#[state(log_flush, next(NextStateStack<Self>))]
#[reflect(Resource)]
enum MyStackedState {
#[default]
A,
B,
}
#[derive(Resource, Component, Reflect)]
#[reflect(Resource, Component)]
struct NextStatePair<S: State>([Option<S>; 2]);
impl<S: State> NextState for NextStatePair<S> {
type State = S;
type Param = ();
fn empty() -> Self {
Self([None, None])
}
fn next_state<'s>(&'s self, _param: &'s SystemParamItem<Self::Param>) -> Option<&'s S> {
self.0[0].as_ref()
}
}
impl<S: State> NextStateMut for NextStatePair<S> {
type ParamMut = ();
fn next_state_from_mut<'s>(
&'s self,
_param: &'s SystemParamItem<Self::ParamMut>,
) -> Option<&'s S> {
self.0[0].as_ref()
}
fn next_state_mut<'s>(
&'s mut self,
_param: &'s mut SystemParamItem<Self::ParamMut>,
) -> Option<&'s mut S> {
self.0[0].as_mut()
}
fn set_next_state(&mut self, _param: &mut SystemParamItem<Self::ParamMut>, state: Option<S>) {
self.0[0] = state;
}
}
trait NextStatePairMut: State {
fn swap(mut swap: ResMut<NextStatePair<Self>>) {
let [left, right] = &mut swap.0;
core::mem::swap(left, right);
}
}
impl<S: State<Next = NextStatePair<S>>> NextStatePairMut for S {}
#[derive(State, Reflect, Clone, PartialEq, Eq, Debug)]
#[state(log_flush, next(NextStatePair<Self>))]
#[reflect(Resource)]
enum MyPairedState {
X,
Y,
}