fix: use typeid of atoms for their unique ID (#558)

This commit is contained in:
Jon Kelley authored and GitHub committed 2022-09-17 10:50:05 -07:00
1 parent 540e785d8b
commit bf9901a6cd
4 files changed
+38 -11

No files matched your search

+6 -3
View File
@@ -3,7 +3,7 @@ use crate::{AtomId, AtomRoot, Readable, Writable};
pub type Atom<T> = fn(AtomBuilder) -> T; pub type Atom<T> = fn(AtomBuilder) -> T;
pub struct AtomBuilder; pub struct AtomBuilder;
impl<V> Readable<V> for Atom<V> { impl<V: 'static> Readable<V> for Atom<V> {
fn read(&self, _root: AtomRoot) -> Option<V> { fn read(&self, _root: AtomRoot) -> Option<V> {
todo!() todo!()
} }
@@ -11,11 +11,14 @@ impl<V> Readable<V> for Atom<V> {
(*self)(AtomBuilder) (*self)(AtomBuilder)
} }
fn unique_id(&self) -> AtomId { fn unique_id(&self) -> AtomId {
*self as *const () AtomId {
ptr: *self as *const (),
type_id: std::any::TypeId::of::<V>(),
}
} }
} }
impl<V> Writable<V> for Atom<V> { impl<V: 'static> Writable<V> for Atom<V> {
fn write(&self, _root: AtomRoot, _value: V) { fn write(&self, _root: AtomRoot, _value: V) {
todo!() todo!()
} }
+6 -3
View File
@@ -4,7 +4,7 @@ use im_rc::HashMap as ImMap;
pub struct AtomFamilyBuilder; pub struct AtomFamilyBuilder;
pub type AtomFamily<K, V> = fn(AtomFamilyBuilder) -> ImMap<K, V>; pub type AtomFamily<K, V> = fn(AtomFamilyBuilder) -> ImMap<K, V>;
impl<K, V> Readable<ImMap<K, V>> for AtomFamily<K, V> { impl<K, V: 'static> Readable<ImMap<K, V>> for AtomFamily<K, V> {
fn read(&self, _root: AtomRoot) -> Option<ImMap<K, V>> { fn read(&self, _root: AtomRoot) -> Option<ImMap<K, V>> {
todo!() todo!()
} }
@@ -14,11 +14,14 @@ impl<K, V> Readable<ImMap<K, V>> for AtomFamily<K, V> {
} }
fn unique_id(&self) -> AtomId { fn unique_id(&self) -> AtomId {
*self as *const () AtomId {
ptr: *self as *const (),
type_id: std::any::TypeId::of::<V>(),
}
} }
} }
impl<K, V> Writable<ImMap<K, V>> for AtomFamily<K, V> { impl<K, V: 'static> Writable<ImMap<K, V>> for AtomFamily<K, V> {
fn write(&self, _root: AtomRoot, _value: ImMap<K, V>) { fn write(&self, _root: AtomRoot, _value: ImMap<K, V>) {
todo!() todo!()
} }
+5 -2
View File
@@ -4,7 +4,7 @@ use std::cell::RefCell;
pub struct AtomRefBuilder; pub struct AtomRefBuilder;
pub type AtomRef<T> = fn(AtomRefBuilder) -> T; pub type AtomRef<T> = fn(AtomRefBuilder) -> T;
impl<V> Readable<RefCell<V>> for AtomRef<V> { impl<V: 'static> Readable<RefCell<V>> for AtomRef<V> {
fn read(&self, _root: AtomRoot) -> Option<RefCell<V>> { fn read(&self, _root: AtomRoot) -> Option<RefCell<V>> {
todo!() todo!()
} }
@@ -14,7 +14,10 @@ impl<V> Readable<RefCell<V>> for AtomRef<V> {
} }
fn unique_id(&self) -> AtomId { fn unique_id(&self) -> AtomId {
*self as *const () AtomId {
ptr: *self as *const (),
type_id: std::any::TypeId::of::<V>(),
}
} }
} }
+21 -3
View File
@@ -1,11 +1,21 @@
use std::{any::Any, cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; use std::{
any::{Any, TypeId},
cell::RefCell,
collections::HashMap,
rc::Rc,
sync::Arc,
};
use dioxus_core::ScopeId; use dioxus_core::ScopeId;
use im_rc::HashSet; use im_rc::HashSet;
use crate::Readable; use crate::Readable;
pub type AtomId = *const (); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AtomId {
pub(crate) ptr: *const (),
pub(crate) type_id: TypeId,
}
pub struct AtomRoot { pub struct AtomRoot {
pub atoms: RefCell<HashMap<AtomId, Slot>>, pub atoms: RefCell<HashMap<AtomId, Slot>>,
@@ -44,7 +54,15 @@ impl AtomRoot {
// initialize the value if it's not already initialized // initialize the value if it's not already initialized
if let Some(slot) = atoms.get_mut(&f.unique_id()) { if let Some(slot) = atoms.get_mut(&f.unique_id()) {
slot.subscribers.insert(scope); slot.subscribers.insert(scope);
slot.value.clone().downcast().unwrap() match slot.value.clone().downcast() {
Ok(res) => res,
Err(e) => panic!(
"Downcasting atom failed: {:?}. Has typeid of {:?} but needs typeid of {:?}",
f.unique_id(),
e.type_id(),
TypeId::of::<V>()
),
}
} else { } else {
let value = Rc::new(f.init()); let value = Rc::new(f.init());
let mut subscribers = HashSet::new(); let mut subscribers = HashSet::new();