From c0315e55f47ce03a29722cae15f21cce6d549dc3 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sun, 1 Jan 2023 22:02:49 -0500 Subject: [PATCH] chore: more signals methods --- examples/signals.rs | 13 +----------- packages/signals/src/lib.rs | 40 +++++++++++++++++++++++++++---------- packages/signals/src/rt.rs | 18 +++++++++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/examples/signals.rs b/examples/signals.rs index 17f21f28d..17ae40b73 100644 --- a/examples/signals.rs +++ b/examples/signals.rs @@ -14,28 +14,17 @@ fn app(cx: Scope) -> Element { use_init_signal_rt(cx); let mut count = use_signal(cx, || 0); - let mut running = use_signal(cx, || false); use_coroutine(cx, |_: UnboundedReceiver<()>| async move { loop { - if running.get() { - count += 1; - } + count += 1; tokio::time::sleep(Duration::from_millis(100)).await; } }); cx.render(rsx! { h1 { "High-Five counter: {count}" } - button { onclick: move |_| count += 1, "Up high!" } button { onclick: move |_| count -= 1, "Down low!" } - - button { onclick: move |_| running.set(!running.get()), "Start counting" } - - - if count.get() > 3 { - rsx! ( h2 { "Nice!" } ) - } }) } diff --git a/packages/signals/src/lib.rs b/packages/signals/src/lib.rs index 9845372fe..2fcbdcdb2 100644 --- a/packages/signals/src/lib.rs +++ b/packages/signals/src/lib.rs @@ -1,4 +1,5 @@ use std::{ + cell::{Ref, RefMut}, fmt::Display, marker::PhantomData, ops::{Add, Div, Mul, Sub}, @@ -17,17 +18,29 @@ pub fn use_init_signal_rt(cx: &ScopeState) { } pub fn use_signal(cx: &ScopeState, f: impl FnOnce() -> T) -> Signal { - *cx.use_hook(|| { + cx.use_hook(|| { let rt: &'static SignalRt = cx.consume_context().unwrap(); let id = rt.init(f()); rt.subscribe(id, cx.scope_id()); - Signal { - rt, - id, - t: PhantomData, + struct SignalHook { + signal: Signal, + } + impl Drop for SignalHook { + fn drop(&mut self) { + self.signal.rt.remove(self.signal.id); + } + } + + SignalHook { + signal: Signal { + id, + rt, + t: PhantomData, + }, } }) + .signal } pub struct Signal { @@ -37,16 +50,21 @@ pub struct Signal { } impl Signal { + pub fn read(&self) -> Ref { + self.rt.read(self.id) + } + + pub fn write(&self) -> RefMut { + self.rt.write(self.id) + } + pub fn set(&mut self, value: T) { self.rt.set(self.id, value); } - pub fn map(&self, _f: impl FnOnce(T) -> U) -> Signal { - todo!() - } - - pub fn update(&self, _f: impl FnOnce(&mut T) -> O) { - todo!() + pub fn update(&self, _f: impl FnOnce(&mut T) -> O) -> O { + let mut write = self.write(); + _f(&mut *write) } } diff --git a/packages/signals/src/rt.rs b/packages/signals/src/rt.rs index bea3c6f98..c24e336f9 100644 --- a/packages/signals/src/rt.rs +++ b/packages/signals/src/rt.rs @@ -59,12 +59,30 @@ impl SignalRt { } } + pub fn remove(&self, id: usize) { + self.signals.borrow_mut().remove(id); + } + pub fn with(&self, id: usize, f: impl FnOnce(&T) -> O) -> O { let signals = self.signals.borrow(); let inner = &signals[id]; let inner = inner.value.downcast_ref::().unwrap(); f(&*inner) } + + pub(crate) fn read(&self, id: usize) -> std::cell::Ref { + let signals = self.signals.borrow(); + std::cell::Ref::map(signals, |signals| { + signals[id].value.downcast_ref::().unwrap() + }) + } + + pub(crate) fn write(&self, id: usize) -> std::cell::RefMut { + let mut signals = self.signals.borrow_mut(); + std::cell::RefMut::map(signals, |signals| { + signals[id].value.downcast_mut::().unwrap() + }) + } } struct Inner {