Skip to main content

geng_net_simple/
server.rs

1use super::*;
2
3struct ClientState<T: Model> {
4    sender: Box<dyn geng::net::Sender<ServerMessage<T>>>,
5}
6
7struct ServerState<T: Model> {
8    current: T,
9    previous: T,
10    events: Vec<T::Event>,
11    next_client_id: usize,
12    clients: HashMap<usize, ClientState<T>>,
13}
14
15impl<T: Model> ServerState<T> {
16    fn send_updates(&mut self) {
17        if self.current != self.previous {
18            let delta = self.previous.diff(&self.current);
19            self.previous = self.current.clone();
20            for client in self.clients.values_mut() {
21                client.sender.send(ServerMessage::Delta(delta.clone()));
22            }
23        }
24        let events = std::mem::take(&mut self.events);
25        if !events.is_empty() {
26            for client in self.clients.values_mut() {
27                client.sender.send(ServerMessage::Events(events.clone()));
28            }
29        }
30    }
31}
32
33struct Client<T: Model> {
34    player_id: T::PlayerId,
35    client_id: usize,
36    server_state: Arc<Mutex<ServerState<T>>>,
37}
38
39impl<T: Model> geng::net::Receiver<T::Message> for Client<T> {
40    fn handle(&mut self, message: T::Message) {
41        let mut state = self.server_state.lock().unwrap();
42        let state: &mut ServerState<T> = &mut state;
43        let replies = state
44            .current
45            .handle_message(&mut state.events, &self.player_id, message);
46        if !replies.is_empty() {
47            state
48                .clients
49                .get_mut(&self.client_id)
50                .unwrap()
51                .sender
52                .send(ServerMessage::Events(replies));
53        }
54    }
55}
56
57impl<T: Model> Drop for Client<T> {
58    fn drop(&mut self) {
59        let mut state = self.server_state.lock().unwrap();
60        let state: &mut ServerState<T> = &mut state;
61        state
62            .current
63            .drop_player(&mut state.events, &self.player_id);
64        state.clients.remove(&self.client_id);
65    }
66}
67
68struct ServerApp<T: Model> {
69    state: Arc<Mutex<ServerState<T>>>,
70}
71
72pub struct Server<T: Model> {
73    state: Arc<Mutex<ServerState<T>>>,
74    inner: geng::net::Server<ServerApp<T>>,
75}
76
77impl<T: Model> Server<T> {
78    pub fn new<A: std::net::ToSocketAddrs + Debug + Copy>(addr: A, model: T) -> Self {
79        let state = Arc::new(Mutex::new(ServerState {
80            current: model.clone(),
81            previous: model,
82            events: Vec::new(),
83            next_client_id: 0,
84            clients: HashMap::new(),
85        }));
86        Self {
87            state: state.clone(),
88            inner: geng::net::Server::new(ServerApp { state }, addr),
89        }
90    }
91    pub fn handle(&self) -> geng::net::ServerHandle {
92        self.inner.handle()
93    }
94    pub fn run(self) {
95        let running = Arc::new(std::sync::atomic::AtomicBool::new(true));
96        let server_thread = std::thread::spawn({
97            let state = self.state;
98            let running = running.clone();
99            let mut timer = Timer::new();
100            let mut unprocessed_time: f32 = 0.0;
101            move || {
102                while running.load(std::sync::atomic::Ordering::Relaxed) {
103                    unprocessed_time += timer.tick().as_secs_f64() as f32;
104                    unprocessed_time = unprocessed_time.min(1.0);
105                    {
106                        let mut state = state.lock().unwrap();
107                        let state: &mut ServerState<T> = &mut state;
108                        while unprocessed_time > 1.0 / T::TICKS_PER_SECOND {
109                            unprocessed_time -= 1.0 / T::TICKS_PER_SECOND;
110                            state.current.tick(&mut state.events);
111                        }
112                        state.send_updates();
113                    }
114                    std::thread::sleep(std::time::Duration::from_secs_f32(
115                        1.0 / T::TICKS_PER_SECOND - unprocessed_time,
116                    ));
117                }
118            }
119        });
120        self.inner.run();
121        running.store(false, std::sync::atomic::Ordering::Relaxed);
122        server_thread.join().expect("Failed to join server thread");
123    }
124}
125
126impl<T: Model> geng::net::server::App for ServerApp<T> {
127    type Client = Client<T>;
128    type ServerMessage = ServerMessage<T>;
129    type ClientMessage = T::Message;
130    fn connect(&mut self, mut sender: Box<dyn geng::net::Sender<ServerMessage<T>>>) -> Client<T> {
131        let mut state = self.state.lock().unwrap();
132        let state: &mut ServerState<T> = &mut state;
133        let player_id = state.current.new_player(&mut state.events);
134        sender.send(ServerMessage::PlayerId(player_id.clone()));
135        sender.send(ServerMessage::Full(state.current.clone()));
136        let client_id = state.next_client_id;
137        state.clients.insert(client_id, ClientState { sender });
138        state.next_client_id += 1;
139        Client {
140            player_id,
141            client_id,
142            server_state: self.state.clone(),
143        }
144    }
145}