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::(); app.add_event::(); 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::); 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::().unwrap(); assert_eq!(test.enter_count, 1); assert_eq!(test.exit_count, 0); app.world.send_event(MenuAction::NewGame); // add SetState resource app.update(); // Update State stack app.update(); let top_state = app.world.get_resource::>().unwrap(); assert_eq!(top_state.0, AppState::Map); let test = app.world.get_resource::().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::().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::>().unwrap(); assert_eq!(top_state.0, AppState::Map); let test = app.world.get_resource::().unwrap(); assert_eq!(test.enter_count, 3); assert_eq!(test.exit_count, 2); } fn enter_counter(mut c: ResMut, state: Res>) { println!("entering: {:?}", state); c.enter_count += 1; } fn exit_counter(mut c: ResMut, state: Res>) { println!("leaving: {:?}", state); c.exit_count += 1; } fn despawn(mut c: Commands, q: Query>) { for e in q.iter() { c.entity(e).despawn() } } fn setup_menu(mut _c: Commands) { // Setup menu } fn setup_map(mut _c: Commands) { // Setup map } fn start_game(mut c: Commands, mut ev: EventReader) { 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) { for e in ev.iter() { if *e == MenuAction::Pause { c.insert_resource(Stack::Push(AppState::Menu)) } } } fn resume(mut c: Commands, mut ev: EventReader) { for e in ev.iter() { if *e == MenuAction::Resume { c.insert_resource(Stack::::Pop); } } }