From 70a6f95c8c7f3d617b233e89567812c0372c7976 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sun, 24 Apr 2022 20:47:22 -0400 Subject: [PATCH 1/2] fix: allow fermi atomref to be cloned --- examples/fermi.rs | 25 +++++++++++++++++++++++++ packages/fermi/src/hooks/atom_ref.rs | 11 +++++++++++ 2 files changed, 36 insertions(+) diff --git a/examples/fermi.rs b/examples/fermi.rs index f4391de5e..9f87961b3 100644 --- a/examples/fermi.rs +++ b/examples/fermi.rs @@ -14,6 +14,7 @@ fn app(cx: Scope) -> Element { cx.render(rsx! { div { "hello {name}!" } Child {} + ChildWithRef{} }) } @@ -27,3 +28,27 @@ fn Child(cx: Scope) -> Element { } }) } + +static NAMES: AtomRef> = |_| vec!["world".to_string()]; + +fn ChildWithRef(cx: Scope) -> Element { + let names = use_atom_ref(&cx, NAMES); + + cx.render(rsx! { + div { + ul { + names.read().iter().map(|f| rsx!{ + li { "hello: {f}" } + }) + } + button { + onclick: move |_| { + let names = names.clone(); + cx.spawn(async move { + names.write().push("asd".to_string()); + }) + } + } + } + }) +} diff --git a/packages/fermi/src/hooks/atom_ref.rs b/packages/fermi/src/hooks/atom_ref.rs index da9ad9367..f9c7f2869 100644 --- a/packages/fermi/src/hooks/atom_ref.rs +++ b/packages/fermi/src/hooks/atom_ref.rs @@ -34,6 +34,17 @@ pub struct UseAtomRef { scope_id: ScopeId, } +impl Clone for UseAtomRef { + fn clone(&self) -> Self { + Self { + ptr: self.ptr, + value: self.value.clone(), + root: self.root.clone(), + scope_id: self.scope_id, + } + } +} + impl UseAtomRef { pub fn read(&self) -> Ref { self.value.borrow() From 07529e491cf85a5fd81d5c7718c43a41432c9468 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sun, 24 Apr 2022 20:51:52 -0400 Subject: [PATCH 2/2] fix: subscription should apply internally to hook --- examples/fermi.rs | 3 ++- packages/fermi/src/hooks/atom_ref.rs | 40 +++++++++++++++++++--------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/examples/fermi.rs b/examples/fermi.rs index 9f87961b3..79e3da1d6 100644 --- a/examples/fermi.rs +++ b/examples/fermi.rs @@ -47,7 +47,8 @@ fn ChildWithRef(cx: Scope) -> Element { cx.spawn(async move { names.write().push("asd".to_string()); }) - } + }, + "Add name" } } }) diff --git a/packages/fermi/src/hooks/atom_ref.rs b/packages/fermi/src/hooks/atom_ref.rs index f9c7f2869..fe488ee2f 100644 --- a/packages/fermi/src/hooks/atom_ref.rs +++ b/packages/fermi/src/hooks/atom_ref.rs @@ -16,15 +16,35 @@ use std::{ pub fn use_atom_ref(cx: &ScopeState, atom: AtomRef) -> &UseAtomRef { let root = use_atom_root(cx); - cx.use_hook(|_| { + &cx.use_hook(|_| { root.initialize(atom); - UseAtomRef { - ptr: atom.unique_id(), - root: root.clone(), - scope_id: cx.scope_id(), - value: root.register(atom, cx.scope_id()), - } + ( + UseAtomRef { + ptr: atom.unique_id(), + root: root.clone(), + scope_id: cx.scope_id(), + value: root.register(atom, cx.scope_id()), + }, + AtomRefSubscription { + ptr: atom.unique_id(), + root: root.clone(), + scope_id: cx.scope_id(), + }, + ) }) + .0 +} + +pub struct AtomRefSubscription { + ptr: AtomId, + root: Rc, + scope_id: ScopeId, +} + +impl Drop for AtomRefSubscription { + fn drop(&mut self) { + self.root.unsubscribe(self.ptr, self.scope_id) + } } pub struct UseAtomRef { @@ -65,9 +85,3 @@ impl UseAtomRef { self.root.set(self.ptr, new); } } - -impl Drop for UseAtomRef { - fn drop(&mut self) { - self.root.unsubscribe(self.ptr, self.scope_id) - } -}