session handling for players and hosts

This commit is contained in:
2025-05-17 12:23:19 -06:00
parent fee5576efd
commit b6a4936247
11 changed files with 221 additions and 28 deletions
+31
View File
@@ -0,0 +1,31 @@
use macroquad::{
color::{BLACK, WHITE},
text::draw_text,
window::{clear_background, screen_height, screen_width},
};
use crate::screen::Screen;
#[derive(Default)]
pub struct HostScreen {}
impl Screen for HostScreen {
fn handle_frame(&mut self, _ctx: &mut crate::context::Context) {
clear_background(WHITE);
draw_text(
"I'm the host!",
screen_width() / 2.0,
screen_height() / 2.0,
100.0,
BLACK,
);
}
fn handle_messages(
&mut self,
_ctx: &mut crate::context::Context,
) -> Option<crate::StateTransition> {
None
}
}
+39 -5
View File
@@ -11,6 +11,7 @@ pub struct LoginScreen {
new_username: String,
new_room_code: String,
sent_join: bool,
sent_host: bool,
retry_count: usize,
error_msg: bool,
}
@@ -23,6 +24,8 @@ impl Screen for LoginScreen {
let window_size = Vec2::new(screen_width() * 0.25, screen_height() * 0.25);
let mut pressed_join = false;
let mut pressed_host = false;
root_ui().window(
hash!("Window"),
Vec2::new(
@@ -47,6 +50,16 @@ impl Screen for LoginScreen {
pressed_join = true;
}
});
ui.group(hash!("Host Group"), group_size, |ui| {
if ui.button(Vec2::new(group_size.x * 0.45, 0.0), "Host Game") {
info!(
"User pressed host with name={} room_code={}",
self.new_username, self.new_room_code
);
pressed_host = true;
}
});
if self.error_msg {
ui.group(hash!("Error Group"), group_size, |ui| {
@@ -64,16 +77,37 @@ impl Screen for LoginScreen {
self.sent_join = true;
}
if pressed_host {
ctx.send_msg(&ClientMessage::CreateRoom(Register {
game_code: self.new_room_code.clone(),
username: self.new_username.clone(),
}));
self.sent_host = true;
}
}
fn handle_messages(&mut self, ctx: &mut Context) -> Option<StateTransition> {
if self.sent_join {
if self.sent_join || self.sent_host {
let msg = ctx.recv_msg();
if let Some(GameResponse::JoinResponse { username, token }) = msg {
ctx.username = username;
ctx.token = token;
return Some(StateTransition::JoinAsPlayer);
if let Some(msg) = msg {
match msg {
GameResponse::JoinResponse { username, token } => {
ctx.username = username;
ctx.token = token;
return Some(StateTransition::JoinAsPlayer);
}
GameResponse::HostResponse { username, token } => {
ctx.username = username;
ctx.token = token;
return Some(StateTransition::JoinAsHost);
}
_ => {
warn!("Got unexpected message: {:?}", msg)
}
}
}
self.retry_count += 1;
+9
View File
@@ -1,10 +1,12 @@
use context::Context;
use host_screen::HostScreen;
use login_screen::LoginScreen;
use macroquad::prelude::*;
use player_screen::PlayerScreen;
use screen::Screen;
mod context;
mod host_screen;
mod login_screen;
mod model;
mod player_screen;
@@ -14,15 +16,18 @@ pub enum State {
Init,
Login(LoginScreen),
PlayerScreen(PlayerScreen),
HostScreen(HostScreen),
}
impl State {
pub fn transition_state(&self, transition: StateTransition) -> Self {
info!("Applying transition: {:?}", transition);
match transition {
StateTransition::Init | StateTransition::LeaveGame => {
Self::Login(LoginScreen::default())
}
StateTransition::JoinAsPlayer => Self::PlayerScreen(PlayerScreen::default()),
StateTransition::JoinAsHost => Self::HostScreen(HostScreen::default()),
}
}
@@ -31,6 +36,7 @@ impl State {
Self::Init => {}
Self::Login(login_screen) => login_screen.handle_frame(ctx),
Self::PlayerScreen(player_screen) => player_screen.handle_frame(ctx),
State::HostScreen(host_screen) => host_screen.handle_frame(ctx),
}
}
@@ -39,13 +45,16 @@ impl State {
Self::Init => Some(StateTransition::Init),
State::Login(login_screen) => login_screen.handle_messages(ctx),
State::PlayerScreen(player_screen) => player_screen.handle_messages(ctx),
State::HostScreen(host_screen) => host_screen.handle_messages(ctx),
}
}
}
#[derive(Debug)]
pub enum StateTransition {
Init,
JoinAsPlayer,
JoinAsHost,
LeaveGame,
}
+3 -1
View File
@@ -10,6 +10,7 @@ pub mod register;
pub enum ClientMessage {
BuzzIn(BuzzIn),
Register(Register),
CreateRoom(Register),
}
#[derive(Debug, Serialize)]
@@ -22,7 +23,8 @@ pub struct ClientRequest {
#[serde(tag = "type")]
pub enum GameResponse {
JoinResponse { username: String, token: String },
HostResponse { username: String, token: String },
AckBuzzer,
ResetBuzzer,
UpdatePountTotal { score: i32 },
UpdatePointTotal { score: i32 },
}
+2 -1
View File
@@ -28,10 +28,11 @@ impl Screen for PlayerScreen {
info!("Button press reset");
self.button_pressed = false;
}
crate::model::GameResponse::UpdatePountTotal { score } => {
crate::model::GameResponse::UpdatePointTotal { score } => {
info!("Score updated to: {}", score);
self.score = score;
}
_ => {}
}
}