refactor(registry): clean up and use parking_lot

This commit is contained in:
Nova
2022-06-12 01:59:02 -04:00
parent 57feb5a49b
commit 66c6e2e3d4
2 changed files with 27 additions and 41 deletions

View File

@@ -1,42 +1,39 @@
use anyhow::{anyhow, Result};
use parking_lot::RwLock;
use slab::{Iter, Slab};
use std::sync::Arc;
use std::sync::RwLock;
use std::sync::{Arc, Weak};
pub trait RegistryEntry {
fn store_idx(&self, idx: usize);
}
pub struct Registry<T>(RwLock<Slab<Weak<T>>>);
pub struct Registry<T: RegistryEntry>(RwLock<Slab<Arc<T>>>);
impl<T: RegistryEntry> Registry<T> {
impl<T> Registry<T> {
pub fn add(&self, t: T) -> Result<Arc<T>> {
let t_arc = Arc::new(t);
let idx = self
.0
.write()
.ok()
.ok_or_else(|| anyhow!("Registry has been poisoned"))?
.insert(t_arc.clone());
t_arc.store_idx(idx);
self.0.write().insert(Arc::downgrade(&t_arc));
Ok(t_arc)
}
pub fn iterate<F: FnOnce(Iter<'_, Arc<T>>)>(&self, closure: F) -> Result<()> {
closure(
self.0
.read()
.ok()
.ok_or_else(|| anyhow!("Registry has been poisoned"))?
.iter(),
);
pub fn iterate<F: FnOnce(Iter<'_, Weak<T>>)>(&self, closure: F) -> Result<()> {
closure(self.0.read().iter());
Ok(())
}
pub fn remove(&self, index: usize) -> Result<T, Arc<T>> {
Arc::try_unwrap(self.0.write().unwrap().remove(index))
pub fn remove(&self, t: &T) -> Result<()> {
let mut del_idx: Option<usize> = None;
for item in self.0.read().iter() {
let (idx, item) = item;
if let Some(item) = item.upgrade() {
if std::ptr::eq(item.as_ref(), t) {
del_idx = Some(idx);
break;
}
}
}
del_idx
.map(|idx| self.0.write().remove(idx))
.ok_or_else(|| anyhow!("Node not found to remove"))?;
Ok(())
}
}
impl<T: RegistryEntry> Default for Registry<T> {
impl<T> Default for Registry<T> {
fn default() -> Self {
Registry::<T>(RwLock::new(Slab::new()))
}