pub struct RwSignal<T, S = SyncStorage> { /* private fields */ }Expand description
The reactive-programming vocabulary Component state is built
on: signals, memos, and context, flat-re-exported from frust-reactive/
reactive_graph so app authors never name either crate directly.
An arena-allocated signal that can be read from or written to.
A signal is a piece of data that may change over time, and notifies other code when it has changed. This is the atomic unit of reactivity, which begins all other processes of reactive updates.
This is an arena-allocated signal, which is Copy and is disposed when its reactive
Owner cleans up. For a reference-counted signal that lives
as long as a reference to it is alive, see ArcRwSignal.
§Core Trait Implementations
§Reading the Value
.get()clones the current value of the signal. If you call it within an effect, it will cause that effect to subscribe to the signal, and to re-run whenever the value of the signal changes..get_untracked()clones the value of the signal without reactively tracking it.
.read()returns a guard that allows accessing the value of the signal by reference. If you call it within an effect, it will cause that effect to subscribe to the signal, and to re-run whenever the value of the signal changes..read_untracked()gives access to the current value of the signal without reactively tracking it.
.with()allows you to reactively access the signal’s value without cloning by applying a callback function..with_untracked()allows you to access the signal’s value by applying a callback function without reactively tracking it.
.to_stream()converts the signal to anasyncstream of values.
§Updating the Value
.set()sets the signal to a new value..update()updates the value of the signal by applying a closure that takes a mutable reference..write()returns a guard through which the signal can be mutated, and which notifies subscribers when it is dropped.
Each of these has a related
_untracked()method, which updates the signal without notifying subscribers. Untracked updates are not desirable in most cases, as they cause “tearing” between the signal’s value and its observed value. If you want a non-reactive container, usedArenaIteminstead.
§Examples
let count = ArcRwSignal::new(0);
// ✅ calling the getter clones and returns the value
// this can be `count()` on nightly
assert_eq!(count.get(), 0);
// ✅ calling the setter sets the value
// this can be `set_count(1)` on nightly
count.set(1);
assert_eq!(count.get(), 1);
// ❌ you could call the getter within the setter
// set_count.set(count.get() + 1);
// ✅ however it's more efficient to use .update() and mutate the value in place
count.update(|count: &mut i32| *count += 1);
assert_eq!(count.get(), 2);
// ✅ you can create "derived signals" with a Fn() -> T interface
let double_count = {
// clone before moving into the closure because we use it below
let count = count.clone();
move || count.get() * 2
};
count.set(0);
assert_eq!(double_count(), 0);
count.set(1);
assert_eq!(double_count(), 2);Implementations§
Source§impl<T, S> RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>>,
impl<T, S> RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>>,
Sourcepub fn new_with_storage(value: T) -> RwSignal<T, S>
pub fn new_with_storage(value: T) -> RwSignal<T, S>
Creates a new signal with the given arena storage method.
Source§impl<T> RwSignal<T, LocalStorage>where
T: 'static,
impl<T> RwSignal<T, LocalStorage>where
T: 'static,
Sourcepub fn new_local(value: T) -> RwSignal<T, LocalStorage>
pub fn new_local(value: T) -> RwSignal<T, LocalStorage>
Creates a new signal, taking the initial value as its argument. Unlike RwSignal::new,
this pins the value to the current thread. Accessing it from any other thread will panic.
Source§impl<T, S> RwSignal<T, S>
impl<T, S> RwSignal<T, S>
Sourcepub fn read_only(&self) -> ReadSignal<T, S>
pub fn read_only(&self) -> ReadSignal<T, S>
Returns a read-only handle to the signal.
Source§impl<T, S> RwSignal<T, S>
impl<T, S> RwSignal<T, S>
Sourcepub fn write_only(&self) -> WriteSignal<T, S>
pub fn write_only(&self) -> WriteSignal<T, S>
Returns a write-only handle to the signal.
Source§impl<T, S> RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>> + Storage<ArcWriteSignal<T>> + Storage<ArcReadSignal<T>>,
impl<T, S> RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>> + Storage<ArcWriteSignal<T>> + Storage<ArcReadSignal<T>>,
Sourcepub fn split(&self) -> (ReadSignal<T, S>, WriteSignal<T, S>)
pub fn split(&self) -> (ReadSignal<T, S>, WriteSignal<T, S>)
Splits the signal into its readable and writable halves.
Sourcepub fn unite(
read: ReadSignal<T, S>,
write: WriteSignal<T, S>,
) -> Option<RwSignal<T, S>>
pub fn unite( read: ReadSignal<T, S>, write: WriteSignal<T, S>, ) -> Option<RwSignal<T, S>>
Reunites the two halves of a signal. Returns None if the two signals
provided were not created from the same signal.
Trait Implementations§
impl<T, S> Copy for RwSignal<T, S>
Source§impl<T, S> DefinedAt for RwSignal<T, S>
impl<T, S> DefinedAt for RwSignal<T, S>
Source§fn defined_at(&self) -> Option<&'static Location<'static>>
fn defined_at(&self) -> Option<&'static Location<'static>>
None in
release mode.impl<T, S> Eq for RwSignal<T, S>
Source§impl<'a, T> From<&'a ArcRwSignal<T>> for RwSignal<T>
impl<'a, T> From<&'a ArcRwSignal<T>> for RwSignal<T>
Source§fn from(value: &'a ArcRwSignal<T>) -> RwSignal<T>
fn from(value: &'a ArcRwSignal<T>) -> RwSignal<T>
Source§impl<T> From<ArcRwSignal<T>> for RwSignal<T>
impl<T> From<ArcRwSignal<T>> for RwSignal<T>
Source§fn from(value: ArcRwSignal<T>) -> RwSignal<T>
fn from(value: ArcRwSignal<T>) -> RwSignal<T>
Source§impl<T> FromLocal<ArcRwSignal<T>> for RwSignal<T, LocalStorage>where
T: 'static,
impl<T> FromLocal<ArcRwSignal<T>> for RwSignal<T, LocalStorage>where
T: 'static,
Source§fn from_local(value: ArcRwSignal<T>) -> RwSignal<T, LocalStorage>
fn from_local(value: ArcRwSignal<T>) -> RwSignal<T, LocalStorage>
Source§impl<T, S> IsDisposed for RwSignal<T, S>where
T: 'static,
impl<T, S> IsDisposed for RwSignal<T, S>where
T: 'static,
Source§fn is_disposed(&self) -> bool
fn is_disposed(&self) -> bool
true, the signal cannot be accessed without a panic.Source§impl<T, S> ReadUntracked for RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>>,
impl<T, S> ReadUntracked for RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>>,
Source§type Value = ReadGuard<T, Plain<T>>
type Value = ReadGuard<T, Plain<T>>
Source§fn try_read_untracked(&self) -> Option<<RwSignal<T, S> as ReadUntracked>::Value>
fn try_read_untracked(&self) -> Option<<RwSignal<T, S> as ReadUntracked>::Value>
None if the signal has already been disposed.Source§fn read_untracked(&self) -> Self::Value
fn read_untracked(&self) -> Self::Value
Source§fn custom_try_read(&self) -> Option<Option<Self::Value>>
fn custom_try_read(&self) -> Option<Option<Self::Value>>
Read::try_read implementation despite it being auto implemented. Read moreSource§impl<T, S> Write for RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>>,
impl<T, S> Write for RwSignal<T, S>where
T: 'static,
S: Storage<ArcRwSignal<T>>,
Source§fn try_write(&self) -> Option<impl UntrackableGuard>
fn try_write(&self) -> Option<impl UntrackableGuard>
None if the signal has already been disposed.Source§fn try_write_untracked(
&self,
) -> Option<UntrackedWriteGuard<<RwSignal<T, S> as Write>::Value>>
fn try_write_untracked( &self, ) -> Option<UntrackedWriteGuard<<RwSignal<T, S> as Write>::Value>>
None if the signal has already been disposed.Source§fn write(&self) -> impl UntrackableGuard
fn write(&self) -> impl UntrackableGuard
Source§fn write_untracked(&self) -> impl DerefMut
fn write_untracked(&self) -> impl DerefMut
Auto Trait Implementations§
impl<T, S> Freeze for RwSignal<T, S>
impl<T, S> RefUnwindSafe for RwSignal<T, S>
impl<T, S> Send for RwSignal<T, S>
impl<T, S> Sync for RwSignal<T, S>
impl<T, S> Unpin for RwSignal<T, S>
impl<T, S> UnsafeUnpin for RwSignal<T, S>
impl<T, S> UnwindSafe for RwSignal<T, S>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<T> Brush for T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Get for T
impl<T> Get for T
Source§impl<T> GetUntracked for T
impl<T> GetUntracked for T
Source§type Value = <T as WithUntracked>::Value
type Value = <T as WithUntracked>::Value
Source§fn try_get_untracked(&self) -> Option<<T as GetUntracked>::Value>
fn try_get_untracked(&self) -> Option<<T as GetUntracked>::Value>
None if the signal has already been disposed.Source§fn get_untracked(&self) -> Self::Value
fn get_untracked(&self) -> Self::Value
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> ReactiveNode for Twhere
T: AsSubscriberSet + DefinedAt,
impl<T> ReactiveNode for Twhere
T: AsSubscriberSet + DefinedAt,
Source§fn mark_dirty(&self)
fn mark_dirty(&self)
Source§fn mark_check(&self)
fn mark_check(&self)
Source§fn mark_subscribers_check(&self)
fn mark_subscribers_check(&self)
Source§fn update_if_necessary(&self) -> bool
fn update_if_necessary(&self) -> bool
Source§impl<T> Read for Twhere
T: Track + ReadUntracked,
impl<T> Read for Twhere
T: Track + ReadUntracked,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Set for Twhere
T: Update + IsDisposed,
impl<T> Set for Twhere
T: Update + IsDisposed,
Source§impl<T> Source for Twhere
T: AsSubscriberSet + DefinedAt,
impl<T> Source for Twhere
T: AsSubscriberSet + DefinedAt,
Source§fn clear_subscribers(&self)
fn clear_subscribers(&self)
Source§fn add_subscriber(&self, subscriber: AnySubscriber)
fn add_subscriber(&self, subscriber: AnySubscriber)
Source§fn remove_subscriber(&self, subscriber: &AnySubscriber)
fn remove_subscriber(&self, subscriber: &AnySubscriber)
Source§impl<T> StorageAccess<T> for T
impl<T> StorageAccess<T> for T
Source§fn as_borrowed(&self) -> &T
fn as_borrowed(&self) -> &T
Source§fn into_taken(self) -> T
fn into_taken(self) -> T
Source§impl<T> ToAnySource for Twhere
T: AsSubscriberSet + DefinedAt + IsDisposed,
<T as AsSubscriberSet>::Output: Borrow<Arc<RwLock<SubscriberSet>>>,
impl<T> ToAnySource for Twhere
T: AsSubscriberSet + DefinedAt + IsDisposed,
<T as AsSubscriberSet>::Output: Borrow<Arc<RwLock<SubscriberSet>>>,
Source§fn to_any_source(&self) -> AnySource
fn to_any_source(&self) -> AnySource
Source§impl<T> Update for Twhere
T: Write,
impl<T> Update for Twhere
T: Write,
Source§fn try_maybe_update<U>(
&self,
fun: impl FnOnce(&mut <T as Update>::Value) -> (bool, U),
) -> Option<U>
fn try_maybe_update<U>( &self, fun: impl FnOnce(&mut <T as Update>::Value) -> (bool, U), ) -> Option<U>
(true, _), and returns the value returned by the update function,
or None if the signal has already been disposed.Source§fn update(&self, fun: impl FnOnce(&mut Self::Value))
fn update(&self, fun: impl FnOnce(&mut Self::Value))
Source§impl<T> UpdateUntracked for Twhere
T: Write,
impl<T> UpdateUntracked for Twhere
T: Write,
Source§fn try_update_untracked<U>(
&self,
fun: impl FnOnce(&mut <T as UpdateUntracked>::Value) -> U,
) -> Option<U>
fn try_update_untracked<U>( &self, fun: impl FnOnce(&mut <T as UpdateUntracked>::Value) -> U, ) -> Option<U>
None if the signal has already been disposed.
Does not notify subscribers that the signal has changed.impl<T> WasmNotSend for Twhere
T: Send,
impl<T> WasmNotSendSync for Twhere
T: WasmNotSend + WasmNotSync,
impl<T> WasmNotSync for Twhere
T: Sync,
Source§impl<T> With for Twhere
T: Read,
impl<T> With for Twhere
T: Read,
Source§type Value = <<T as Read>::Value as Deref>::Target
type Value = <<T as Read>::Value as Deref>::Target
Source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
Source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
Source§fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Source§impl<T> WithUntracked for Twhere
T: DefinedAt + ReadUntracked,
impl<T> WithUntracked for Twhere
T: DefinedAt + ReadUntracked,
Source§type Value = <<T as ReadUntracked>::Value as Deref>::Target
type Value = <<T as ReadUntracked>::Value as Deref>::Target
Source§fn try_with_untracked<U>(
&self,
fun: impl FnOnce(&<T as WithUntracked>::Value) -> U,
) -> Option<U>
fn try_with_untracked<U>( &self, fun: impl FnOnce(&<T as WithUntracked>::Value) -> U, ) -> Option<U>
None if the signal has already been disposed.