feat: simple signals implementation

This commit is contained in:
Jonathan Kelley committed 2023-01-01 19:57:33 -05:00
1 parent c8f88b6428
commit 4f9d67fb45
5 files changed
+257

No files matched your search

+73
View File
@@ -0,0 +1,73 @@
use std::{
any::Any,
cell::RefCell,
rc::Rc,
sync::{Arc, Mutex},
};
use dioxus_core::ScopeId;
use slab::Slab;
/// Provide the runtime for signals
///
/// This will reuse dead runtimes
pub fn claim_rt(update_any: Arc<dyn Fn(ScopeId)>) -> &'static SignalRt {
Box::leak(Box::new(SignalRt {
signals: RefCell::new(Slab::new()),
update_any,
}))
}
pub fn reclam_rt(rt: usize) {}
struct GlobalRt {
signals: Slab<Inner>,
}
pub struct SignalRt {
signals: RefCell<Slab<Inner>>,
update_any: Arc<dyn Fn(ScopeId)>,
}
impl SignalRt {
pub fn init<T: 'static>(&self, val: T) -> usize {
self.signals.borrow_mut().insert(Inner {
value: Box::new(val),
subscribers: Vec::new(),
})
}
pub fn subscribe(&self, id: usize, subscriber: ScopeId) {
self.signals.borrow_mut()[id].subscribers.push(subscriber);
}
pub fn get<T: Clone + 'static>(&self, id: usize) -> T {
self.signals.borrow()[id]
.value
.downcast_ref::<T>()
.cloned()
.unwrap()
}
pub fn set<T: 'static>(&self, id: usize, value: T) {
let mut signals = self.signals.borrow_mut();
let inner = &mut signals[id];
inner.value = Box::new(value);
for subscriber in inner.subscribers.iter() {
(self.update_any)(*subscriber);
}
}
pub fn with<T: 'static, O>(&self, id: usize, f: impl FnOnce(&T) -> O) -> O {
let signals = self.signals.borrow();
let inner = &signals[id];
let inner = inner.value.downcast_ref::<T>().unwrap();
f(&*inner)
}
}
struct Inner {
value: Box<dyn Any>,
subscribers: Vec<ScopeId>,
}