refactor(registry): clean up and use parking_lot
This commit is contained in:
@@ -1,42 +1,39 @@
|
|||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use parking_lot::RwLock;
|
||||||
use slab::{Iter, Slab};
|
use slab::{Iter, Slab};
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Weak};
|
||||||
use std::sync::RwLock;
|
|
||||||
|
|
||||||
pub trait RegistryEntry {
|
pub struct Registry<T>(RwLock<Slab<Weak<T>>>);
|
||||||
fn store_idx(&self, idx: usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Registry<T: RegistryEntry>(RwLock<Slab<Arc<T>>>);
|
impl<T> Registry<T> {
|
||||||
|
|
||||||
impl<T: RegistryEntry> Registry<T> {
|
|
||||||
pub fn add(&self, t: T) -> Result<Arc<T>> {
|
pub fn add(&self, t: T) -> Result<Arc<T>> {
|
||||||
let t_arc = Arc::new(t);
|
let t_arc = Arc::new(t);
|
||||||
let idx = self
|
self.0.write().insert(Arc::downgrade(&t_arc));
|
||||||
.0
|
|
||||||
.write()
|
|
||||||
.ok()
|
|
||||||
.ok_or_else(|| anyhow!("Registry has been poisoned"))?
|
|
||||||
.insert(t_arc.clone());
|
|
||||||
t_arc.store_idx(idx);
|
|
||||||
Ok(t_arc)
|
Ok(t_arc)
|
||||||
}
|
}
|
||||||
pub fn iterate<F: FnOnce(Iter<'_, Arc<T>>)>(&self, closure: F) -> Result<()> {
|
pub fn iterate<F: FnOnce(Iter<'_, Weak<T>>)>(&self, closure: F) -> Result<()> {
|
||||||
closure(
|
closure(self.0.read().iter());
|
||||||
self.0
|
|
||||||
.read()
|
|
||||||
.ok()
|
|
||||||
.ok_or_else(|| anyhow!("Registry has been poisoned"))?
|
|
||||||
.iter(),
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn remove(&self, index: usize) -> Result<T, Arc<T>> {
|
pub fn remove(&self, t: &T) -> Result<()> {
|
||||||
Arc::try_unwrap(self.0.write().unwrap().remove(index))
|
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 {
|
fn default() -> Self {
|
||||||
Registry::<T>(RwLock::new(Slab::new()))
|
Registry::<T>(RwLock::new(Slab::new()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
use super::core::Node;
|
use super::core::Node;
|
||||||
use crate::core::registry::{Registry, RegistryEntry};
|
use crate::core::registry::Registry;
|
||||||
use anyhow::{ensure, Result};
|
use anyhow::{ensure, Result};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use rccell::RcCell;
|
use rccell::RcCell;
|
||||||
use std::sync::RwLock;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref PULSE_SENDER_REGISTRY: Registry<PulseSender> = Default::default();
|
static ref PULSE_SENDER_REGISTRY: Registry<PulseSender> = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PulseSender {
|
pub struct PulseSender {}
|
||||||
registry_idx: RwLock<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PulseSender {
|
impl PulseSender {
|
||||||
pub fn add_to(node: &RcCell<Node>) -> Result<()> {
|
pub fn add_to(node: &RcCell<Node>) -> Result<()> {
|
||||||
@@ -20,23 +17,15 @@ impl PulseSender {
|
|||||||
"Node does not have a spatial attached!"
|
"Node does not have a spatial attached!"
|
||||||
);
|
);
|
||||||
|
|
||||||
let sender = PulseSender {
|
let sender = PulseSender {};
|
||||||
registry_idx: Default::default(),
|
|
||||||
};
|
|
||||||
let sender = PULSE_SENDER_REGISTRY.add(sender)?;
|
let sender = PULSE_SENDER_REGISTRY.add(sender)?;
|
||||||
node.borrow_mut().pulse_sender = Some(sender);
|
node.borrow_mut().pulse_sender = Some(sender);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegistryEntry for PulseSender {
|
|
||||||
fn store_idx(&self, store_idx: usize) {
|
|
||||||
*self.registry_idx.write().unwrap() = store_idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for PulseSender {
|
impl Drop for PulseSender {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let _ = PULSE_SENDER_REGISTRY.remove(*self.registry_idx.read().unwrap());
|
let _ = PULSE_SENDER_REGISTRY.remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user