From 7a4f6e5f3fc21b3ebee255d6ceb849fc31cbdf2a Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Thu, 9 Feb 2023 13:17:39 +0200 Subject: [PATCH] WIP(sdbclient): browse games from play screen --- sdbclient/src/api/game/mod.rs | 2 +- sdbclient/src/api/game/types.rs | 1 - .../src/plugins/menu/play/allformingcall.rs | 84 +++++++++++++++++ sdbclient/src/plugins/menu/play/mod.rs | 9 ++ sdbclient/src/plugins/menu/play/ui.rs | 93 +++++++++++++------ sdbclient/src/runtime/menu/mod.rs | 9 +- 6 files changed, 168 insertions(+), 30 deletions(-) create mode 100644 sdbclient/src/plugins/menu/play/allformingcall.rs diff --git a/sdbclient/src/api/game/mod.rs b/sdbclient/src/api/game/mod.rs index 5f405e5..5492a2d 100644 --- a/sdbclient/src/api/game/mod.rs +++ b/sdbclient/src/api/game/mod.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use super::APIErrorWrapper; -mod types; +pub mod types; #[derive(Debug, Serialize, Deserialize)] pub struct ResultCreateGame { diff --git a/sdbclient/src/api/game/types.rs b/sdbclient/src/api/game/types.rs index 49f633f..6bbcc1b 100644 --- a/sdbclient/src/api/game/types.rs +++ b/sdbclient/src/api/game/types.rs @@ -16,4 +16,3 @@ pub struct Game { pub state: u8, pub ended_at: String, } - diff --git a/sdbclient/src/plugins/menu/play/allformingcall.rs b/sdbclient/src/plugins/menu/play/allformingcall.rs new file mode 100644 index 0000000..78184af --- /dev/null +++ b/sdbclient/src/plugins/menu/play/allformingcall.rs @@ -0,0 +1,84 @@ +/* + * This file is part of sdbclient + * Copyright (C) 2023 Jonni Liljamo + * + * Licensed under GPL-3.0-only. + * See LICENSE for licensing information. + */ + +use bevy::{ + prelude::*, + tasks::{AsyncComputeTaskPool, Task}, +}; +use bevy_console::PrintConsoleLine; + +use futures_lite::future; + +use crate::{ + api::{self, game::ResponseAllForming}, + cfg::{CfgDev, CfgUser}, + runtime::menu::RTDMenu, +}; + +use super::AllFormingEvent; + +struct AllFormingCallResponse { + all_forming: ResponseAllForming, +} + +#[derive(Component)] +pub(super) struct AllFormingCall(Task); + +pub(super) fn start( + mut events: EventReader, + mut commands: Commands, + cfg_dev: Res, + cfg_user: Res, + mut rtdmenu: ResMut, +) { + for _event in events.iter() { + let api_address = cfg_dev.api_server.clone(); + let token = cfg_user.user_token.clone(); + + let thread_pool = AsyncComputeTaskPool::get(); + let task = thread_pool.spawn(async move { + let all_forming_response = api::game::all_forming(api_address, token); + + AllFormingCallResponse { + all_forming: all_forming_response, + } + }); + commands.spawn(AllFormingCall(task)); + rtdmenu.waiting_for_all_forming_call = true; + } +} + +pub(super) fn handle( + mut commands: Commands, + mut all_forming_call_tasks: Query<(Entity, &mut AllFormingCall)>, + mut rtdmenu: ResMut, + mut console: EventWriter, +) { + if all_forming_call_tasks.is_empty() { + return; + } + + let (entity, mut task) = all_forming_call_tasks.single_mut(); + if let Some(all_forming_call_response) = future::block_on(future::poll_once(&mut task.0)) { + rtdmenu.waiting_for_all_forming_call = false; + match all_forming_call_response.all_forming { + ResponseAllForming::Valid(res) => { + rtdmenu.all_forming_games = res.games; + } + ResponseAllForming::Error(error) => { + console.send(PrintConsoleLine::new( + format!("Fetching all forming games faield, got error: '{}'", error).into(), + )); + } + } + + // Remove the task, since it's done now + commands.entity(entity).remove::(); + commands.entity(entity).despawn_recursive(); + } +} diff --git a/sdbclient/src/plugins/menu/play/mod.rs b/sdbclient/src/plugins/menu/play/mod.rs index a0414d8..5993149 100644 --- a/sdbclient/src/plugins/menu/play/mod.rs +++ b/sdbclient/src/plugins/menu/play/mod.rs @@ -15,9 +15,11 @@ use super::MenuState; mod ui; +mod allformingcall; mod creategamecall; struct CreateGameEvent; +struct AllFormingEvent; pub(super) struct PlayMenuPlugin; @@ -25,6 +27,7 @@ impl Plugin for PlayMenuPlugin { fn build(&self, app: &mut App) { app.add_loopless_state(PlayMenuState::None) .add_event::() + .add_event::() .add_enter_system(MenuState::Play, play_menu_setup) .add_system_set( ConditionSet::new() @@ -32,6 +35,8 @@ impl Plugin for PlayMenuPlugin { .with_system(ui::show) .with_system(creategamecall::start.run_on_event::()) .with_system(creategamecall::handle.run_if(waiting_for_create_game_call)) + .with_system(allformingcall::start.run_on_event::()) + .with_system(allformingcall::handle.run_if(waiting_for_all_forming_call)) .into(), ); } @@ -51,3 +56,7 @@ fn play_menu_setup(mut commands: Commands) { fn waiting_for_create_game_call(rtdmenu: Res) -> bool { rtdmenu.waiting_for_create_game_call } + +fn waiting_for_all_forming_call(rtdmenu: Res) -> bool { + rtdmenu.waiting_for_all_forming_call +} diff --git a/sdbclient/src/plugins/menu/play/ui.rs b/sdbclient/src/plugins/menu/play/ui.rs index bc79c35..574c7c4 100644 --- a/sdbclient/src/plugins/menu/play/ui.rs +++ b/sdbclient/src/plugins/menu/play/ui.rs @@ -15,15 +15,16 @@ use crate::{ runtime::menu::{PlayMenuUIState, RTDMenu}, }; -use super::{CreateGameEvent, PlayMenuState}; +use super::{AllFormingEvent, CreateGameEvent, PlayMenuState}; pub(super) fn show( mut commands: Commands, mut egui_context: ResMut, mut rtdmenu: ResMut, mut creategame_ev_w: EventWriter, + mut allforming_ev_w: EventWriter, ) { - egui::Window::new(egui::RichText::new(rtdmenu.play_menu_ui_state.display()).size(42.)) + egui::Window::new(egui::RichText::new(rtdmenu.play_menu_ui_state.display()).size(32.)) .resizable(false) .collapsible(false) .anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO) @@ -31,30 +32,77 @@ pub(super) fn show( // Override egui style for this scope. let mut egui_style = (*ui.style_mut()).clone(); egui_style.text_styles = [ - (egui::TextStyle::Heading, egui::FontId::new(30.0, egui::FontFamily::Proportional)), - (egui::TextStyle::Body, egui::FontId::new(18.0, egui::FontFamily::Proportional)), - (egui::TextStyle::Monospace, egui::FontId::new(14.0, egui::FontFamily::Proportional)), - (egui::TextStyle::Button, egui::FontId::new(32.0, egui::FontFamily::Proportional)), - (egui::TextStyle::Small, egui::FontId::new(10.0, egui::FontFamily::Proportional)), - ].into(); + ( + egui::TextStyle::Heading, + egui::FontId::new(30.0, egui::FontFamily::Proportional), + ), + ( + egui::TextStyle::Body, + egui::FontId::new(18.0, egui::FontFamily::Proportional), + ), + ( + egui::TextStyle::Monospace, + egui::FontId::new(14.0, egui::FontFamily::Proportional), + ), + ( + egui::TextStyle::Button, + egui::FontId::new(24.0, egui::FontFamily::Proportional), + ), + ( + egui::TextStyle::Small, + egui::FontId::new(10.0, egui::FontFamily::Proportional), + ), + ] + .into(); ui.set_style(egui_style); match rtdmenu.play_menu_ui_state { PlayMenuUIState::Main => { - ui.vertical_centered(|ui| { - if ui.button("Create").clicked() { - rtdmenu.play_menu_ui_state = PlayMenuUIState::CreateGame - } + egui::SidePanel::left("play_side_panel").show_inside(ui, |ui| { + ui.vertical_centered(|ui| { + if ui.button("Create").clicked() { + rtdmenu.play_menu_ui_state = PlayMenuUIState::CreateGame + } - if ui.button("Browse").clicked() { - rtdmenu.play_menu_ui_state = PlayMenuUIState::BrowseGames - } + if ui.button("Refresh Browse").clicked() { + allforming_ev_w.send(AllFormingEvent); + } - if ui.button("Back").clicked() { - commands.insert_resource(NextState(PlayMenuState::None)); - commands.insert_resource(NextState(MenuState::Main)); - } + if ui.button("Back").clicked() { + commands.insert_resource(NextState(PlayMenuState::None)); + commands.insert_resource(NextState(MenuState::Main)); + } + }); }); + + match rtdmenu.waiting_for_all_forming_call { + true => { + ui.horizontal(|ui| { + ui.spinner(); + ui.label("loading..."); + }); + } + false => { + ui.vertical_centered(|ui| { + egui::ScrollArea::vertical() + .max_height(200.) + .show(ui, |ui| match rtdmenu.all_forming_games.is_empty() { + true => { + ui.label("No games found."); + } + false => { + for game in &rtdmenu.all_forming_games { + egui::Frame::none().show(ui, |ui| { + ui.horizontal(|ui| { + ui.label(format!("Host: {}", game.p1)); + }); + }); + } + } + }); + }); + } + } } PlayMenuUIState::CreateGame => { ui.vertical_centered(|ui| { @@ -69,13 +117,6 @@ pub(super) fn show( }); }); } - PlayMenuUIState::BrowseGames => { - ui.vertical_centered(|ui| { - if ui.button("Back").clicked() { - rtdmenu.play_menu_ui_state = PlayMenuUIState::Main - } - }); - } PlayMenuUIState::InLobbyHost => { if ui.button("Back").clicked() { rtdmenu.play_menu_ui_state = PlayMenuUIState::Main diff --git a/sdbclient/src/runtime/menu/mod.rs b/sdbclient/src/runtime/menu/mod.rs index d8cb466..cc50ba9 100644 --- a/sdbclient/src/runtime/menu/mod.rs +++ b/sdbclient/src/runtime/menu/mod.rs @@ -8,6 +8,8 @@ use bevy::prelude::Resource; +use crate::api::game::types::Game; + /// Runtime data for use in the menu #[derive(Resource)] pub(crate) struct RTDMenu { @@ -15,6 +17,9 @@ pub(crate) struct RTDMenu { pub waiting_for_create_game_call: bool, /// Current game ID, for showing lobby data etc pub cur_game_id: String, + /// List of all forming games + pub all_forming_games: Vec, + pub waiting_for_all_forming_call: bool, } impl Default for RTDMenu { @@ -23,6 +28,8 @@ impl Default for RTDMenu { play_menu_ui_state: PlayMenuUIState::Main, waiting_for_create_game_call: false, cur_game_id: String::from(""), + all_forming_games: vec![], + waiting_for_all_forming_call: false, } } } @@ -30,7 +37,6 @@ impl Default for RTDMenu { pub(crate) enum PlayMenuUIState { Main, CreateGame, - BrowseGames, InLobbyHost, InLobbyGuest, } @@ -40,7 +46,6 @@ impl PlayMenuUIState { match self { PlayMenuUIState::Main => "Play", PlayMenuUIState::CreateGame => "Create", - PlayMenuUIState::BrowseGames => "Browse", PlayMenuUIState::InLobbyHost => "Lobby (Host)", PlayMenuUIState::InLobbyGuest => "Lobby (Guest)", } -- 2.44.1