mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Implement non-multiplayer parts of custom games
This commit is contained in:
82
rc_services_room/src/user_service.rs
Normal file
82
rc_services_room/src/user_service.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
pub struct UserMesh {
|
||||
online_users: tokio::sync::RwLock<std::collections::HashMap<String, UserHandle>>,
|
||||
}
|
||||
|
||||
struct UserHandle {
|
||||
emitter: polariton_server::events::WeakEventEmitter,
|
||||
is_alive: std::sync::atomic::AtomicBool,
|
||||
}
|
||||
|
||||
impl UserMesh {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
online_users: tokio::sync::RwLock::new(std::collections::HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn user_count(&self) -> usize {
|
||||
self.online_users.read().await.values()
|
||||
.filter(|u| u.is_alive.load(std::sync::atomic::Ordering::Relaxed))
|
||||
.count()
|
||||
}
|
||||
|
||||
/// returns whether the user was replaced (true) or new (false)
|
||||
pub async fn add_user(
|
||||
&self,
|
||||
public_id: String,
|
||||
emitter: polariton_server::events::WeakEventEmitter,
|
||||
) -> bool {
|
||||
let handle = UserHandle {
|
||||
emitter,
|
||||
is_alive: std::sync::atomic::AtomicBool::new(true),
|
||||
};
|
||||
self.online_users.write().await
|
||||
.insert(public_id, handle)
|
||||
.is_some()
|
||||
}
|
||||
|
||||
/// returns whether the user existing (true) or not (false)
|
||||
pub async fn remove_user(
|
||||
&self,
|
||||
public_id: String,
|
||||
) -> bool {
|
||||
self.online_users.write().await
|
||||
.remove(&public_id)
|
||||
.is_some()
|
||||
}
|
||||
|
||||
pub async fn broadcast_event_to(&self, public_ids: impl std::iter::Iterator<Item = &str>, event: impl polariton_server::events::IntoEvent<()> + Clone) -> bool {
|
||||
let user_lock = self.online_users.read().await;
|
||||
let mut total_success = true;
|
||||
for public_id in public_ids {
|
||||
let is_success = if let Some(user_handle) = user_lock.get(public_id) {
|
||||
let is_success = user_handle.emitter.emit(event.clone());
|
||||
user_handle.is_alive.swap(is_success, std::sync::atomic::Ordering::SeqCst);
|
||||
is_success
|
||||
} else {
|
||||
false
|
||||
};
|
||||
total_success &= is_success;
|
||||
}
|
||||
total_success
|
||||
}
|
||||
|
||||
pub async fn send_event_to(&self, public_id: &str, event: impl polariton_server::events::IntoEvent<()>) -> bool {
|
||||
let user_lock = self.online_users.read().await;
|
||||
if let Some(user_handle) = user_lock.get(public_id) {
|
||||
let is_success = user_handle.emitter.emit(event);
|
||||
user_handle.is_alive.swap(is_success, std::sync::atomic::Ordering::SeqCst);
|
||||
is_success
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_user_online(&self, public_id: &str) -> bool {
|
||||
if let Some(user) = self.online_users.read().await.get(public_id) {
|
||||
user.is_alive.load(std::sync::atomic::Ordering::Relaxed)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user