DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

89095ffd6848dd36c6916657352497aed596047d — Jonni Liljamo 1 year, 10 months ago 718b5bc
feat!(sdbclient): change to iyes_loopless states
M sdbclient/src/main.rs => sdbclient/src/main.rs +4 -1
@@ 16,6 16,8 @@ use bevy_inspector_egui::quick::WorldInspectorPlugin;

use bevy_mod_scripting::prelude::*;

use iyes_loopless::prelude::*;

mod api;
mod cfg;
mod constants;


@@ 84,7 86,8 @@ fn main() {
        .insert_resource(cfg::CfgUser::default())
        .insert_resource(cfg::CfgDev::default());

    app.add_startup_system(setup).add_state(GameState::Splash);
    app.add_startup_system(setup)
        .add_loopless_state(GameState::Splash);

    app.add_plugin(plugins::config::ConfigPlugin)
        .add_plugin(plugins::connection_check::ConnectionCheckPlugin)

M sdbclient/src/plugins/menu/accountlogin/mod.rs => sdbclient/src/plugins/menu/accountlogin/mod.rs +16 -13
@@ 11,6 11,7 @@ use bevy::{
    tasks::{AsyncComputeTaskPool, Task},
};
use bevy_console::PrintConsoleLine;
use iyes_loopless::prelude::*;

use futures_lite::future;



@@ 31,18 32,22 @@ pub struct AccountLoginPlugin;

impl Plugin for AccountLoginPlugin {
    fn build(&self, app: &mut App) {
        app.add_state(LoginState::None)
        app.add_loopless_state(LoginState::None)
            // UI system
            .insert_resource(ui::InputsUserLogin::new())
            .add_system_set(
                SystemSet::on_update(LoginState::Input).with_system(ui::account_login_ui),
                ConditionSet::new()
                    .run_in_state(LoginState::Input)
                    .with_system(ui::account_login_ui)
                    .into(),
            )
            // Login system, as in calling the API
            .add_enter_system(LoginState::LoggingIn, start_login_call)
            .add_system_set(
                SystemSet::on_enter(LoginState::LoggingIn).with_system(start_login_call),
            )
            .add_system_set(
                SystemSet::on_update(LoginState::LoggingIn).with_system(handle_login_call),
                ConditionSet::new()
                    .run_in_state(LoginState::LoggingIn)
                    .with_system(handle_login_call)
                    .into(),
            );
    }
}


@@ 99,8 104,6 @@ fn handle_login_call(
    mut commands: Commands,
    mut login_call_tasks: Query<(Entity, &mut LoginCall)>,
    mut inputs: ResMut<ui::InputsUserLogin>,
    mut login_state: ResMut<State<LoginState>>,
    mut menu_state: ResMut<State<MenuState>>,
    mut cfg_user: ResMut<CfgUser>,
    mut save_event_writer: EventWriter<SaveEvent>,
    mut console: EventWriter<PrintConsoleLine>,


@@ 127,22 130,22 @@ fn handle_login_call(
                            value: SaveEventValue::User(cfg_user.into_inner().clone()),
                        });

                        login_state.set(LoginState::None).unwrap();
                        menu_state.set(MenuState::AccountLoggedIn).unwrap();
                        commands.insert_resource(NextState(LoginState::None));
                        commands.insert_resource(NextState(MenuState::AccountLoggedIn));
                    }
                    ResponseUserInfoP::Error(error) => {
                        console.send(PrintConsoleLine::new(format!(
                            "Something went wrong with getting the user information after logging in, got error: '{}'", error
                        ).into()));

                        login_state.set(LoginState::None).unwrap();
                        menu_state.set(MenuState::AccountLoggedIn).unwrap();
                        commands.insert_resource(NextState(LoginState::None));
                        commands.insert_resource(NextState(MenuState::AccountLoggedIn));
                    }
                }
            }
            ResponseToken::Error(error) => {
                inputs.error = error.error.description;
                login_state.set(LoginState::Input).unwrap();
                commands.insert_resource(NextState(LoginState::Input));
            }
        }


M sdbclient/src/plugins/menu/accountlogin/ui.rs => sdbclient/src/plugins/menu/accountlogin/ui.rs +5 -5
@@ 8,6 8,7 @@

use bevy::prelude::*;
use bevy_inspector_egui::bevy_egui::{egui, EguiContext};
use iyes_loopless::prelude::*;

use crate::util::eguipwd;



@@ 34,9 35,8 @@ impl InputsUserLogin {
}

pub fn account_login_ui(
    mut commands: Commands,
    mut egui_context: ResMut<EguiContext>,
    mut menu_state: ResMut<State<MenuState>>,
    mut login_state: ResMut<State<LoginState>>,
    mut inputs: ResMut<InputsUserLogin>,
) {
    egui::Window::new("Login")


@@ 61,11 61,11 @@ pub fn account_login_ui(

            ui.with_layout(egui::Layout::right_to_left(egui::Align::Min), |ui| {
                if ui.button("Cancel").clicked() {
                    login_state.set(LoginState::None).unwrap();
                    menu_state.set(MenuState::AccountLoggedOut).unwrap();
                    commands.insert_resource(NextState(LoginState::None));
                    commands.insert_resource(NextState(MenuState::AccountLoggedOut));
                }
                if ui.button("Login").clicked() {
                    login_state.set(LoginState::LoggingIn).unwrap();
                    commands.insert_resource(NextState(LoginState::LoggingIn));
                    // Reset error field
                    inputs.error = "".to_string();
                }

M sdbclient/src/plugins/menu/accountregister/mod.rs => sdbclient/src/plugins/menu/accountregister/mod.rs +16 -13
@@ 11,6 11,7 @@ use bevy::{
    tasks::{AsyncComputeTaskPool, Task},
};
use bevy_console::PrintConsoleLine;
use iyes_loopless::prelude::*;

use futures_lite::future;



@@ 31,18 32,22 @@ pub struct AccountRegisterPlugin;

impl Plugin for AccountRegisterPlugin {
    fn build(&self, app: &mut App) {
        app.add_state(RegisterState::None)
        app.add_loopless_state(RegisterState::None)
            // UI system
            .insert_resource(ui::InputsUserRegister::new())
            .add_system_set(
                SystemSet::on_update(RegisterState::Input).with_system(ui::account_register_ui),
                ConditionSet::new()
                    .run_in_state(RegisterState::Input)
                    .with_system(ui::account_register_ui)
                    .into(),
            )
            // Register system, as in calling the API
            .add_enter_system(RegisterState::Registering, start_register_call)
            .add_system_set(
                SystemSet::on_enter(RegisterState::Registering).with_system(start_register_call),
            )
            .add_system_set(
                SystemSet::on_update(RegisterState::Registering).with_system(handle_register_call),
                ConditionSet::new()
                    .run_in_state(RegisterState::Registering)
                    .with_system(handle_register_call)
                    .into(),
            );
    }
}


@@ 96,8 101,6 @@ fn handle_register_call(
    mut commands: Commands,
    mut register_call_tasks: Query<(Entity, &mut RegisterCall)>,
    mut inputs: ResMut<ui::InputsUserRegister>,
    mut register_state: ResMut<State<RegisterState>>,
    mut menu_state: ResMut<State<MenuState>>,
    mut cfg_user: ResMut<CfgUser>,
    mut save_event_writer: EventWriter<SaveEvent>,
    mut console: EventWriter<PrintConsoleLine>,


@@ 124,8 127,8 @@ fn handle_register_call(
                            value: SaveEventValue::User(cfg_user.into_inner().clone()),
                        });

                        register_state.set(RegisterState::None).unwrap();
                        menu_state.set(MenuState::AccountLoggedIn).unwrap();
                        commands.insert_resource(NextState(RegisterState::None));
                        commands.insert_resource(NextState(MenuState::AccountLoggedIn));
                    }
                    ResponseToken::Error(error) => {
                        // TODO: Handle? Is it possible to even get here without the server shitting itself between the register and token calls?


@@ 134,14 137,14 @@ fn handle_register_call(
                            "Something went wrong with getting the user token after registering, got error: '{}'", error
                        ).into()));

                        register_state.set(RegisterState::None).unwrap();
                        menu_state.set(MenuState::AccountLoggedOut).unwrap();
                        commands.insert_resource(NextState(RegisterState::None));
                        commands.insert_resource(NextState(MenuState::AccountLoggedOut));
                    }
                }
            }
            ResponseRegister::Error(error) => {
                inputs.error = error.error.description;
                register_state.set(RegisterState::Input).unwrap();
                commands.insert_resource(NextState(RegisterState::Input));
            }
        }


M sdbclient/src/plugins/menu/accountregister/ui.rs => sdbclient/src/plugins/menu/accountregister/ui.rs +5 -5
@@ 8,6 8,7 @@

use bevy::prelude::*;
use bevy_inspector_egui::bevy_egui::{egui, EguiContext};
use iyes_loopless::prelude::*;

use crate::util::eguipwd;



@@ 40,9 41,8 @@ impl InputsUserRegister {
}

pub fn account_register_ui(
    mut commands: Commands,
    mut egui_context: ResMut<EguiContext>,
    mut menu_state: ResMut<State<MenuState>>,
    mut register_state: ResMut<State<RegisterState>>,
    mut inputs: ResMut<InputsUserRegister>,
) {
    egui::Window::new("Register")


@@ 85,13 85,13 @@ pub fn account_register_ui(

            ui.with_layout(egui::Layout::right_to_left(egui::Align::Min), |ui| {
                if ui.button("Cancel").clicked() {
                    register_state.set(RegisterState::None).unwrap();
                    menu_state.set(MenuState::AccountLoggedOut).unwrap();
                    commands.insert_resource(NextState(RegisterState::None));
                    commands.insert_resource(NextState(MenuState::AccountLoggedOut));
                }

                ui.add_enabled_ui(inputs.passwords_match, |ui| {
                    if ui.button("Register").clicked() {
                        register_state.set(RegisterState::Registering).unwrap();
                        commands.insert_resource(NextState(RegisterState::Registering));
                        // Reset error field
                        inputs.error = "".to_string();
                    }

M sdbclient/src/plugins/menu/mod.rs => sdbclient/src/plugins/menu/mod.rs +57 -43
@@ 7,6 7,7 @@
 */

use bevy::{app::AppExit, prelude::*};
use iyes_loopless::prelude::*;

use crate::cfg::CfgUser;



@@ 47,34 48,40 @@ impl Plugin for MenuPlugin {
    fn build(&self, app: &mut App) {
        app.
            // Start with no menu. The menu is loaded when the GameState::MainMenu is entered.
            add_state(MenuState::None)
            .add_system_set(SystemSet::on_enter(GameState::MainMenu).with_system(menu_setup))
            add_loopless_state(MenuState::None)
            .add_enter_system(GameState::MainMenu, menu_setup)
            // Systems for main menu screen
            .add_system_set(SystemSet::on_enter(MenuState::Main).with_system(main_menu_setup))
            .add_system_set(SystemSet::on_exit(MenuState::Main).with_system(despawn_screen::<OnMainMenuScreen>))
            .add_enter_system(MenuState::Main, main_menu_setup)
            .add_exit_system(MenuState::Main, despawn_screen::<OnMainMenuScreen>)
            // Systems for settings menu screen
            .add_system_set(SystemSet::on_enter(MenuState::Settings).with_system(settings_menu_setup))
            .add_system_set(SystemSet::on_exit(MenuState::Settings).with_system(despawn_screen::<OnSettingsMenuScreen>))
            .add_enter_system(MenuState::Settings, settings_menu_setup)
            .add_exit_system(MenuState::Settings, despawn_screen::<OnSettingsMenuScreen>)
            // Systems for settings display screen
            .add_system_set(SystemSet::on_enter(MenuState::SettingsDisplay).with_system(settings_display_setup))
            .add_system_set(SystemSet::on_exit(MenuState::SettingsDisplay).with_system(despawn_screen::<OnSettingsDisplayScreen>))
            .add_enter_system(MenuState::SettingsDisplay, settings_display_setup)
            .add_exit_system(MenuState::SettingsDisplay, despawn_screen::<OnSettingsDisplayScreen>)
            // Systems for settings audio screen
            .add_system_set(SystemSet::on_enter(MenuState::SettingsAudio).with_system(settings_audio_setup))
            .add_system_set(SystemSet::on_exit(MenuState::SettingsAudio).with_system(despawn_screen::<OnSettingsAudioScreen>))
            .add_enter_system(MenuState::SettingsAudio, settings_audio_setup)
            .add_exit_system(MenuState::SettingsAudio, despawn_screen::<OnSettingsAudioScreen>)
            // Systems for settings misc screen
            .add_system_set(SystemSet::on_enter(MenuState::SettingsMisc).with_system(settings_misc_setup))
            .add_system_set(SystemSet::on_exit(MenuState::SettingsMisc).with_system(despawn_screen::<OnSettingsMiscScreen>))
            .add_enter_system(MenuState::SettingsMisc, settings_misc_setup)
            .add_exit_system(MenuState::SettingsMisc, despawn_screen::<OnSettingsMiscScreen>)
            // Systems for account loggedout screen
            .add_system_set(SystemSet::on_enter(MenuState::AccountLoggedOut).with_system(account_loggedout_setup))
            .add_system_set(SystemSet::on_exit(MenuState::AccountLoggedOut).with_system(despawn_screen::<OnAccountLoggedOutScreen>))
            .add_enter_system(MenuState::AccountLoggedOut, account_loggedout_setup)
            .add_exit_system(MenuState::AccountLoggedOut, despawn_screen::<OnAccountLoggedOutScreen>)
            // Systems for account loggedin screen
            .add_system_set(SystemSet::on_enter(MenuState::AccountLoggedIn).with_system(account_loggedin_setup))
            .add_system_set(SystemSet::on_exit(MenuState::AccountLoggedIn).with_system(despawn_screen::<OnAccountLoggedInScreen>))
            .add_enter_system(MenuState::AccountLoggedIn, account_loggedin_setup)
            .add_exit_system(MenuState::AccountLoggedIn, despawn_screen::<OnAccountLoggedInScreen>)
            // Systems for play screen
            .add_system_set(SystemSet::on_enter(MenuState::Play).with_system(play_setup))
            .add_system_set(SystemSet::on_exit(MenuState::Play).with_system(despawn_screen::<OnPlayScreen>))
            .add_enter_system(MenuState::Play, play_setup)
            .add_exit_system(MenuState::Play, despawn_screen::<OnPlayScreen>)
            // Common systems
            .add_system_set(SystemSet::on_update(GameState::MainMenu).with_system(menu_action).with_system(button_system));
            .add_system_set(
                ConditionSet::new()
                    .run_in_state(GameState::MainMenu)
                    .with_system(menu_action)
                    .with_system(button_system)
                    .into()
            );

        app.add_plugin(accountregister::AccountRegisterPlugin)
            .add_plugin(accountlogin::AccountLoginPlugin);


@@ 133,49 140,52 @@ enum MenuButtonAction {
}

fn menu_action(
    mut commands: Commands,
    interaction_query: Query<
        (&Interaction, &MenuButtonAction),
        (Changed<Interaction>, With<Button>),
    >,
    mut app_exit_events: EventWriter<AppExit>,
    mut menu_state: ResMut<State<MenuState>>,
    mut register_state: ResMut<State<accountregister::RegisterState>>,
    mut login_state: ResMut<State<accountlogin::LoginState>>,
    mut cfg_user: ResMut<CfgUser>,
    mut save_event_writer: EventWriter<SaveEvent>,
    //mut game_state: ResMut<State<GameState>>,
) {
    for (interaction, menu_button_action) in &interaction_query {
        if *interaction == Interaction::Clicked {
            match menu_button_action {
                MenuButtonAction::Exit => app_exit_events.send(AppExit),
                MenuButtonAction::Play => menu_state.set(MenuState::Play).unwrap(),
                MenuButtonAction::CreateGame => menu_state.set(MenuState::CreateGame).unwrap(),
                MenuButtonAction::JoinGame => menu_state.set(MenuState::JoinGame).unwrap(),
                MenuButtonAction::Settings => menu_state.set(MenuState::Settings).unwrap(),
                MenuButtonAction::Play => commands.insert_resource(NextState(MenuState::Play)),
                MenuButtonAction::CreateGame => {
                    commands.insert_resource(NextState(MenuState::CreateGame))
                }
                MenuButtonAction::JoinGame => {
                    commands.insert_resource(NextState(MenuState::JoinGame))
                }
                MenuButtonAction::Settings => {
                    commands.insert_resource(NextState(MenuState::Settings))
                }
                MenuButtonAction::SettingsDisplay => {
                    menu_state.set(MenuState::SettingsDisplay).unwrap()
                    commands.insert_resource(NextState(MenuState::SettingsDisplay))
                }
                MenuButtonAction::SettingsAudio => {
                    menu_state.set(MenuState::SettingsAudio).unwrap()
                    commands.insert_resource(NextState(MenuState::SettingsAudio))
                }
                MenuButtonAction::SettingsMisc => {
                    commands.insert_resource(NextState(MenuState::SettingsMisc))
                }
                MenuButtonAction::SettingsMisc => menu_state.set(MenuState::SettingsMisc).unwrap(),
                MenuButtonAction::Account => {
                    if cfg_user.logged_in {
                        menu_state.set(MenuState::AccountLoggedIn).unwrap()
                        commands.insert_resource(NextState(MenuState::AccountLoggedIn))
                    } else {
                        menu_state.set(MenuState::AccountLoggedOut).unwrap()
                        commands.insert_resource(NextState(MenuState::AccountLoggedOut))
                    }
                }
                MenuButtonAction::AccountLogin => {
                    menu_state.set(MenuState::AccountLogin).unwrap();
                    login_state.set(accountlogin::LoginState::Input).unwrap();
                    commands.insert_resource(NextState(MenuState::AccountLogin));
                    commands.insert_resource(NextState(accountlogin::LoginState::Input));
                }
                MenuButtonAction::AccountRegister => {
                    menu_state.set(MenuState::AccountRegister).unwrap();
                    register_state
                        .set(accountregister::RegisterState::Input)
                        .unwrap();
                    commands.insert_resource(NextState(MenuState::AccountRegister));
                    commands.insert_resource(NextState(accountregister::RegisterState::Input));
                }
                MenuButtonAction::AccountLogout => {
                    // Reset CfgUser to default.


@@ 185,10 195,14 @@ fn menu_action(
                        value: SaveEventValue::User(cfg_user.clone()),
                    });

                    menu_state.set(MenuState::AccountLoggedOut).unwrap()
                    commands.insert_resource(NextState(MenuState::AccountLoggedOut))
                }
                MenuButtonAction::BackToSettings => {
                    commands.insert_resource(NextState(MenuState::Settings))
                }
                MenuButtonAction::BackToMainMenu => {
                    commands.insert_resource(NextState(MenuState::Main))
                }
                MenuButtonAction::BackToSettings => menu_state.set(MenuState::Settings).unwrap(),
                MenuButtonAction::BackToMainMenu => menu_state.set(MenuState::Main).unwrap(),
            }
        }
    }


@@ 215,6 229,6 @@ fn button_system(
    }
}

fn menu_setup(mut menu_state: ResMut<State<MenuState>>) {
    let _ = menu_state.set(MenuState::Main);
fn menu_setup(mut commands: Commands) {
    commands.insert_resource(NextState(MenuState::Main))
}

M sdbclient/src/plugins/phases/loading/mod.rs => sdbclient/src/plugins/phases/loading/mod.rs +4 -7
@@ 12,6 12,7 @@ use bevy::{
    prelude::*,
    ui::{JustifyContent, Size, Style, Val},
};
use iyes_loopless::prelude::*;

use crate::{
    constants::TEXT_COLOR,


@@ 27,12 28,9 @@ impl Plugin for LoadingPlugin {
    fn build(&self, app: &mut App) {
        app
            // Load the loading screen when we enter the Loading state
            .add_system_set(SystemSet::on_enter(GameState::Loading).with_system(loading_setup))
            .add_enter_system(GameState::Loading, loading_setup)
            // Despawn when we exit the Loading state
            .add_system_set(
                SystemSet::on_exit(GameState::Loading)
                    .with_system(despawn_screen::<OnLoadingScreen>),
            );
            .add_exit_system(GameState::Loading, despawn_screen::<OnLoadingScreen>);
    }
}



@@ 43,7 41,6 @@ struct OnLoadingScreen;
fn loading_setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut game_state: ResMut<State<GameState>>,
    mut load_event_writer: EventWriter<LoadEvent>,
) {
    let font = asset_server.load("fonts/FiraMono-Regular.ttf");


@@ 91,5 88,5 @@ fn loading_setup(
        value: LoadEventValue::Dev,
    });

    game_state.overwrite_set(GameState::MainMenu).unwrap();
    commands.insert_resource(NextState(GameState::MainMenu));
}

M sdbclient/src/plugins/phases/splash/mod.rs => sdbclient/src/plugins/phases/splash/mod.rs +11 -11
@@ 10,6 10,7 @@ use bevy::{
    prelude::*,
    ui::{JustifyContent, Size, Style, Val},
};
use iyes_loopless::prelude::*;

use crate::{despawn_screen, GameState};



@@ 20,13 21,16 @@ impl Plugin for SplashPlugin {
    fn build(&self, app: &mut App) {
        app
            // Load the splash when we enter the Splash state
            .add_system_set(SystemSet::on_enter(GameState::Splash).with_system(splash_setup))
            .add_enter_system(GameState::Splash, splash_setup)
            // Run a timer for a few seconds
            .add_system_set(SystemSet::on_update(GameState::Splash).with_system(splash_timer))
            // Despawn when we exit the Splash state
            .add_system_set(
                SystemSet::on_exit(GameState::Splash).with_system(despawn_screen::<OnSplashScreen>),
            );
                ConditionSet::new()
                    .run_in_state(GameState::Splash)
                    .with_system(splash_timer)
                    .into(),
            )
            // Despawn when we exit the Splash state
            .add_exit_system(GameState::Splash, despawn_screen::<OnSplashScreen>);
    }
}



@@ 69,12 73,8 @@ fn splash_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.insert_resource(SplashTimer(Timer::from_seconds(2., TimerMode::Once)));
}

fn splash_timer(
    mut game_state: ResMut<State<GameState>>,
    time: Res<Time>,
    mut timer: ResMut<SplashTimer>,
) {
fn splash_timer(mut commands: Commands, time: Res<Time>, mut timer: ResMut<SplashTimer>) {
    if timer.tick(time.delta()).finished() {
        game_state.set(GameState::Loading).unwrap()
        commands.insert_resource(NextState(GameState::Loading))
    }
}