refactor(registry): use globals instead of storing in event loop

This commit is contained in:
Nova
2022-06-12 00:51:12 -04:00
parent 3ef45a1041
commit 01971b5048
4 changed files with 39 additions and 47 deletions

View File

@@ -11,6 +11,7 @@ anyhow = "1.0.57"
ctrlc = "3.2.2"
flexbuffers = "2.0.0"
glam = {version = "0.20.5", features = ["mint"]}
lazy_static = "1.4.0"
mint = "0.5.9"
mio = {version = "0.8.3", features = ["net", "os-poll", "os-ext"]}
rccell = "0.1.3"

View File

@@ -10,15 +10,10 @@ use std::rc::Rc;
use std::sync::{Arc, RwLock};
use std::thread::{self, JoinHandle};
use super::registry::Registry;
use crate::nodes::data::PulseSender;
pub struct EventLoop {
pub socket_path: String,
join_handle: RwLock<Option<JoinHandle<Result<()>>>>,
stop_write: pipe::Sender,
pub pulse_senders: Registry<Arc<PulseSender>>,
}
impl EventLoop {
@@ -31,8 +26,6 @@ impl EventLoop {
socket_path,
join_handle: RwLock::new(None),
stop_write: sender,
pulse_senders: Default::default(),
});
let event_loop_arc_captured = event_loop_arc.clone();
let join_handle = thread::Builder::new()

View File

@@ -1,19 +1,27 @@
use anyhow::{anyhow, Result};
use slab::{Iter, Slab};
use std::sync::Arc;
use std::sync::RwLock;
pub struct Registry<T>(RwLock<Slab<T>>);
pub trait RegistryEntry {
fn store_idx(&self, idx: usize);
}
impl<T> Registry<T> {
pub fn add(&self, t: T) -> Result<usize> {
Ok(self
pub struct Registry<T: RegistryEntry>(RwLock<Slab<Arc<T>>>);
impl<T: RegistryEntry> 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))
.insert(t_arc.clone());
t_arc.store_idx(idx);
Ok(t_arc)
}
pub fn iterate<F: FnOnce(Iter<'_, T>)>(&self, closure: F) -> Result<()> {
pub fn iterate<F: FnOnce(Iter<'_, Arc<T>>)>(&self, closure: F) -> Result<()> {
closure(
self.0
.read()
@@ -23,17 +31,12 @@ impl<T> Registry<T> {
);
Ok(())
}
pub fn remove(&self, index: usize) -> Result<T> {
Ok(self
.0
.write()
.ok()
.ok_or_else(|| anyhow!("Registry has been poisoned"))?
.remove(index))
pub fn remove(&self, index: usize) -> Result<T, Arc<T>> {
Arc::try_unwrap(self.0.write().unwrap().remove(index))
}
}
impl<T> Default for Registry<T> {
impl<T: RegistryEntry> Default for Registry<T> {
fn default() -> Self {
Registry::<T>(RwLock::new(Slab::new()))
}

View File

@@ -1,12 +1,16 @@
use super::core::Node;
use crate::core::eventloop::EventLoop;
use crate::core::registry::{Registry, RegistryEntry};
use anyhow::{ensure, Result};
use lazy_static::lazy_static;
use rccell::RcCell;
use std::sync::{Arc, RwLock, Weak};
use std::sync::RwLock;
lazy_static! {
static ref PULSE_SENDER_REGISTRY: Registry<PulseSender> = Default::default();
}
pub struct PulseSender {
event_loop: Weak<EventLoop>,
registry_idx: RwLock<Option<usize>>,
registry_idx: RwLock<usize>,
}
impl PulseSender {
@@ -16,32 +20,23 @@ impl PulseSender {
"Node does not have a spatial attached!"
);
let sender = Arc::new(PulseSender {
event_loop: node.borrow().get_client().map_or(Weak::new(), |client| {
Arc::downgrade(&client.get_event_loop())
}),
registry_idx: RwLock::new(None),
});
let idx = sender
.event_loop
.upgrade()
.and_then(|event_loop| event_loop.pulse_senders.add(sender.clone()).ok());
*sender.registry_idx.write().unwrap() = idx;
let sender = PulseSender {
registry_idx: Default::default(),
};
let sender = PULSE_SENDER_REGISTRY.add(sender)?;
node.borrow_mut().pulse_sender = Some(sender);
Ok(())
}
}
impl Drop for PulseSender {
fn drop(&mut self) {
let event_loop = self.event_loop.upgrade();
let idx = self
.registry_idx
.write()
.ok()
.and_then(|registry_idx| registry_idx.clone());
event_loop
.zip(idx)
.and_then(|(event_loop, idx)| event_loop.pulse_senders.remove(idx).ok());
impl RegistryEntry for PulseSender {
fn store_idx(&self, store_idx: usize) {
*self.registry_idx.write().unwrap() = store_idx;
}
}
impl Drop for PulseSender {
fn drop(&mut self) {
let _ = PULSE_SENDER_REGISTRY.remove(*self.registry_idx.read().unwrap());
}
}