diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index 39173f2..1c0e955 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -99,8 +99,8 @@ impl GameManager { if let Some(mut game) = self.game.take() { game.bind_mut().finish_game(); game.queue_free(); + self.go_to_main_menu(); } - self.go_to_main_menu(); } pub fn go_to_finish_screen(&self) { diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 2b4bafb..300247c 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -10,6 +10,7 @@ pub mod map_resource; pub mod net; pub mod player; pub mod player_hand_remover; +pub mod popup_queue; pub mod soldier_mesh; pub mod team_resource; pub mod ui; diff --git a/rust/src/popup_queue.rs b/rust/src/popup_queue.rs new file mode 100644 index 0000000..635140c --- /dev/null +++ b/rust/src/popup_queue.rs @@ -0,0 +1,27 @@ +use std::collections::VecDeque; + +use godot::prelude::*; + +pub struct Popup { + pub title: String, + pub message: String, + pub ok: bool, +} + +#[derive(GodotClass)] +#[class(base=Node, init, singleton)] +pub struct PopupQueue { + popups: VecDeque, + + base: Base, +} + +impl PopupQueue { + pub fn queue(&mut self, popup: Popup) { + self.popups.push_back(popup); + } + + pub fn poll(&mut self) -> Option { + self.popups.pop_front() + } +} diff --git a/rust/src/ui/main_menu.rs b/rust/src/ui/main_menu.rs index f652b36..8f2d5f7 100644 --- a/rust/src/ui/main_menu.rs +++ b/rust/src/ui/main_menu.rs @@ -4,7 +4,10 @@ use godot::{ register::property::SimpleVar, }; -use crate::net::network_manager::NetworkManager; +use crate::{ + net::network_manager::NetworkManager, + popup_queue::{Popup, PopupQueue}, +}; #[derive(Debug, Clone, GodotConvert, Default, Export)] #[godot(via = u8)] @@ -66,19 +69,31 @@ impl INode3D for MainMenu { .bind_mut() .signals() .on_client_disconnected() - .connect_other(self, |s, msg| { + .connect_other(self, |_, msg| { if msg.is_empty() { - s.show_popup("Disconnected", "disconnected", true); + PopupQueue::singleton().bind_mut().queue(Popup { + title: "Disconnected".to_owned(), + message: "disconnected".to_owned(), + ok: true, + }); } else { - s.show_popup("Error", &msg.to_string(), true); + PopupQueue::singleton().bind_mut().queue(Popup { + title: "Error".to_owned(), + message: msg.to_string(), + ok: true, + }); } }); NetworkManager::singleton() .bind_mut() .signals() .on_error_hosting_server() - .connect_other(self, |s, msg| { - s.show_popup("Error Hosting Server", &msg.to_string(), true); + .connect_other(self, |_, msg| { + PopupQueue::singleton().bind_mut().queue(Popup { + title: "Error hosting server".to_owned(), + message: msg.to_string(), + ok: true, + }); }); } @@ -139,6 +154,16 @@ impl INode3D for MainMenu { } } } + + if let Some(popup_panel) = self.popup_panel.clone() + && let Some(button) = self.popup_button.clone() + { + if !popup_panel.is_visible() || !button.is_visible() { + if let Some(popup) = PopupQueue::singleton().bind_mut().poll() { + self.show_popup(&popup.title, &popup.message, popup.ok); + } + } + } } } @@ -157,12 +182,21 @@ impl MainMenu { pub fn join_game(&mut self) { if let Some(addr) = self.join_addr.clone() { self.show_popup("Joining", "joining game", false); + PopupQueue::singleton().bind_mut().queue(Popup { + title: "Joining".to_owned(), + message: "joining game".to_owned(), + ok: false, + }); match addr.get_text().to_string().parse() { Ok(addr) => { NetworkManager::singleton().bind_mut().join(addr); } Err(err) => { - self.show_popup("Error", &format!("Error joining: {}", err), true); + PopupQueue::singleton().bind_mut().queue(Popup { + title: "Error".to_owned(), + message: format!("Error joining: {}", err), + ok: true, + }); } } }