diff --git a/packages/signals/examples/iterator.rs b/packages/signals/examples/iterator.rs deleted file mode 100644 index 2f6484b55..000000000 --- a/packages/signals/examples/iterator.rs +++ /dev/null @@ -1,28 +0,0 @@ -use dioxus::prelude::*; -use dioxus_signals::*; - -fn main() { - dioxus_desktop::launch(App); -} - -#[component] -fn App(cx: Scope) -> Element { - let signal = use_signal(cx, || vec![String::from("Hello"), String::from("World")]); - - render! { - button { - onclick: move |_| { - signal.write().push(String::from("Hello")); - }, - "Add one" - } - for item in signal.iter_signals() { - Child { signal: item } - } - } -} - -#[component] -fn Child(cx: Scope, signal: MappedSignal) -> Element { - render! {"{signal:?}"} -} diff --git a/packages/signals/examples/option.rs b/packages/signals/examples/option.rs deleted file mode 100644 index c0d1746b7..000000000 --- a/packages/signals/examples/option.rs +++ /dev/null @@ -1,39 +0,0 @@ -use dioxus::prelude::*; -use dioxus_signals::*; - -fn main() { - dioxus_desktop::launch(App); -} - -#[component] -fn App(cx: Scope) -> Element { - let signal = use_signal(cx, || Some(String::from("Hello"))); - - render! { - button { - onclick: move |_| { - let new_value = (!signal.read().is_some()).then(|| String::from("Hello")); - signal.set(new_value); - }, - "Swap" - } - button { - onclick: move |_| { - if let Some(value) = &mut *signal.write() { - value.push_str(" World"); - } - }, - "Change" - } - if let Some(item) = signal.as_mapped_ref() { - render! { - Child { signal: item } - } - } - } -} - -#[component] -fn Child(cx: Scope, signal: MappedSignal) -> Element { - render! {"{signal:?}"} -} diff --git a/packages/signals/src/impls.rs b/packages/signals/src/impls.rs index 7429f5886..27ac8849b 100644 --- a/packages/signals/src/impls.rs +++ b/packages/signals/src/impls.rs @@ -1,6 +1,5 @@ use crate::rt::CopyValue; use crate::signal::{ReadOnlySignal, Signal, Write}; -use crate::MappedSignal; use crate::SignalData; use generational_box::Mappable; use generational_box::{MappableMut, Storage}; @@ -333,7 +332,7 @@ pub struct CopyValueIterator>> { } impl>> Iterator for CopyValueIterator { - type Item = S::Ref; + type Item = >>::Mapped; fn next(&mut self) -> Option { let index = self.index; @@ -343,9 +342,9 @@ impl>> Iterator for CopyValueIterator { } impl>> IntoIterator for CopyValue, S> { - type IntoIter = S::Ref; + type IntoIter = CopyValueIterator; - type Item = GenerationalRef; + type Item = >>::Mapped; fn into_iter(self) -> Self::IntoIter { CopyValueIterator { @@ -378,7 +377,9 @@ pub struct SignalIterator>>> { } impl>>> Iterator for SignalIterator { - type Item = S::Ref; + type Item = <<>>>::Ref as Mappable>>>::Mapped< + Vec, + > as Mappable>>::Mapped; fn next(&mut self) -> Option { let index = self.index; @@ -390,7 +391,9 @@ impl>>> Iterator for SignalIterator { impl>>> IntoIterator for Signal, S> { type IntoIter = SignalIterator; - type Item = GenerationalRef; + type Item = <<>>>::Ref as Mappable>>>::Mapped< + Vec, + > as Mappable>>::Mapped; fn into_iter(self) -> Self::IntoIter { SignalIterator { @@ -400,23 +403,6 @@ impl>>> IntoIterator for Signal, } } -/// An iterator over items in a `Signal>` that yields [`MappedSignal`]s. -pub struct MappedSignalIterator>>> { - index: usize, - length: usize, - value: Signal, S>, -} - -impl>>> Iterator for MappedSignalIterator { - type Item = MappedSignal; - - fn next(&mut self) -> Option { - let index = self.index; - self.index += 1; - (index < self.length).then(|| self.value.map(move |v| v.get(index).unwrap())) - } -} - impl>>> Signal, S> where <>>>::Mut as MappableMut< @@ -439,15 +425,6 @@ where > { Write::filter_map(self.write(), |v| v.get_mut(index)) } - - /// Create an iterator of [`MappedSignal`]s over the inner vector. - pub fn iter_signals(&self) -> MappedSignalIterator { - MappedSignalIterator { - index: 0, - length: self.read().len(), - value: *self, - } - } } impl>>> Signal, S> { @@ -455,13 +432,4 @@ impl>>> Signal, S> { pub fn as_mut(&self) -> Option>>>::Mut as MappableMut>>>::Mapped> as MappableMut>>::Mapped, S, Option>>{ Write::filter_map(self.write(), |v| v.as_mut()) } - - /// Try to create a [`MappedSignal`] over the inner value. - pub fn as_mapped_ref(&self) -> Option> { - if self.read().is_some() { - Some(self.map(|v| v.as_ref().unwrap())) - } else { - None - } - } } diff --git a/packages/signals/src/map.rs b/packages/signals/src/map.rs index 13555e265..6c02b8553 100644 --- a/packages/signals/src/map.rs +++ b/packages/signals/src/map.rs @@ -1,40 +1,54 @@ use crate::CopyValue; use crate::Signal; +use crate::SignalData; use dioxus_core::ScopeId; -use generational_box::GenerationalRef; +use generational_box::Mappable; +use generational_box::Storage; use std::fmt::Debug; use std::fmt::Display; /// A read only signal that has been mapped to a new type. pub struct MappedSignal { origin_scope: ScopeId, - mapping: CopyValue GenerationalRef>>, + mapping: CopyValue U>>, } -impl MappedSignal { +impl MappedSignal<()> { /// Create a new mapped signal. - pub fn new(signal: Signal, mapping: impl Fn(&T) -> &U + 'static) -> Self { - Self { + pub fn new>, U>( + signal: Signal, + mapping: impl Fn(&T) -> &U + 'static, + ) -> MappedSignal< + <<>>::Ref as Mappable>>::Mapped< + T, + > as generational_box::Mappable>::Mapped, + > { + MappedSignal { origin_scope: signal.origin_scope(), mapping: CopyValue::new(Box::new(move || { - GenerationalRef::map(signal.read(), |v| (mapping)(v)) + <<>>::Ref as Mappable>>::Mapped>::map( + signal.read(), + &mapping, + ) })), } } +} +impl MappedSignal { /// Get the scope that the signal was created in. pub fn origin_scope(&self) -> ScopeId { self.origin_scope } /// Get the current value of the signal. This will subscribe the current scope to the signal. - pub fn read(&self) -> GenerationalRef { + pub fn read(&self) -> U { (self.mapping.read())() } /// Run a closure with a reference to the signal's value. - pub fn with(&self, f: impl FnOnce(&U) -> O) -> O { - f(&*self.read()) + pub fn with(&self, f: impl FnOnce(U) -> O) -> O { + f(self.read()) } } @@ -59,42 +73,20 @@ impl std::clone::Clone for MappedSignal { impl Copy for MappedSignal {} -impl Display for MappedSignal { +impl Display for MappedSignal { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.with(|v| Display::fmt(v, f)) + self.with(|v| Display::fmt(&v, f)) } } -impl Debug for MappedSignal { +impl Debug for MappedSignal { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.with(|v| Debug::fmt(v, f)) - } -} - -impl MappedSignal> { - /// Read a value from the inner vector. - pub fn get(&self, index: usize) -> Option> { - GenerationalRef::filter_map(self.read(), |v| v.get(index)) - } -} - -impl MappedSignal> { - /// Unwraps the inner value and clones it. - pub fn unwrap(&self) -> U - where - U: Clone, - { - self.with(|v| v.clone()).unwrap() - } - - /// Attemps to read the inner value of the Option. - pub fn as_ref(&self) -> Option> { - GenerationalRef::filter_map(self.read(), |v| v.as_ref()) + self.with(|v| Debug::fmt(&v, f)) } } impl std::ops::Deref for MappedSignal { - type Target = dyn Fn() -> GenerationalRef; + type Target = dyn Fn() -> T; fn deref(&self) -> &Self::Target { // https://github.com/dtolnay/case-studies/tree/master/callable-types diff --git a/packages/signals/src/signal.rs b/packages/signals/src/signal.rs index bdb426761..96c455b25 100644 --- a/packages/signals/src/signal.rs +++ b/packages/signals/src/signal.rs @@ -394,7 +394,14 @@ impl>> Signal { } /// Map the signal to a new type. - pub fn map(self, f: impl Fn(&T) -> &O + 'static) -> MappedSignal { + pub fn map( + self, + f: impl Fn(&T) -> &O + 'static, + ) -> MappedSignal< + <<>>::Ref as generational_box::Mappable< + SignalData, + >>::Mapped as generational_box::Mappable>::Mapped, + > { MappedSignal::new(self, f) }