From 619823e3ddc038163a57c12df3663dd358e0f0a5 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Thu, 16 Feb 2023 10:30:35 +0200 Subject: [PATCH] feat(sdbclient): start game API call --- sdbclient/src/plugins/menu/play/mod.rs | 9 ++ .../src/plugins/menu/play/startgamecall.rs | 105 ++++++++++++++++++ sdbclient/src/plugins/menu/play/ui.rs | 8 +- sdbclient/src/runtime/game/mod.rs | 9 +- sdbclient/src/runtime/menu/mod.rs | 2 + 5 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 sdbclient/src/plugins/menu/play/startgamecall.rs diff --git a/sdbclient/src/plugins/menu/play/mod.rs b/sdbclient/src/plugins/menu/play/mod.rs index ae2799e..c11c10e 100644 --- a/sdbclient/src/plugins/menu/play/mod.rs +++ b/sdbclient/src/plugins/menu/play/mod.rs @@ -19,11 +19,13 @@ mod allformingcall; mod creategamecall; mod joingamecall; mod mygamescall; +mod startgamecall; struct CreateGameEvent; struct AllFormingEvent; struct JoinGameEvent; struct MyGamesEvent; +struct StartGameEvent; pub(super) struct PlayMenuPlugin; @@ -34,6 +36,7 @@ impl Plugin for PlayMenuPlugin { .add_event::() .add_event::() .add_event::() + .add_event::() .add_enter_system(MenuState::Play, play_menu_setup) .add_system_set( ConditionSet::new() @@ -47,6 +50,8 @@ impl Plugin for PlayMenuPlugin { .with_system(joingamecall::handle.run_if(waiting_for_join_game_call)) .with_system(mygamescall::start.run_on_event::()) .with_system(mygamescall::handle.run_if(waiting_for_my_games_call)) + .with_system(startgamecall::start.run_on_event::()) + .with_system(startgamecall::handle.run_if(waiting_for_start_game_call)) .into(), ); } @@ -78,3 +83,7 @@ fn waiting_for_join_game_call(rtdmenu: Res) -> bool { fn waiting_for_my_games_call(rtdmenu: Res) -> bool { rtdmenu.waiting_for_my_games_call } + +fn waiting_for_start_game_call(rtdmenu: Res) -> bool { + rtdmenu.waiting_for_start_game_call +} diff --git a/sdbclient/src/plugins/menu/play/startgamecall.rs b/sdbclient/src/plugins/menu/play/startgamecall.rs new file mode 100644 index 0000000..1d29dc7 --- /dev/null +++ b/sdbclient/src/plugins/menu/play/startgamecall.rs @@ -0,0 +1,105 @@ +/* + * 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 iyes_loopless::state::NextState; + +use crate::{ + api::{ + self, + game::{types::GameState, ResponsePatchGameState}, + }, + cfg::{CfgDev, CfgUser}, + runtime::{ + game::RTDGame, + menu::{PlayMenuUIState, RTDMenu}, + }, +}; + +use super::{PlayMenuState, StartGameEvent}; + +struct StartGameCallResponse { + res: ResponsePatchGameState, +} + +#[derive(Component)] +pub(super) struct StartGameCall(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 game_id = rtdmenu.cur_game.as_ref().unwrap().id.clone(); + + let thread_pool = AsyncComputeTaskPool::get(); + let task = thread_pool.spawn(async move { + let patch_game_state_response = + api::game::patch_state(api_address, token, game_id, GameState::InProgress); + + StartGameCallResponse { + res: patch_game_state_response, + } + }); + commands.spawn(StartGameCall(task)); + rtdmenu.waiting_for_start_game_call = true; + } +} + +pub(super) fn handle( + mut commands: Commands, + mut start_game_call_tasks: Query<(Entity, &mut StartGameCall)>, + mut rtdmenu: ResMut, + mut rtdgame: ResMut, + mut console: EventWriter, +) { + if start_game_call_tasks.is_empty() { + return; + } + + let (entity, mut task) = start_game_call_tasks.single_mut(); + if let Some(start_game_call_response) = future::block_on(future::poll_once(&mut task.0)) { + rtdmenu.waiting_for_start_game_call = false; + match start_game_call_response.res { + ResponsePatchGameState::Valid(res) => { + rtdmenu.play_menu_ui_state = PlayMenuUIState::Main; + rtdgame.cur_game = Some(res); + commands.insert_resource(NextState(PlayMenuState::None)); + commands.insert_resource(NextState(crate::GameState::Game)); + + console.send(PrintConsoleLine::new( + format!( + "Started game with id: '{}'", + rtdmenu.cur_game.as_ref().unwrap().id + ) + .into(), + )); + } + ResponsePatchGameState::Error(error) => { + console.send(PrintConsoleLine::new( + format!("Starting game failed, 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/ui.rs b/sdbclient/src/plugins/menu/play/ui.rs index 5f8bed5..fcec568 100644 --- a/sdbclient/src/plugins/menu/play/ui.rs +++ b/sdbclient/src/plugins/menu/play/ui.rs @@ -17,7 +17,9 @@ use crate::{ runtime::menu::{BrowseMenuTab, PlayMenuUIState, RTDMenu}, }; -use super::{AllFormingEvent, CreateGameEvent, JoinGameEvent, MyGamesEvent, PlayMenuState}; +use super::{ + AllFormingEvent, CreateGameEvent, JoinGameEvent, MyGamesEvent, PlayMenuState, StartGameEvent, +}; pub(super) fn show( mut commands: Commands, @@ -28,6 +30,7 @@ pub(super) fn show( mut allforming_ev_w: EventWriter, mut joingame_ev_w: EventWriter, mut mygames_ev_w: EventWriter, + mut startgame_ev_w: EventWriter, ) { egui::Window::new(egui::RichText::new(rtdmenu.play_menu_ui_state.display()).size(32.)) .resizable(false) @@ -162,8 +165,7 @@ pub(super) fn show( } PlayMenuUIState::InLobbyHost => { if ui.button("Start").clicked() { - // patch state to "in-progress" - todo!(); + startgame_ev_w.send(StartGameEvent); } if ui.button("Back").clicked() { diff --git a/sdbclient/src/runtime/game/mod.rs b/sdbclient/src/runtime/game/mod.rs index cdafbd3..39cded4 100644 --- a/sdbclient/src/runtime/game/mod.rs +++ b/sdbclient/src/runtime/game/mod.rs @@ -8,12 +8,17 @@ use bevy::prelude::Resource; +use crate::api::game::types::Game; + /// Runtime data for use when in game #[derive(Resource)] -pub(crate) struct RTDGame {} +pub(crate) struct RTDGame { + /// Current game + pub cur_game: Option, +} impl Default for RTDGame { fn default() -> Self { - Self {} + Self { cur_game: None } } } diff --git a/sdbclient/src/runtime/menu/mod.rs b/sdbclient/src/runtime/menu/mod.rs index d28d45b..f8c0fc4 100644 --- a/sdbclient/src/runtime/menu/mod.rs +++ b/sdbclient/src/runtime/menu/mod.rs @@ -25,6 +25,7 @@ pub(crate) struct RTDMenu { /// Stores games where the player is involved pub my_games: Vec, pub waiting_for_my_games_call: bool, + pub waiting_for_start_game_call: bool, } impl Default for RTDMenu { @@ -39,6 +40,7 @@ impl Default for RTDMenu { waiting_for_join_game_call: false, my_games: vec![], waiting_for_my_games_call: false, + waiting_for_start_game_call: false, } } } -- 2.44.1