use bevy::ecs::system::Resource;
use bevy::prelude::*;
use leafwing_input_manager::prelude::*;
use menu_mocking::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(InputManagerPlugin::<MenuAction>::default())
.init_resource::<ActionState<MenuAction>>()
.insert_resource(InputMap::<MenuAction>::new([
(MenuAction::CloseWindow, KeyCode::Escape),
(MenuAction::OpenMainMenu, KeyCode::KeyM),
(MenuAction::OpenSubMenu, KeyCode::KeyS),
]))
.init_resource::<MainMenu>()
.init_resource::<SubMenu>()
.add_systems(Update, report_menus)
.add_systems(Update, open_main_menu)
.add_systems(Update, open_sub_menu)
.add_systems(Update, close_menu::<SubMenu>.before(close_menu::<MainMenu>))
.add_systems(Update, close_menu::<MainMenu>)
.run()
}
#[derive(Actionlike, Debug, Clone, Reflect, PartialEq, Eq, Hash)]
enum MenuAction {
CloseWindow,
OpenMainMenu,
OpenSubMenu,
}
fn report_menus(main_menu: Res<MainMenu>, submenu: Res<SubMenu>) {
if main_menu.is_changed() {
if main_menu.is_open() {
println!("The main menu is now open.")
} else {
println!("The main menu is now closed.")
}
}
if submenu.is_changed() {
if submenu.is_open() {
println!("The submenu is now open.")
} else {
println!("The submenu is now closed.")
}
}
}
fn open_main_menu(action_state: Res<ActionState<MenuAction>>, mut menu_state: ResMut<MainMenu>) {
if action_state.just_pressed(&MenuAction::OpenMainMenu) && !menu_state.is_open() {
menu_state.open();
}
}
fn open_sub_menu(action_state: Res<ActionState<MenuAction>>, mut menu_state: ResMut<SubMenu>) {
if action_state.just_pressed(&MenuAction::OpenSubMenu) && !menu_state.is_open() {
menu_state.open();
}
}
fn close_menu<M: Resource + Menu>(
mut action_state: ResMut<ActionState<MenuAction>>,
mut menu_status: ResMut<M>,
) {
if action_state.pressed(&MenuAction::CloseWindow) && menu_status.is_open() {
println!("Closing the top window, as requested.");
menu_status.close();
action_state.consume(&MenuAction::CloseWindow);
}
}
mod menu_mocking {
use bevy::prelude::Resource;
pub trait Menu {
fn is_open(&self) -> bool;
fn open(&mut self);
fn close(&mut self);
}
#[derive(Resource, Default)]
pub struct MainMenu {
is_open: bool,
}
impl Menu for MainMenu {
fn is_open(&self) -> bool {
self.is_open
}
fn open(&mut self) {
self.is_open = true;
}
fn close(&mut self) {
self.is_open = false;
}
}
#[derive(Resource, Default)]
pub struct SubMenu {
is_open: bool,
}
impl Menu for SubMenu {
fn is_open(&self) -> bool {
self.is_open
}
fn open(&mut self) {
self.is_open = true;
}
fn close(&mut self) {
self.is_open = false;
}
}
}