let game_handler own user_id to game_id lookup table

This commit is contained in:
Adam 2024-12-11 23:20:44 -05:00
parent 51bf21a287
commit a70050fdbd
4 changed files with 36 additions and 59 deletions

View file

@ -20,6 +20,7 @@ pub enum GameHandlerMessage {
DeleteGame(GameDeleteRequest),
SendGameStateUpdate(Vec<String>),
SendGameMetaUpdate(Vec<String>),
SendGameUserUpdate(String),
BroadcastGamesUpdate(),
SendCardPacks(Sender<Message>),
}
@ -31,6 +32,7 @@ pub struct GameHandler {
games: HashMap<String, Game>,
packs: CardPacks,
packs_meta: CardPacksMeta,
game_id_by_user_id: HashMap<String, Vec<String>>,
}
impl GameHandler {
@ -38,11 +40,14 @@ impl GameHandler {
pub fn new(state: Arc<AppState>) -> Self {
let games = HashMap::new();
let (packs, packs_meta) = card_loader("data/cah-cards-full.json").unwrap();
let game_id_by_user_id = HashMap::<String, Vec<String>>::new();
GameHandler {
state,
games,
packs,
packs_meta,
game_id_by_user_id,
}
}
@ -56,6 +61,7 @@ impl GameHandler {
DeleteGame(request) => self.delete_game(request).await,
SendGameStateUpdate(game_ids) => self.send_game_state_update_all(game_ids),
SendGameMetaUpdate(game_ids) => self.send_game_meta_update(game_ids),
SendGameUserUpdate(user_id) => self.send_game_user_update(user_id),
BroadcastGamesUpdate() => self.broadcast_game_browser_update(),
SendCardPacks(tx) => self.send_card_packs(tx).await,
}
@ -139,37 +145,6 @@ impl GameHandler {
self.send_game_meta_update(vec![request.game_id]);
}
// Ties game ids to user for easier lookup
fn register_user_in_game(&self, game_id: String, user_id: String) {
if !self
.state
.games_by_user
.read()
.unwrap()
.contains_key(&user_id)
{
self.state
.games_by_user
.write()
.unwrap()
.insert(user_id, vec![game_id]);
} else if self
.state
.games_by_user
.read()
.unwrap()
.contains_key(&user_id)
{
self.state
.games_by_user
.write()
.unwrap()
.get_mut(&user_id)
.unwrap()
.extend(vec![game_id]);
}
}
/// Puts a user in a game
async fn join_game(&mut self, game_id: String, addr: SocketAddr) {
if self.games.contains_key(&game_id) {
@ -177,7 +152,15 @@ impl GameHandler {
let this_user_id = this_user.read().unwrap().uuid.clone();
// Register game to user
self.register_user_in_game(game_id.clone(), this_user_id.clone());
if !self.game_id_by_user_id.contains_key(&this_user_id) {
self.game_id_by_user_id
.insert(this_user_id.clone(), vec![game_id.clone()]);
} else if self.game_id_by_user_id.contains_key(&this_user_id) {
self.game_id_by_user_id
.get_mut(&this_user_id)
.unwrap()
.extend(vec![game_id.clone()]);
}
// Create player
self.games
@ -256,6 +239,14 @@ impl GameHandler {
}
}
/// Send game meta update for all players of a game
fn send_game_user_update(&self, user_id: String) {
if self.game_id_by_user_id.contains_key(&user_id) {
let game_ids = self.game_id_by_user_id.get(&user_id).unwrap().to_vec();
self.send_game_meta_update(game_ids);
}
}
/// Send game state update for all players of a game
fn send_game_state_update_all(&self, game_ids: Vec<String>) {
for game_id in game_ids {
@ -376,7 +367,16 @@ impl GameHandler {
.insert(new_game_object.uuid.to_string(), new_game_object);
// Register game to user
self.register_user_in_game(game_id.clone(), host.read().unwrap().uuid.clone());
let user_id = host.read().unwrap().uuid.clone();
if !self.game_id_by_user_id.contains_key(&user_id) {
self.game_id_by_user_id
.insert(user_id.clone(), vec![game_id.clone()]);
} else if self.game_id_by_user_id.contains_key(&user_id) {
self.game_id_by_user_id
.get_mut(&user_id)
.unwrap()
.extend(vec![game_id.clone()]);
}
self.send_game_state_update_all(vec![game_id.clone()]);
self.send_game_meta_update(vec![game_id]);

View file

@ -46,7 +46,6 @@ impl User {
/// Shared state
pub struct AppState {
pub games_by_user: RwLock<HashMap<String, Vec<String>>>,
pub offline_users: RwLock<HashMap<String, Arc<RwLock<User>>>>,
pub online_users: RwLock<HashMap<SocketAddr, Arc<RwLock<User>>>>,
pub tx_broadcast: tokio::sync::broadcast::Sender<Message>,

View file

@ -82,12 +82,10 @@ async fn main() -> Result<()> {
let (tx_incoming_message_handler, mut rx_incoming_message_handler) = mpsc::channel(32);
let (tx_outgoing_message_handler, mut rx_outgoing_message_handler) = mpsc::channel(32);
let (tx_user_handler, mut rx_user_handler) = mpsc::channel(32);
let games_by_user = RwLock::new(HashMap::<String, Vec<String>>::new());
let offline_users = RwLock::new(HashMap::<String, Arc<RwLock<User>>>::new());
let online_users = RwLock::new(HashMap::<SocketAddr, Arc<RwLock<User>>>::new());
let app_state = Arc::new(AppState {
games_by_user,
offline_users,
online_users,
tx_broadcast: tx_broadcast.clone(),

View file

@ -332,31 +332,11 @@ impl UserHandler {
)
.await;
// Update games this user is in
// TODO: game handler maybe should own games_by_user
if let Some(user) = &self.state.online_users.read().unwrap().get(&addr) {
let user_id = user.read().unwrap().uuid.to_string();
{
if self
.state
.games_by_user
.read()
.unwrap()
.contains_key(&user_id)
{
let msg = GameHandlerMessage::SendGameMetaUpdate(
self.state
.games_by_user
.read()
.unwrap()
.get(&user_id)
.unwrap()
.to_vec(),
);
let tx = self.state.tx_game_handler.clone();
tokio::spawn(async move { tx.send(msg).await });
}
}
let msg = GameHandlerMessage::SendGameUserUpdate(user_id);
let tx = self.state.tx_game_handler.clone();
tokio::spawn(async move { tx.send(msg).await });
}
// Send client updates
let tx = self.state.tx_game_handler.clone();