refactor message handling to drive state transitions

This commit is contained in:
Joey Hines 2025-05-17 11:04:26 -06:00
parent d9d7325e04
commit fee5576efd
Signed by: joeyahines
GPG Key ID: 38BA6F25C94C9382
6 changed files with 24 additions and 43 deletions

View File

@ -149,7 +149,7 @@ fn handle_client_msg(
let token = bit_array.base64_encode(token, True) let token = bit_array.base64_encode(token, True)
web.JoinResponse(token, username) web.JoinResponse(username, token)
} }
} }
} }

View File

@ -42,11 +42,6 @@ impl Context {
ewebsock::WsMessage::Text(msg) => { ewebsock::WsMessage::Text(msg) => {
let game_resp: GameResponse = serde_json::from_str(&msg).unwrap(); let game_resp: GameResponse = serde_json::from_str(&msg).unwrap();
if let GameResponse::JoinResponse { username, token } = &game_resp {
self.username = username.clone();
self.token = token.clone();
}
Some(game_resp) Some(game_resp)
} }
_ => None, _ => None,

View File

@ -16,7 +16,7 @@ pub struct LoginScreen {
} }
impl Screen for LoginScreen { impl Screen for LoginScreen {
fn handle_frame(&mut self, ctx: &mut Context) -> Option<StateTransition> { fn handle_frame(&mut self, ctx: &mut Context) {
clear_background(WHITE); clear_background(WHITE);
let group_size = Vec2::new(screen_width() * 0.25, screen_height() * 0.05); let group_size = Vec2::new(screen_width() * 0.25, screen_height() * 0.05);
@ -64,12 +64,16 @@ impl Screen for LoginScreen {
self.sent_join = true; self.sent_join = true;
} }
}
fn handle_messages(&mut self, ctx: &mut Context) -> Option<StateTransition> {
if self.sent_join { if self.sent_join {
let msg = ctx.recv_msg(); let msg = ctx.recv_msg();
if let Some(GameResponse::JoinResponse { username, token }) = msg { if let Some(GameResponse::JoinResponse { username, token }) = msg {
return Some(StateTransition::JoinAsPlayer { username, token }); ctx.username = username;
ctx.token = token;
return Some(StateTransition::JoinAsPlayer);
} }
self.retry_count += 1; self.retry_count += 1;
@ -84,8 +88,4 @@ impl Screen for LoginScreen {
None None
} }
fn handle_messages(&mut self, ctx: &mut Context) {
// do nothing
}
} }

View File

@ -22,23 +22,21 @@ impl State {
StateTransition::Init | StateTransition::LeaveGame => { StateTransition::Init | StateTransition::LeaveGame => {
Self::Login(LoginScreen::default()) Self::Login(LoginScreen::default())
} }
StateTransition::JoinAsPlayer { username, token } => { StateTransition::JoinAsPlayer => Self::PlayerScreen(PlayerScreen::default()),
Self::PlayerScreen(PlayerScreen::new(&username, &token))
}
} }
} }
pub fn handle_frame(&mut self, ctx: &mut Context) -> Option<StateTransition> { pub fn handle_frame(&mut self, ctx: &mut Context) {
match self { match self {
Self::Init => Some(StateTransition::Init), Self::Init => {}
Self::Login(login_screen) => login_screen.handle_frame(ctx), Self::Login(login_screen) => login_screen.handle_frame(ctx),
Self::PlayerScreen(player_screen) => player_screen.handle_frame(ctx), Self::PlayerScreen(player_screen) => player_screen.handle_frame(ctx),
} }
} }
pub fn handle_messages(&mut self, ctx: &mut Context) { pub fn handle_messages(&mut self, ctx: &mut Context) -> Option<StateTransition> {
match self { match self {
Self::Init => {} Self::Init => Some(StateTransition::Init),
State::Login(login_screen) => login_screen.handle_messages(ctx), State::Login(login_screen) => login_screen.handle_messages(ctx),
State::PlayerScreen(player_screen) => player_screen.handle_messages(ctx), State::PlayerScreen(player_screen) => player_screen.handle_messages(ctx),
} }
@ -47,7 +45,7 @@ impl State {
pub enum StateTransition { pub enum StateTransition {
Init, Init,
JoinAsPlayer { username: String, token: String }, JoinAsPlayer,
LeaveGame, LeaveGame,
} }
@ -59,11 +57,12 @@ async fn main() {
state.transition_state(StateTransition::Init); state.transition_state(StateTransition::Init);
loop { loop {
state.handle_messages(&mut context); if let Some(transition) = state.handle_messages(&mut context) {
if let Some(transition) = state.handle_frame(&mut context) {
state = state.transition_state(transition); state = state.transition_state(transition);
} }
state.handle_frame(&mut context);
next_frame().await next_frame().await
} }
} }

View File

@ -7,26 +7,14 @@ use crate::model::buzz_in::BuzzIn;
use crate::screen::Screen; use crate::screen::Screen;
use macroquad::prelude::*; use macroquad::prelude::*;
#[derive(Default)]
pub struct PlayerScreen { pub struct PlayerScreen {
token: String,
username: String,
score: i32, score: i32,
button_pressed: bool, button_pressed: bool,
} }
impl PlayerScreen {
pub fn new(token: &str, username: &str) -> Self {
Self {
token: token.to_string(),
username: username.to_string(),
score: 0,
button_pressed: false,
}
}
}
impl Screen for PlayerScreen { impl Screen for PlayerScreen {
fn handle_messages(&mut self, ctx: &mut Context) { fn handle_messages(&mut self, ctx: &mut Context) -> Option<StateTransition> {
let msg = ctx.recv_msg(); let msg = ctx.recv_msg();
if let Some(msg) = msg { if let Some(msg) = msg {
@ -46,9 +34,11 @@ impl Screen for PlayerScreen {
} }
} }
} }
None
} }
fn handle_frame(&mut self, ctx: &mut Context) -> Option<StateTransition> { fn handle_frame(&mut self, ctx: &mut Context) {
clear_background(BEIGE); clear_background(BEIGE);
let button_color = if self.button_pressed { let button_color = if self.button_pressed {
@ -95,7 +85,5 @@ impl Screen for PlayerScreen {
ctx.send_msg(&ClientMessage::BuzzIn(buzz_in)); ctx.send_msg(&ClientMessage::BuzzIn(buzz_in));
} }
} }
None
} }
} }

View File

@ -1,7 +1,6 @@
use crate::{StateTransition, context::Context}; use crate::{StateTransition, context::Context};
pub trait Screen { pub trait Screen {
fn init_frame(&mut self) {} fn handle_frame(&mut self, ctx: &mut Context);
fn handle_frame(&mut self, ctx: &mut Context) -> Option<StateTransition>; fn handle_messages(&mut self, ctx: &mut Context) -> Option<StateTransition>;
fn handle_messages(&mut self, ctx: &mut Context);
} }