Skip to content

Commit 0ab13d2

Browse files
committed
refactor: move game snapshot logic
1 parent 0b0b776 commit 0ab13d2

4 files changed

Lines changed: 83 additions & 70 deletions

File tree

src/routes/games.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
config::Config,
33
database::entities::players::PlayerRole,
44
middleware::auth::MaybeAuth,
5-
services::game::{store::Games, GameSnapshot},
5+
services::game::{snapshot::GameSnapshot, store::Games},
66
utils::types::GameID,
77
};
88
use axum::{
@@ -110,7 +110,7 @@ pub async fn get_game(
110110
let include_players = auth.is_some() || !config.api.public_games_hide_players;
111111

112112
let game = games.get_by_id(game_id).ok_or(GamesError::NotFound)?;
113-
let snapshot = game.read().snapshot(include_net, include_players);
113+
let snapshot = GameSnapshot::new(&game.read(), include_net, include_players);
114114

115115
Ok(Json(snapshot))
116116
}

src/services/game/mod.rs

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use crate::{
2727
use chrono::{DateTime, Utc};
2828
use log::{debug, warn};
2929
use parking_lot::RwLock;
30-
use serde::Serialize;
3130
use std::sync::{Arc, Weak};
3231
use store::Games;
3332
use tdf::{ObjectId, TdfMap, TdfSerializer};
@@ -36,6 +35,7 @@ use super::tunnel::TunnelService;
3635

3736
pub mod matchmaking;
3837
pub mod rules;
38+
pub mod snapshot;
3939
pub mod store;
4040

4141
pub type GameRef = Arc<RwLock<Game>>;
@@ -101,25 +101,6 @@ pub struct Game {
101101
pub tunnel_service: Arc<TunnelService>,
102102
}
103103

104-
/// Snapshot of the current game state and players
105-
#[derive(Serialize)]
106-
pub struct GameSnapshot {
107-
/// The ID of the game the snapshot is for
108-
pub id: GameID,
109-
/// The current game state
110-
pub state: GameState,
111-
/// The current game setting
112-
pub setting: u16,
113-
/// The game attributes
114-
pub attributes: AttrMap,
115-
/// Snapshots of the game players
116-
pub players: Option<Box<[GamePlayerSnapshot]>>,
117-
/// The total number of players in the game
118-
pub total_players: usize,
119-
/// When the game was created
120-
pub created_at: DateTime<Utc>,
121-
}
122-
123104
/// Attributes map type
124105
pub type AttrMap = TdfMap<String, String>;
125106

@@ -134,18 +115,6 @@ pub struct GamePlayer {
134115
pub state: PlayerState,
135116
}
136117

137-
/// Structure for taking a snapshot of the players current
138-
/// state.
139-
#[derive(Serialize)]
140-
pub struct GamePlayerSnapshot {
141-
/// The player ID of the snapshot
142-
pub player_id: PlayerID,
143-
/// The player name of the snapshot
144-
pub display_name: Box<str>,
145-
/// The player net data of the snapshot if collected
146-
pub net: Option<Arc<NetData>>,
147-
}
148-
149118
impl GamePlayer {
150119
/// Creates a new game player structure with the provided player
151120
/// details
@@ -202,16 +171,6 @@ impl GamePlayer {
202171
session.tx.notify(packet)
203172
}
204173

205-
/// Takes a snapshot of the current player state
206-
/// for serialization
207-
pub fn snapshot(&self, include_net: bool) -> GamePlayerSnapshot {
208-
GamePlayerSnapshot {
209-
player_id: self.player.id,
210-
display_name: Box::from(self.player.display_name.as_ref()),
211-
net: if include_net { self.net() } else { None },
212-
}
213-
}
214-
215174
pub fn encode<S: TdfSerializer>(&self, game_id: GameID, slot: usize, w: &mut S) {
216175
w.group_body(|w| {
217176
// Custom data
@@ -467,30 +426,6 @@ impl Game {
467426
GameJoinableState::Joinable
468427
}
469428

470-
pub fn snapshot(&self, include_net: bool, include_players: bool) -> GameSnapshot {
471-
let total_players: usize = self.players.len();
472-
let players = if include_players {
473-
let players = self
474-
.players
475-
.iter()
476-
.map(|value| value.snapshot(include_net))
477-
.collect();
478-
Some(players)
479-
} else {
480-
None
481-
};
482-
483-
GameSnapshot {
484-
id: self.id,
485-
state: self.state,
486-
setting: self.settings.bits(),
487-
attributes: self.attributes.clone(),
488-
players,
489-
total_players,
490-
created_at: self.created_at,
491-
}
492-
}
493-
494429
/// Writes the provided packet to all connected sessions.
495430
/// Does not wait for the write to complete just waits for
496431
/// it to be placed into each sessions write buffers.

src/services/game/snapshot.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use std::sync::Arc;
2+
3+
use chrono::{DateTime, Utc};
4+
use serde::Serialize;
5+
6+
use crate::{
7+
session::{data::NetData, models::game_manager::GameState},
8+
utils::types::{GameID, PlayerID},
9+
};
10+
11+
use super::{AttrMap, Game, GamePlayer};
12+
13+
/// Snapshot of the current game state and players
14+
#[derive(Serialize)]
15+
pub struct GameSnapshot {
16+
/// The ID of the game the snapshot is for
17+
pub id: GameID,
18+
/// The current game state
19+
pub state: GameState,
20+
/// The current game setting
21+
pub setting: u16,
22+
/// The game attributes
23+
pub attributes: AttrMap,
24+
/// Snapshots of the game players
25+
pub players: Option<Box<[GamePlayerSnapshot]>>,
26+
/// The total number of players in the game
27+
pub total_players: usize,
28+
/// When the game was created
29+
pub created_at: DateTime<Utc>,
30+
}
31+
32+
impl GameSnapshot {
33+
pub fn new(game: &Game, include_net: bool, include_players: bool) -> Self {
34+
let total_players: usize = game.players.len();
35+
let players = if include_players {
36+
let players = game
37+
.players
38+
.iter()
39+
.map(|value| GamePlayerSnapshot::new(value, include_net))
40+
.collect();
41+
Some(players)
42+
} else {
43+
None
44+
};
45+
46+
Self {
47+
id: game.id,
48+
state: game.state,
49+
setting: game.settings.bits(),
50+
attributes: game.attributes.clone(),
51+
players,
52+
total_players,
53+
created_at: game.created_at,
54+
}
55+
}
56+
}
57+
58+
/// Structure for taking a snapshot of the players current
59+
/// state.
60+
#[derive(Serialize)]
61+
pub struct GamePlayerSnapshot {
62+
/// The player ID of the snapshot
63+
pub player_id: PlayerID,
64+
/// The player name of the snapshot
65+
pub display_name: Box<str>,
66+
/// The player net data of the snapshot if collected
67+
pub net: Option<Arc<NetData>>,
68+
}
69+
70+
impl GamePlayerSnapshot {
71+
pub fn new(player: &GamePlayer, include_net: bool) -> Self {
72+
Self {
73+
player_id: player.player.id,
74+
display_name: Box::from(player.player.display_name.as_ref()),
75+
net: if include_net { player.net() } else { None },
76+
}
77+
}
78+
}

src/services/game/store.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{rules::RuleSet, Game, GameJoinableState, GameRef, GameSnapshot};
1+
use super::{rules::RuleSet, snapshot::GameSnapshot, Game, GameJoinableState, GameRef};
22
use crate::utils::{hashing::IntHashMap, types::GameID};
33
use parking_lot::RwLock;
44
use std::sync::{
@@ -87,7 +87,7 @@ impl Games {
8787
// Iterate over the game links
8888
.map(|(_, value)| value.clone())
8989
// Spawn the snapshot tasks
90-
.map(|game| game.read().snapshot(include_net, include_players))
90+
.map(|game| GameSnapshot::new(&game.read(), include_net, include_players))
9191
.collect();
9292

9393
(snapshots, more)

0 commit comments

Comments
 (0)