use super::resource_id::{ResourceId};
use super::poll::{PollRegistry};
use super::adapter::{Resource};
use crate::util::thread::{OTHER_THREAD_ERR};
use std::collections::{HashMap};
use std::net::{SocketAddr};
use std::sync::{Arc, RwLock};
pub struct Register<S: Resource> {
pub resource: S,
pub addr: SocketAddr,
poll_registry: Arc<PollRegistry>,
}
impl<S: Resource> Register<S> {
fn new(resource: S, addr: SocketAddr, poll_registry: Arc<PollRegistry>) -> Self {
Self { resource, addr, poll_registry }
}
}
impl<S: Resource> Drop for Register<S> {
fn drop(&mut self) {
self.poll_registry.remove(self.resource.source());
}
}
pub struct ResourceRegistry<S: Resource> {
resources: RwLock<HashMap<ResourceId, Arc<Register<S>>>>,
poll_registry: Arc<PollRegistry>,
}
impl<S: Resource> ResourceRegistry<S> {
pub fn new(poll_registry: PollRegistry) -> Self {
ResourceRegistry {
resources: RwLock::new(HashMap::new()),
poll_registry: Arc::new(poll_registry),
}
}
pub fn add(&self, mut resource: S, addr: SocketAddr) -> ResourceId {
let id = self.poll_registry.add(resource.source());
let register = Register::new(resource, addr, self.poll_registry.clone());
self.resources.write().expect(OTHER_THREAD_ERR).insert(id, Arc::new(register));
id
}
pub fn remove(&self, id: ResourceId) -> bool {
self.resources.write().expect(OTHER_THREAD_ERR).remove(&id).is_some()
}
pub fn get(&self, id: ResourceId) -> Option<Arc<Register<S>>> {
self.resources.read().expect(OTHER_THREAD_ERR).get(&id).cloned()
}
}