diff --git a/packages/generational-box/src/lib.rs b/packages/generational-box/src/lib.rs index 87941c99e..040fb842b 100644 --- a/packages/generational-box/src/lib.rs +++ b/packages/generational-box/src/lib.rs @@ -250,19 +250,25 @@ impl Default for SyncStorage { pub trait Mappable: Deref { type Mapped: Mappable + Deref; - fn map(_self: Self, f: fn(&T) -> &U) -> Self::Mapped; + fn map(_self: Self, f: impl FnOnce(&T) -> &U) -> Self::Mapped; - fn try_map(_self: Self, f: fn(&T) -> Option<&U>) -> Option>; + fn try_map( + _self: Self, + f: impl FnOnce(&T) -> Option<&U>, + ) -> Option>; } impl Mappable for Ref<'static, T> { type Mapped = Ref<'static, U>; - fn map(_self: Self, f: fn(&T) -> &U) -> Self::Mapped { + fn map(_self: Self, f: impl FnOnce(&T) -> &U) -> Self::Mapped { Ref::map(_self, f) } - fn try_map(_self: Self, f: fn(&T) -> Option<&U>) -> Option> { + fn try_map( + _self: Self, + f: impl FnOnce(&T) -> Option<&U>, + ) -> Option> { Ref::try_map(_self, f) } } @@ -270,11 +276,14 @@ impl Mappable for Ref<'static, T> { impl Mappable for MappedRwLockReadGuard<'static, T> { type Mapped = MappedRwLockReadGuard<'static, U>; - fn map(_self: Self, f: fn(&T) -> &U) -> Self::Mapped { + fn map(_self: Self, f: impl FnOnce(&T) -> &U) -> Self::Mapped { MappedRwLockReadGuard::map(_self, f) } - fn try_map(_self: Self, f: fn(&T) -> Option<&U>) -> Option> { + fn try_map( + _self: Self, + f: impl FnOnce(&T) -> Option<&U>, + ) -> Option> { MappedRwLockReadGuard::try_map(_self, f).ok() } } @@ -320,7 +329,7 @@ impl MappableMut for MappedRwLockWriteGuard<'static, T> { } } -pub trait Storage: Copy + AnyStorage { +pub trait Storage: Copy + AnyStorage + 'static { type Ref: Mappable + Deref; type Mut: MappableMut + DerefMut; diff --git a/packages/signals/src/impls.rs b/packages/signals/src/impls.rs index a217dfaa4..bf994cf4b 100644 --- a/packages/signals/src/impls.rs +++ b/packages/signals/src/impls.rs @@ -3,7 +3,7 @@ use crate::signal::{ReadOnlySignal, Signal, Write}; use crate::SignalData; use generational_box::Mappable; use generational_box::{MappableMut, Storage}; -use parking_lot::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; +use std::ops::Deref; use std::{ fmt::{Debug, Display}, @@ -11,60 +11,38 @@ use std::{ }; macro_rules! read_impls { - ($ty:ident) => { - impl> Default for $ty { + ($ty:ident, $bound:path) => { + impl Default for $ty { fn default() -> Self { Self::new(Default::default()) } } - impl> std::clone::Clone for $ty { + impl std::clone::Clone for $ty { fn clone(&self) -> Self { *self } } - impl + Copy> Copy for $ty {} + impl Copy for $ty {} - impl> Display for $ty { + impl Display for $ty { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Display::fmt(v, f)) } } - impl> Debug for $ty { + impl Debug for $ty { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Debug::fmt(v, f)) } } - - impl> $ty, S> { - /// Read a value from the inner vector. - pub fn get(&self, index: usize) -> Option> { - MappedRwLockReadGuard::try_map(self.read(), |v| v.get(index)).ok() - } - } - - impl> $ty, S> { - /// Unwraps the inner value and clones it. - pub fn unwrap(&self) -> T - where - T: Clone, - { - self.with(|v| v.clone()).unwrap() - } - - /// Attemps to read the inner value of the Option. - pub fn as_ref(&self) -> Option> { - MappedRwLockReadGuard::try_map(self.read(), |v| v.as_ref()).ok() - } - } }; } macro_rules! write_impls { - ($ty:ident) => { - impl + Copy + 'static, S: Storage> std::ops::Add for $ty { + ($ty:ident, $bound:path, $vec_bound:path) => { + impl + Copy + 'static, S: $bound> std::ops::Add for $ty { type Output = T; fn add(self, rhs: T) -> Self::Output { @@ -72,23 +50,19 @@ macro_rules! write_impls { } } - impl + Copy + 'static, S: Storage> std::ops::AddAssign - for $ty - { + impl + Copy + 'static, S: $bound> std::ops::AddAssign for $ty { fn add_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v + rhs) } } - impl + Copy + 'static, S: Storage> std::ops::SubAssign - for $ty - { + impl + Copy + 'static, S: $bound> std::ops::SubAssign for $ty { fn sub_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v - rhs) } } - impl + Copy + 'static, S: Storage> std::ops::Sub for $ty { + impl + Copy + 'static, S: $bound> std::ops::Sub for $ty { type Output = T; fn sub(self, rhs: T) -> Self::Output { @@ -96,15 +70,13 @@ macro_rules! write_impls { } } - impl + Copy + 'static, S: Storage> std::ops::MulAssign - for $ty - { + impl + Copy + 'static, S: $bound> std::ops::MulAssign for $ty { fn mul_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v * rhs) } } - impl + Copy + 'static, S: Storage> std::ops::Mul for $ty { + impl + Copy + 'static, S: $bound> std::ops::Mul for $ty { type Output = T; fn mul(self, rhs: T) -> Self::Output { @@ -112,15 +84,13 @@ macro_rules! write_impls { } } - impl + Copy + 'static, S: Storage> std::ops::DivAssign - for $ty - { + impl + Copy + 'static, S: $bound> std::ops::DivAssign for $ty { fn div_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v / rhs) } } - impl + Copy + 'static, S: Storage> std::ops::Div for $ty { + impl + Copy + 'static, S: $bound> std::ops::Div for $ty { type Output = T; fn div(self, rhs: T) -> Self::Output { @@ -128,7 +98,7 @@ macro_rules! write_impls { } } - impl> $ty, S> { + impl $ty, S> { /// Pushes a new value to the end of the vector. pub fn push(&self, value: T) { self.with_mut(|v| v.push(value)) @@ -179,54 +149,154 @@ macro_rules! write_impls { self.with_mut(|v| v.split_off(at)) } } - - impl> $ty, S> { - /// Takes the value out of the Option. - pub fn take(&self) -> Option { - self.with_mut(|v| v.take()) - } - - /// Replace the value in the Option. - pub fn replace(&self, value: T) -> Option { - self.with_mut(|v| v.replace(value)) - } - - /// Gets the value out of the Option, or inserts the given value if the Option is empty. - pub fn get_or_insert(&self, default: T) -> S::Ref { - self.get_or_insert_with(|| default) - } - - /// Gets the value out of the Option, or inserts the value returned by the given function if the Option is empty. - pub fn get_or_insert_with( - &self, - default: impl FnOnce() -> T, - ) -> >::Mapped { - let borrow = self.read(); - if borrow.is_none() { - drop(borrow); - self.with_mut(|v| *v = Some(default())); - S::Ref::map(self.read(), |v| v.as_ref().unwrap()) - } else { - S::Ref::map(borrow, |v| v.as_ref().unwrap()) - } - } - } }; } -read_impls!(CopyValue); -write_impls!(CopyValue); -read_impls!(Signal); -write_impls!(Signal); -read_impls!(ReadOnlySignal); +read_impls!(CopyValue, Storage); + +impl>> CopyValue, S> { + /// Read a value from the inner vector. + pub fn get(&self, index: usize) -> Option<>>::Mapped> { + S::Ref::try_map(self.read(), move |v| v.get(index)) + } +} + +impl>> CopyValue, S> { + /// Unwraps the inner value and clones it. + pub fn unwrap(&self) -> T + where + T: Clone, + { + self.with(|v| v.clone()).unwrap() + } + + /// Attempts to read the inner value of the Option. + pub fn as_ref(&self) -> Option<>>::Mapped> { + S::Ref::try_map(self.read(), |v| v.as_ref()) + } +} + +write_impls!(CopyValue, Storage, Storage>); + +impl>> CopyValue, S> { + /// Takes the value out of the Option. + pub fn take(&self) -> Option { + self.with_mut(|v| v.take()) + } + + /// Replace the value in the Option. + pub fn replace(&self, value: T) -> Option { + self.with_mut(|v| v.replace(value)) + } + + /// Gets the value out of the Option, or inserts the given value if the Option is empty. + pub fn get_or_insert(&self, default: T) -> >>::Mapped { + self.get_or_insert_with(|| default) + } + + /// Gets the value out of the Option, or inserts the value returned by the given function if the Option is empty. + pub fn get_or_insert_with( + &self, + default: impl FnOnce() -> T, + ) -> >>::Mapped { + let borrow = self.read(); + if borrow.is_none() { + drop(borrow); + self.with_mut(|v| *v = Some(default())); + S::Ref::map(self.read(), |v| v.as_ref().unwrap()) + } else { + S::Ref::map(borrow, |v| v.as_ref().unwrap()) + } + } +} + +read_impls!(Signal, Storage>); + +impl>>> Signal, S> { + /// Read a value from the inner vector. + pub fn get( + &self, + index: usize, + ) -> Option< + <<>>>::Ref as Mappable>>>::Mapped> as Mappable< + Vec, + >>::Mapped, + >{ + <>>>::Ref as Mappable>>>::Mapped::>::try_map(self.read(), move |v| v.get(index)) + } +} + +impl>>> Signal, S> { + /// Unwraps the inner value and clones it. + pub fn unwrap(&self) -> T + where + T: Clone, + { + self.with(|v| v.clone()).unwrap() + } + + /// Attempts to read the inner value of the Option. + pub fn as_ref( + &self, + ) -> Option< + <<>>>::Ref as Mappable>>>::Mapped< + Option, + > as Mappable>>::Mapped, + > { + <>>>::Ref as Mappable>>>::Mapped::< + Option, + >::try_map(self.read(), |v| v.as_ref()) + } +} + +write_impls!(Signal, Storage>, Storage>>); + +impl>>> Signal, S> { + /// Takes the value out of the Option. + pub fn take(&self) -> Option { + self.with_mut(|v| v.take()) + } + + /// Replace the value in the Option. + pub fn replace(&self, value: T) -> Option { + self.with_mut(|v| v.replace(value)) + } + + /// Gets the value out of the Option, or inserts the given value if the Option is empty. + pub fn get_or_insert(&self, default: T) -> <>>>::Mapped> as Mappable>>::Mapped{ + self.get_or_insert_with(|| default) + } + + /// Gets the value out of the Option, or inserts the value returned by the given function if the Option is empty. + pub fn get_or_insert_with( + &self, + default: impl FnOnce() -> T, + ) -><>>>::Mapped> as Mappable>>::Mapped{ + let borrow = self.read(); + if borrow.is_none() { + drop(borrow); + self.with_mut(|v| *v = Some(default())); + >>>::Mapped::>::map( + self.read(), + |v| v.as_ref().unwrap(), + ) + } else { + >>>::Mapped::>::map(borrow, |v| { + v.as_ref().unwrap() + }) + } + } +} + +read_impls!(ReadOnlySignal, Storage>); /// An iterator over the values of a `CopyValue>`. -pub struct CopyValueIterator> { +pub struct CopyValueIterator>> { index: usize, value: CopyValue, S>, } -impl> Iterator for CopyValueIterator { +impl>> Iterator for CopyValueIterator { type Item = T; fn next(&mut self) -> Option { @@ -236,7 +306,7 @@ impl> Iterator for CopyValueIterator { } } -impl> IntoIterator for CopyValue, S> { +impl>> IntoIterator for CopyValue, S> { type IntoIter = CopyValueIterator; type Item = T; @@ -266,12 +336,12 @@ impl>> CopyValue, S> { } /// An iterator over items in a `Signal>`. -pub struct SignalIterator> { +pub struct SignalIterator>>> { index: usize, value: Signal, S>, } -impl> Iterator for SignalIterator { +impl>>> Iterator for SignalIterator { type Item = T; fn next(&mut self) -> Option { @@ -281,7 +351,7 @@ impl> Iterator for SignalIterator { } } -impl> IntoIterator for Signal, S> { +impl>>> IntoIterator for Signal, S> { type IntoIter = SignalIterator; type Item = T; diff --git a/packages/signals/src/rt.rs b/packages/signals/src/rt.rs index 7ae6365f7..a6005748a 100644 --- a/packages/signals/src/rt.rs +++ b/packages/signals/src/rt.rs @@ -41,11 +41,10 @@ fn owner_in_scope, T>(scope: ScopeId) -> Rc> { // } } -#[derive(Debug)] /// CopyValue is a wrapper around a value to make the value mutable and Copy. /// /// It is internally backed by [`generational_box::GenerationalBox`]. -pub struct CopyValue { +pub struct CopyValue> { pub(crate) value: GenerationalBox, origin_scope: ScopeId, } diff --git a/packages/signals/src/signal.rs b/packages/signals/src/signal.rs index 501f736dd..61186b92c 100644 --- a/packages/signals/src/signal.rs +++ b/packages/signals/src/signal.rs @@ -90,7 +90,7 @@ pub fn use_signal(cx: &ScopeState, f: impl FnOnce() -> T) -> Signal< pub fn use_signal_sync( cx: &ScopeState, f: impl FnOnce() -> T, -) -> Signal { +) -> Signal { // *cx.use_hook(|| Signal::new(f())) todo!() } @@ -130,7 +130,8 @@ pub(crate) struct SignalSubscribers { pub(crate) effect_subscribers: Vec, } -pub(crate) struct SignalData { +/// The data stored for tracking in a signal. +pub struct SignalData { pub(crate) subscribers: Arc>, pub(crate) update_any: Arc, pub(crate) effect_stack: EffectStack, @@ -341,7 +342,7 @@ impl>> PartialEq for Signal { } } -impl>> Deref for Signal { +impl> + 'static> Deref for Signal { type Target = dyn Fn() -> <>>::Ref as Mappable>>::Mapped; @@ -481,7 +482,7 @@ impl>> PartialEq for ReadOnlySignal { } } -impl>> Deref for ReadOnlySignal { +impl> + 'static> Deref for ReadOnlySignal { type Target = dyn Fn() -> <>>::Ref as Mappable>>::Mapped;