1 use slab; |
1 use slab; |
2 use utils; |
2 use utils; |
3 use super::{ |
3 use super::{ |
4 client::*, room::*, actions, handlers |
4 client::*, room::*, actions, handlers, |
|
5 actions::{Destination, PendingMessage} |
5 }; |
6 }; |
6 use protocol::messages::*; |
7 use protocol::messages::*; |
7 |
8 |
8 type Slab<T> = slab::Slab<T>; |
9 type Slab<T> = slab::Slab<T>; |
9 |
10 |
10 #[derive(Debug)] |
|
11 pub enum Destination { |
|
12 ToAll, |
|
13 ToSelf(ClientId), |
|
14 ToOthers(ClientId), |
|
15 ToSelected(Vec<ClientId>) |
|
16 } |
|
17 |
|
18 pub struct PendingMessage(pub Destination, pub HWServerMessage); |
|
19 |
11 |
20 pub struct HWServer { |
12 pub struct HWServer { |
21 pub clients: Slab<HWClient>, |
13 pub clients: Slab<HWClient>, |
22 pub rooms: Slab<HWRoom>, |
14 pub rooms: Slab<HWRoom>, |
23 pub lobby_id: RoomId, |
15 pub lobby_id: RoomId, |
24 pub output: Vec<PendingMessage>, |
16 pub output: Vec<(Vec<ClientId>, HWServerMessage)>, |
25 pub removed_clients: Vec<ClientId>, |
17 pub removed_clients: Vec<ClientId>, |
26 } |
18 } |
27 |
19 |
28 impl HWServer { |
20 impl HWServer { |
29 pub fn new(clients_limit: usize, rooms_limit: usize) -> HWServer { |
21 pub fn new(clients_limit: usize, rooms_limit: usize) -> HWServer { |
45 let entry = self.clients.vacant_entry(); |
37 let entry = self.clients.vacant_entry(); |
46 key = entry.key(); |
38 key = entry.key(); |
47 let client = HWClient::new(entry.key()); |
39 let client = HWClient::new(entry.key()); |
48 entry.insert(client); |
40 entry.insert(client); |
49 } |
41 } |
50 self.send_self(key, HWServerMessage::Connected(utils::PROTOCOL_VERSION)); |
42 self.send(key, Destination::ToSelf, HWServerMessage::Connected(utils::PROTOCOL_VERSION)); |
51 key |
43 key |
52 } |
44 } |
53 |
45 |
54 pub fn client_lost(&mut self, client_id: ClientId) { |
46 pub fn client_lost(&mut self, client_id: ClientId) { |
55 actions::run_action(self, client_id, |
47 actions::run_action(self, client_id, |
67 pub fn handle_msg(&mut self, client_id: ClientId, msg: HWProtocolMessage) { |
59 pub fn handle_msg(&mut self, client_id: ClientId, msg: HWProtocolMessage) { |
68 debug!("Handling message {:?} for client {}", msg, client_id); |
60 debug!("Handling message {:?} for client {}", msg, client_id); |
69 handlers::handle(self, client_id, msg); |
61 handlers::handle(self, client_id, msg); |
70 } |
62 } |
71 |
63 |
72 pub fn send_all(&mut self, msg: HWServerMessage) { |
64 fn get_recipients(&self, client_id: ClientId, destination: Destination) -> Vec<ClientId> { |
73 self.output.push(PendingMessage( |
65 let mut ids = match destination { |
74 Destination::ToAll, msg)); |
66 Destination::ToSelf => vec![client_id], |
|
67 Destination::ToAll {room_id: Some(id), ..} => |
|
68 self.room_clients(id), |
|
69 Destination::ToAll {protocol: Some(proto), ..} => |
|
70 self.protocol_clients(proto), |
|
71 Destination::ToAll {..} => |
|
72 self.clients.iter().map(|(id, _)| id).collect::<Vec<_>>(), |
|
73 _ => Vec::new() |
|
74 }; |
|
75 if let Destination::ToAll {skip_self: true, ..} = destination { |
|
76 if let Some(index) = ids.iter().position(|id| *id == client_id) { |
|
77 ids.remove(index); |
|
78 } |
|
79 } |
|
80 ids |
75 } |
81 } |
76 |
82 |
77 pub fn send_self(&mut self, client_id: ClientId, msg: HWServerMessage) { |
83 pub fn send(&mut self, client_id: ClientId, destination: Destination, message: HWServerMessage) { |
78 self.output.push(PendingMessage( |
84 let ids = self.get_recipients(client_id, destination); |
79 Destination::ToSelf(client_id), msg)); |
85 self.output.push((ids, message)); |
80 } |
|
81 |
|
82 pub fn send_others(&mut self, client_id: ClientId, msg: HWServerMessage) { |
|
83 self.output.push(PendingMessage( |
|
84 Destination::ToOthers(client_id), msg)); |
|
85 } |
|
86 |
|
87 pub fn send_to_selected(&mut self, client_ids: Vec<ClientId>, msg: HWServerMessage) { |
|
88 self.output.push(PendingMessage( |
|
89 Destination::ToSelected(client_ids), msg)); |
|
90 } |
86 } |
91 |
87 |
92 pub fn react(&mut self, client_id: ClientId, actions: Vec<actions::Action>) { |
88 pub fn react(&mut self, client_id: ClientId, actions: Vec<actions::Action>) { |
93 for action in actions { |
89 for action in actions { |
94 actions::run_action(self, client_id, action); |
90 actions::run_action(self, client_id, action); |