naia_server/
room.rs

1use std::{
2    collections::{hash_set::Iter, HashSet, VecDeque},
3    hash::Hash,
4};
5
6use naia_shared::{BigMapKey, Channel, ChannelKind, Message};
7
8use super::user::UserKey;
9
10// RoomKey
11#[derive(Clone, Copy, Eq, PartialEq, Hash)]
12pub struct RoomKey(u64);
13
14impl BigMapKey for RoomKey {
15    fn to_u64(&self) -> u64 {
16        self.0
17    }
18
19    fn from_u64(value: u64) -> Self {
20        RoomKey(value)
21    }
22}
23
24// Room
25pub struct Room<E: Copy + Eq + Hash> {
26    users: HashSet<UserKey>,
27    entities: HashSet<E>,
28    entity_removal_queue: VecDeque<(UserKey, E)>,
29}
30
31impl<E: Copy + Eq + Hash> Room<E> {
32    pub(crate) fn new() -> Room<E> {
33        Room {
34            users: HashSet::new(),
35            entities: HashSet::new(),
36            entity_removal_queue: VecDeque::new(),
37        }
38    }
39
40    // Users
41
42    pub(crate) fn has_user(&self, user_key: &UserKey) -> bool {
43        self.users.contains(user_key)
44    }
45
46    pub(crate) fn subscribe_user(&mut self, user_key: &UserKey) {
47        self.users.insert(*user_key);
48    }
49
50    pub(crate) fn unsubscribe_user(&mut self, user_key: &UserKey) {
51        self.users.remove(user_key);
52        for entity in self.entities.iter() {
53            self.entity_removal_queue.push_back((*user_key, *entity));
54        }
55    }
56
57    pub(crate) fn user_keys(&self) -> Iter<UserKey> {
58        self.users.iter()
59    }
60
61    pub(crate) fn users_count(&self) -> usize {
62        self.users.len()
63    }
64
65    // Entities
66
67    pub(crate) fn add_entity(&mut self, entity: &E) {
68        self.entities.insert(*entity);
69    }
70
71    pub(crate) fn remove_entity(&mut self, entity: &E, entity_is_despawned: bool) -> bool {
72        if self.entities.remove(entity) {
73            if !entity_is_despawned {
74                for user_key in self.users.iter() {
75                    self.entity_removal_queue.push_back((*user_key, *entity));
76                }
77            }
78            true
79        } else {
80            panic!("Room does not contain Entity");
81        }
82    }
83
84    pub(crate) fn has_entity(&self, entity: &E) -> bool {
85        self.entities.contains(entity)
86    }
87
88    pub(crate) fn entities(&self) -> Iter<E> {
89        self.entities.iter()
90    }
91
92    pub(crate) fn pop_entity_removal_queue(&mut self) -> Option<(UserKey, E)> {
93        self.entity_removal_queue.pop_front()
94    }
95
96    pub(crate) fn entities_count(&self) -> usize {
97        self.entities.len()
98    }
99}
100
101// room references
102
103use super::server::Server;
104
105// RoomRef
106
107pub struct RoomRef<'s, E: Copy + Eq + Hash + Send + Sync> {
108    server: &'s Server<E>,
109    key: RoomKey,
110}
111
112impl<'s, E: Copy + Eq + Hash + Send + Sync> RoomRef<'s, E> {
113    pub fn new(server: &'s Server<E>, key: &RoomKey) -> Self {
114        RoomRef { server, key: *key }
115    }
116
117    pub fn key(&self) -> RoomKey {
118        self.key
119    }
120
121    // Users
122
123    pub fn has_user(&self, user_key: &UserKey) -> bool {
124        self.server.room_has_user(&self.key, user_key)
125    }
126
127    pub fn users_count(&self) -> usize {
128        self.server.room_users_count(&self.key)
129    }
130
131    /// Returns an iterator of the [`UserKey`] for Users that belong in the [`Room`]
132    pub fn user_keys(&self) -> impl Iterator<Item = &UserKey> {
133        self.server.room_user_keys(&self.key)
134    }
135
136    // Entities
137
138    pub fn has_entity(&self, entity: &E) -> bool {
139        self.server.room_has_entity(&self.key, entity)
140    }
141
142    pub fn entities_count(&self) -> usize {
143        self.server.room_entities_count(&self.key)
144    }
145
146    pub fn entities(&self) -> impl Iterator<Item = &E> {
147        self.server.room_entities(&self.key)
148    }
149}
150
151// RoomMut
152pub struct RoomMut<'s, E: Copy + Eq + Hash + Send + Sync> {
153    server: &'s mut Server<E>,
154    key: RoomKey,
155}
156
157impl<'s, E: Copy + Eq + Hash + Send + Sync> RoomMut<'s, E> {
158    pub fn new(server: &'s mut Server<E>, key: &RoomKey) -> Self {
159        RoomMut { server, key: *key }
160    }
161
162    pub fn key(&self) -> RoomKey {
163        self.key
164    }
165
166    pub fn destroy(&mut self) {
167        self.server.room_destroy(&self.key);
168    }
169
170    // Users
171
172    pub fn has_user(&self, user_key: &UserKey) -> bool {
173        self.server.room_has_user(&self.key, user_key)
174    }
175
176    pub fn add_user(&mut self, user_key: &UserKey) -> &mut Self {
177        self.server.room_add_user(&self.key, user_key);
178
179        self
180    }
181
182    pub fn remove_user(&mut self, user_key: &UserKey) -> &mut Self {
183        self.server.room_remove_user(&self.key, user_key);
184
185        self
186    }
187
188    pub fn users_count(&self) -> usize {
189        self.server.room_users_count(&self.key)
190    }
191
192    /// Returns an iterator of the [`UserKey`] for Users that belong in the [`Room`]
193    pub fn user_keys(&self) -> impl Iterator<Item = &UserKey> {
194        self.server.room_user_keys(&self.key)
195    }
196
197    // Entities
198
199    pub fn has_entity(&self, entity: &E) -> bool {
200        self.server.room_has_entity(&self.key, entity)
201    }
202
203    pub fn add_entity(&mut self, entity: &E) -> &mut Self {
204        self.server.room_add_entity(&self.key, entity);
205
206        self
207    }
208
209    pub fn remove_entity(&mut self, entity: &E) -> &mut Self {
210        self.server.room_remove_entity(&self.key, entity);
211
212        self
213    }
214
215    pub fn entities_count(&self) -> usize {
216        self.server.room_entities_count(&self.key)
217    }
218
219    // Messages
220
221    pub fn broadcast_message<C: Channel, M: Message>(&mut self, message: &M) {
222        let cloned_message = message.clone_box();
223        self.server
224            .room_broadcast_message(&ChannelKind::of::<C>(), &self.key, cloned_message);
225    }
226}