use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use bevy_state_stack::*;
#[derive(Debug, Clone, Eq, PartialEq, Hash, StageLabel)]
enum AppState {
Menu,
Map,
Encounter,
}
#[derive(Component)]
struct Menu;
#[derive(Debug, PartialEq, Eq)]
enum MenuAction {
Pause,
Resume,
NewGame,
}
#[derive(Default)]
struct Test {
exit_count: u8,
enter_count: u8,
}
#[test]
fn test() {
let mut app = App::new();
app.init_resource::<Test>();
app.add_event::<MenuAction>();
app.add_state_stack(AppState::Menu);
app.add_system_on_enter(AppState::Menu, enter_counter);
app.add_system_on_enter(AppState::Map, enter_counter);
app.add_system_on_exit(AppState::Menu, exit_counter);
app.add_system_on_exit(AppState::Map, exit_counter);
app.add_system_on_enter(AppState::Menu, setup_menu);
app.add_system_on_exit(AppState::Menu, despawn::<Menu>);
app.add_system_on_enter(AppState::Map, setup_map);
app.add_system_on_update(AppState::Map, pause)
.add_system_on_update(AppState::Encounter, pause)
.add_system_set_on_update(
AppState::Menu,
SystemSet::new().with_system(resume).with_system(start_game),
);
app.update();
let test = app.world.get_resource::<Test>().unwrap();
assert_eq!(test.enter_count, 1);
assert_eq!(test.exit_count, 0);
app.world.send_event(MenuAction::NewGame);
app.update();
app.update();
let top_state = app.world.get_resource::<TopState<AppState>>().unwrap();
assert_eq!(top_state.0, AppState::Map);
let test = app.world.get_resource::<Test>().unwrap();
assert_eq!(test.enter_count, 2);
assert_eq!(test.exit_count, 1);
app.world.send_event(MenuAction::Pause);
app.update();
app.update();
let test = app.world.get_resource::<Test>().unwrap();
assert_eq!(test.enter_count, 3);
assert_eq!(test.exit_count, 1);
app.world.send_event(MenuAction::Resume);
app.update();
app.update();
let top_state = app.world.get_resource::<TopState<AppState>>().unwrap();
assert_eq!(top_state.0, AppState::Map);
let test = app.world.get_resource::<Test>().unwrap();
assert_eq!(test.enter_count, 3);
assert_eq!(test.exit_count, 2);
}
fn enter_counter(mut c: ResMut<Test>, state: Res<TopState<AppState>>) {
println!("entering: {:?}", state);
c.enter_count += 1;
}
fn exit_counter(mut c: ResMut<Test>, state: Res<TopState<AppState>>) {
println!("leaving: {:?}", state);
c.exit_count += 1;
}
fn despawn<T: Component>(mut c: Commands, q: Query<Entity, With<T>>) {
for e in q.iter() {
c.entity(e).despawn()
}
}
fn setup_menu(mut _c: Commands) {
}
fn setup_map(mut _c: Commands) {
}
fn start_game(mut c: Commands, mut ev: EventReader<MenuAction>) {
println!("New game check");
for e in ev.iter() {
if *e == MenuAction::NewGame {
println!("New game event");
c.insert_resource(Stack::Set(AppState::Map))
}
}
}
fn pause(mut c: Commands, mut ev: EventReader<MenuAction>) {
for e in ev.iter() {
if *e == MenuAction::Pause {
c.insert_resource(Stack::Push(AppState::Menu))
}
}
}
fn resume(mut c: Commands, mut ev: EventReader<MenuAction>) {
for e in ev.iter() {
if *e == MenuAction::Resume {
c.insert_resource(Stack::<AppState>::Pop);
}
}
}