naia-server 0.25.0

A server that uses either UDP or WebRTC communication to send/receive messages to/from connected clients, and syncs registered Entities/Components to clients to whom they are in-scope.
use std::collections::{HashMap, HashSet};

use naia_shared::GlobalEntity;

use crate::user::UserKey;

pub struct EntityScopeMap {
    entities_of_user: HashMap<UserKey, HashSet<GlobalEntity>>,
    users_of_entity: HashMap<GlobalEntity, HashSet<UserKey>>,
    main_map: HashMap<(UserKey, GlobalEntity), bool>,
}

impl EntityScopeMap {
    pub fn new() -> Self {
        Self {
            main_map: HashMap::new(),
            entities_of_user: HashMap::new(),
            users_of_entity: HashMap::new(),
        }
    }

    pub fn get(&self, user_key: &UserKey, entity: &GlobalEntity) -> Option<&bool> {
        let key = (*user_key, *entity);

        self.main_map.get(&key)
    }

    pub fn insert(&mut self, user_key: UserKey, entity: GlobalEntity, in_scope: bool) {
        self.entities_of_user
            .entry(user_key)
            .or_default();
        self.users_of_entity
            .entry(entity)
            .or_default();

        self.entities_of_user
            .get_mut(&user_key)
            .unwrap()
            .insert(entity);
        self.users_of_entity
            .get_mut(&entity)
            .unwrap()
            .insert(user_key);

        self.main_map.insert((user_key, entity), in_scope);
    }

    pub fn remove_user(&mut self, user_key: &UserKey) {
        if let Some(entities) = self.entities_of_user.get(user_key) {
            for entity in entities {
                if let Some(users) = self.users_of_entity.get_mut(entity) {
                    users.remove(user_key);
                    self.main_map.remove(&(*user_key, *entity));
                }
            }
        }

        self.entities_of_user.remove(user_key);
    }

    pub fn remove_entity(&mut self, entity: &GlobalEntity) {
        if let Some(users) = self.users_of_entity.get(entity) {
            for user in users {
                if let Some(entities) = self.entities_of_user.get_mut(user) {
                    entities.remove(entity);
                    self.main_map.remove(&(*user, *entity));
                }
            }
        }

        self.users_of_entity.remove(entity);
    }
}