use std::{
collections::HashMap,
hash::Hash,
net::SocketAddr,
sync::{Arc, RwLock, RwLockReadGuard},
};
use crate::{ComponentKind, DiffMask, GlobalWorldManagerType};
use super::{global_diff_handler::GlobalDiffHandler, mut_channel::MutReceiver};
#[derive(Clone)]
pub struct UserDiffHandler<E: Copy + Eq + Hash> {
receivers: HashMap<(E, ComponentKind), MutReceiver>,
global_diff_handler: Arc<RwLock<GlobalDiffHandler<E>>>,
}
impl<E: Copy + Eq + Hash> UserDiffHandler<E> {
pub fn new(global_world_manager: &dyn GlobalWorldManagerType<E>) -> Self {
Self {
receivers: HashMap::new(),
global_diff_handler: global_world_manager.diff_handler(),
}
}
pub fn register_component(
&mut self,
address: &Option<SocketAddr>,
entity: &E,
component_kind: &ComponentKind,
) {
let Ok(global_handler) = self.global_diff_handler.as_ref().read() else {
panic!("Be sure you can get self.global_diff_handler before calling this!");
};
let receiver = global_handler
.receiver(address, entity, component_kind)
.expect("GlobalDiffHandler has not yet registered this Component");
self.receivers.insert((*entity, *component_kind), receiver);
}
pub fn deregister_component(&mut self, entity: &E, component_kind: &ComponentKind) {
self.receivers.remove(&(*entity, *component_kind));
}
pub fn has_component(&self, entity: &E, component: &ComponentKind) -> bool {
self.receivers.contains_key(&(*entity, *component))
}
pub fn diff_mask(
&self,
entity: &E,
component_kind: &ComponentKind,
) -> RwLockReadGuard<DiffMask> {
let Some(receiver) = self.receivers.get(&(*entity, *component_kind)) else {
panic!("Should not call this unless we're sure there's a receiver");
};
return receiver.mask();
}
pub fn diff_mask_is_clear(&self, entity: &E, component_kind: &ComponentKind) -> bool {
let Some(receiver) = self.receivers.get(&(*entity, *component_kind)) else {
panic!("Should not call this unless we're sure there's a receiver");
};
return receiver.diff_mask_is_clear();
}
pub fn or_diff_mask(
&mut self,
entity: &E,
component_kind: &ComponentKind,
other_mask: &DiffMask,
) {
let Some(receiver) = self.receivers.get_mut(&(*entity, *component_kind)) else {
panic!("Should not call this unless we're sure there's a receiver");
};
receiver.or_mask(other_mask);
}
pub fn clear_diff_mask(&mut self, entity: &E, component_kind: &ComponentKind) {
let Some(receiver) = self.receivers.get_mut(&(*entity, *component_kind)) else {
panic!("Should not call this unless we're sure there's a receiver");
};
receiver.clear_mask();
}
}