start to use user lifetime

This commit is contained in:
Adam 2024-08-01 23:47:28 -04:00
parent 8ee0c67301
commit d516f52c6f
6 changed files with 170 additions and 149 deletions

View file

@ -14,13 +14,6 @@ pub fn Browser() -> impl IntoView {
let fake_new_game_request = NewGameRequest {
name: String::from("Ligma"),
host: Player {
name: String::from("Adam"),
role: PlayerRole::Host,
white: vec![],
black: vec![],
},
packs: vec![0],
};
// Game stuff

View file

@ -1,115 +1,115 @@
use anyhow::Result;
use rand::prelude::IteratorRandom;
use rand::thread_rng;
use crate::models::*;
impl Game {
/// Build game decks from input data for game start.
/// This should only run once and at startup.
fn _build_decks(&mut self, cards_json: Vec<CardSet>) -> Result<()> {
for pack in cards_json {
if let Some(white) = pack.white {
self.white.extend(white)
}
if let Some(black) = pack.black {
self.black.extend(black)
}
}
Ok(())
}
pub fn new(request: NewGameRequest) -> Result<Self> {
let mut game = Game {
..Default::default()
};
tracing::debug!("Creating game {}", &request.name);
game.name = request.name;
// game.build_decks(request.packs)?;
game.create_player(request.host)?;
game.deal_black()?;
Ok(game)
}
// pub fn join(request:GameJoinRequest)
/// Log counts of current drawable cards
/// For testing
pub fn deck_counts(&self) {
tracing::debug!(
"Deck Counts:\n {} White cards\n {} Black cards",
self.white.len(),
self.black.len()
);
}
/// Draw one white card at random from play deck.
fn draw_one_white(&mut self) -> Result<CardWhite> {
let deck = &mut self.white;
// this feels sloppy
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
Ok(deck.swap_remove(index))
} else {
Ok(CardWhite {
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
pack: 0,
})
}
}
/// Draw one black card at random from play deck.
fn draw_one_black(&mut self) -> Result<CardBlack> {
let deck = &mut self.black;
// this feels sloppy
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
Ok(deck.swap_remove(index))
} else {
Ok(CardBlack {
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
pick: 0,
pack: 0,
})
}
}
/// Deal a black card and use it for the current round
fn deal_black(&mut self) -> Result<()> {
self.current_black = Some(self.draw_one_black()?);
Ok(())
}
/// Create a new player and add them to the game.
pub fn create_player(&mut self, mut player: Player) -> Result<()> {
tracing::debug!("Creating player {} as {:?}", &player.name, &player.role);
let mut hand_buf = vec![];
for _ in 0..10 {
hand_buf.push(self.draw_one_white()?);
}
tracing::debug!("Dealing hand to {}", &player.name);
player.white.extend(hand_buf);
self.players.push(player);
Ok(())
}
pub fn game_start(&mut self) -> Result<()> {
self.game_active = true;
tracing::debug!("Game Active!");
if let Some(black) = &self.current_black {
tracing::debug!("{}", black.text);
} else {
tracing::debug!("YOU DONE FUCKED UP (no current black card)");
}
Ok(())
}
}
// use anyhow::Result;
// use rand::prelude::IteratorRandom;
// use rand::thread_rng;
//
// use crate::models::*;
//
// impl Game {
// /// Build game decks from input data for game start.
// /// This should only run once and at startup.
// fn _build_decks(&mut self, cards_json: Vec<CardSet>) -> Result<()> {
// for pack in cards_json {
// if let Some(white) = pack.white {
// self.white.extend(white)
// }
// if let Some(black) = pack.black {
// self.black.extend(black)
// }
// }
//
// Ok(())
// }
//
// pub fn new(request: NewGameRequest) -> Result<Self> {
// let mut game = Game {
// ..Default::default()
// };
// tracing::debug!("Creating game {}", &request.name);
// game.name = request.name;
//
// // game.build_decks(request.packs)?;
// game.create_player(request.host)?;
// game.deal_black()?;
//
// Ok(game)
// }
//
// // pub fn join(request:GameJoinRequest)
//
// /// Log counts of current drawable cards
// /// For testing
// pub fn deck_counts(&self) {
// tracing::debug!(
// "Deck Counts:\n {} White cards\n {} Black cards",
// self.white.len(),
// self.black.len()
// );
// }
//
// /// Draw one white card at random from play deck.
// fn draw_one_white(&mut self) -> Result<CardWhite> {
// let deck = &mut self.white;
//
// // this feels sloppy
// if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
// Ok(deck.swap_remove(index))
// } else {
// Ok(CardWhite {
// text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
// pack: 0,
// })
// }
// }
//
// /// Draw one black card at random from play deck.
// fn draw_one_black(&mut self) -> Result<CardBlack> {
// let deck = &mut self.black;
//
// // this feels sloppy
// if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
// Ok(deck.swap_remove(index))
// } else {
// Ok(CardBlack {
// text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
// pick: 0,
// pack: 0,
// })
// }
// }
//
// /// Deal a black card and use it for the current round
// fn deal_black(&mut self) -> Result<()> {
// self.current_black = Some(self.draw_one_black()?);
//
// Ok(())
// }
//
// /// Create a new player and add them to the game.
// pub fn create_player(&mut self, mut player: Player) -> Result<()> {
// tracing::debug!("Creating player {} as {:?}", &player.name, &player.role);
//
// let mut hand_buf = vec![];
// for _ in 0..10 {
// hand_buf.push(self.draw_one_white()?);
// }
// tracing::debug!("Dealing hand to {}", &player.name);
// player.white.extend(hand_buf);
//
// self.players.push(player);
//
// Ok(())
// }
//
// pub fn game_start(&mut self) -> Result<()> {
// self.game_active = true;
// tracing::debug!("Game Active!");
//
// if let Some(black) = &self.current_black {
// tracing::debug!("{}", black.text);
// } else {
// tracing::debug!("YOU DONE FUCKED UP (no current black card)");
// }
//
// Ok(())
// }
// }

View file

@ -55,10 +55,16 @@ impl User {
pub struct NewGameRequest {
/// Game name
pub name: String,
}
/// New game request structure
use std::pin::Pin;
#[derive(Debug)]
pub struct NewGameManifest<'user> {
/// Game name
pub name: String,
/// Game host
pub host: Player,
/// Chosen packs
pub packs: Vec<u8>,
pub host: &'user Pin<Box<User>>,
}
/// Game join request structure

View file

@ -109,8 +109,14 @@ async fn handle_new_user(
// Register using `addr` as key until something longer lived exists
state.online_users.lock().unwrap().insert(*addr, new_user);
tracing::debug!("New user inserted at ptr: {:p}", state.online_users.lock().unwrap().get(addr).unwrap());
tracing::debug!("New user hashmap deref ptr: {:p}", *state.online_users.lock().unwrap().get(addr).unwrap());
tracing::debug!(
"New user inserted at ptr: {:p}",
state.online_users.lock().unwrap().get(addr).unwrap()
);
tracing::debug!(
"New user hashmap deref ptr: {:p}",
*state.online_users.lock().unwrap().get(addr).unwrap()
);
// Hydrate client
// this should probably be combined and sent as one
@ -128,7 +134,11 @@ async fn handle_new_user(
}
/// This runs right after a WebSocket connection is established
pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, addr: SocketAddr) {
pub async fn on_websocket_connection(
stream: WebSocket,
state: Arc<AppState>,
addr: SocketAddr,
) {
// Split channels to send and receive asynchronously.
let (mut sender, mut receiver) = stream.split();
@ -151,7 +161,7 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, ad
// Pass messages from broadcast down to this client
let mut recv_task = tokio::spawn(async move {
while let Some(Ok(message)) = receiver.next().await {
message_handler(&state, addr, message)
message_handler(state.clone(), addr, message)
.await
.expect("Message Handler exploded!")
}

View file

@ -11,23 +11,33 @@ fn handle_new_game(
new_game: NewGameRequest,
state: &Arc<AppState>,
tx: &Sender<String>,
addr: SocketAddr,
) -> Result<()> {
// create game
if let Ok(new_game_object) = Game::new(new_game) {
if let Ok(game_json) = to_string(&new_game_object) {
tracing::debug!("Sent new game JSON.");
// this is a broadcast
// change this
tx.send(game_json)?;
} else {
// change this
tracing::error!("Failed to convert Game object to JSON.")
}
let binding = state.online_users.lock().unwrap();
let user = binding.get(&addr).unwrap();
state.games.lock().unwrap().push(new_game_object);
tx.send(games_update(state))?;
tx.send(server_summary_update(state))?;
}
tracing::debug!("{:#?} from {}", new_game, user.name);
let manifest = NewGameManifest {
name: new_game.name,
host: user,
};
// create game
// if let Ok(new_game_object) = Game::new(new_game) {
// if let Ok(game_json) = to_string(&new_game_object) {
// tracing::debug!("Sent new game JSON.");
// // this is a broadcast
// // change this
// tx.send(game_json)?;
// } else {
// // change this
// tracing::error!("Failed to convert Game object to JSON.")
// }
//
// state.games.lock().unwrap().push(new_game_object);
// tx.send(games_update(state))?;
// tx.send(server_summary_update(state))?;
// }
Ok(())
}
@ -179,7 +189,7 @@ fn handle_close(
/// Handle incoming messages over the WebSocket
pub async fn message_handler(
state: &Arc<AppState>,
state: Arc<AppState>,
addr: SocketAddr,
message: Message,
) -> Result<()> {
@ -189,13 +199,13 @@ pub async fn message_handler(
Message::Text(text) => match text {
_new_game if let Ok(_new_game) = from_str::<NewGameRequest>(&text) => {
tracing::debug!("New game request received.");
handle_new_game(_new_game, state, tx)?;
handle_new_game(_new_game, &state, tx, addr)?;
}
_chat_message if let Ok(_chat_message) = from_str::<ChatMessage>(&text) => {
handle_chat_message(_chat_message, state, tx, addr)?;
handle_chat_message(_chat_message, &state, tx, addr)?;
}
_user_log_in if let Ok(_user_log_in) = from_str::<UserLogIn>(&text) => {
handle_user_log_in(_user_log_in, state, tx, addr)?;
handle_user_log_in(_user_log_in, &state, tx, addr)?;
}
_ => {
tracing::debug!("Unhandled text message: {}", &text);
@ -205,7 +215,7 @@ pub async fn message_handler(
tracing::debug!("Binary: {:?}", data)
}
Message::Close(close_frame) => {
handle_close(close_frame, state, tx, addr)?;
handle_close(close_frame, &state, tx, addr)?;
}
Message::Pong(ping) => {
tracing::debug!("Pong received with: {:?}", ping);

View file

@ -52,6 +52,7 @@ pub struct AppState {
all_cards: Vec<CardSet>,
// Games list
games: Mutex<Vec<Game>>,
// chatrooms: Mutex<HashMap<String, ChatRoom<'user>>>,
first_names: Vec<String>,
last_names: Vec<String>,
}
@ -68,6 +69,7 @@ async fn main() -> Result<()> {
.init();
// Set up application state for use with with_state().
// Main Broadcast Channel
let (tx, _rx) = broadcast::channel(100);
let online_users = Mutex::new(HashMap::<SocketAddr, Pin<Box<User>>>::new());
let offline_users = Mutex::new(HashMap::<String, Pin<Box<User>>>::new());