pub struct Signal<T>{ /* private fields */ }Expand description
A reactive signal handle.
Allows reading, writing, and subscribing to changes.
Implements Clone and Copy for ergonomic use; all copies share the same
underlying state. The inner state lives in the global append-only signal
slab and the handle carries its slot index as a usize. The Copy
semantics are safe because only the slot index is copied — the actual
slot is owned by the slab and is never freed or recycled.
Implementations§
Source§impl<T> Signal<T>
Implementation of reactive signal operations.
impl<T> Signal<T>
Implementation of reactive signal operations.
Sourcepub fn create(value: T) -> Self
pub fn create(value: T) -> Self
Creates a new Signal with the given initial value.
Stores the SignalInner<T> in the global slab ([SIGNAL_SLAB]) and
returns a Signal<T> handle carrying the slot index. The slab is
append-only: a slot always belongs to the Signal that created it,
so stale handles can never observe a recycled slot of a different
type.
§Arguments
T: Clone + PartialEq + 'static- The initial value of the signal.
§Returns
Self- A handle to the newly created reactive signal.
Sourcepub fn get(&self) -> T
pub fn get(&self) -> T
Returns the current value of the signal.
Directly reads the value from the slot stored in the global slab.
If the signal has been marked inactive (alive == false), returns the
last stored value without registering tracking dependencies. This
ensures that stale async callbacks (e.g., orphaned setInterval)
holding a Signal copy can still call .get() safely without
triggering side effects or panics.
If a tracking context is active (i.e., a DynamicNode is being rendered), automatically registers the current dynamic node as a dependent of this signal for precise reactive updates.
§Returns
T: Clone + PartialEq + 'static- The current value of the signal.
Sourcepub fn with<F, R>(&self, f: F) -> R
pub fn with<F, R>(&self, f: F) -> R
Read-only access to the signal value without cloning.
OPT 17: callers that only need to inspect the value (e.g. format!, eq
check, debug print, length) can borrow via with(|v| ...) and avoid
one T::clone per call. The closure runs under the same tracking
rules as get (still registers CURRENT_TRACKING_DYNAMIC_ID if a
DynamicNode is rendering). The T: Clone bound stays on the impl
because get is required by the existing public API; with is the
zero-copy alternative for new code.
§Arguments
F: FnOnce(&T) -> R- Closure receiving&T.
§Returns
R- Whatever the closure returns.
Sourcepub fn subscribe<F>(&self, callback: F) -> usizewhere
F: FnMut() + 'static,
pub fn subscribe<F>(&self, callback: F) -> usizewhere
F: FnMut() + 'static,
Subscribes a callback to be invoked when the signal changes.
Returns the subscription id, which can later be passed to
Signal::unsubscribe to detach exactly this listener. Framework
DOM bindings use the id to tear down a binding when its element is
removed; macro-generated watch! / computed! subscriptions keep
the id unused because their lifetime is the enclosing hook context.
§Arguments
FnMut() + 'static- The callback to invoke when the signal changes.
§Returns
usize- The subscription id.usize::MAXwhen the handle is stale (out-of-bounds slot); such an id is a safe no-op forunsubscribe.
Sourcepub fn unsubscribe(&self, id: usize)
pub fn unsubscribe(&self, id: usize)
Detaches a single listener previously registered by Signal::subscribe.
When called while the signal is mid-notification (a listener callback
triggered this call re-entrantly), the removal is deferred: the id is
recorded and filtered out during update’s merge-back pass, so the
detached listener cannot be resurrected into the live list.
§Arguments
usize- The subscription id returned bysubscribe.
Sourcepub fn set(&self, value: T)
pub fn set(&self, value: T)
Sets the value of the signal and notifies listeners.
Uses precise dirty marking: only dynamic nodes that depend on this signal are marked dirty, avoiding full broadcast.
When called inside batch, the dispatch is
deferred (dirty slots are still marked precisely), and the
outermost set() call outside the suppressed scope will
trigger the actual dispatch cycle.
§Arguments
T: Clone + PartialEq + 'static- The new value to assign to the signal.
Source§impl<T> Signal<T>
impl<T> Signal<T>
pub fn get_inner(&self) -> usize
pub fn get__marker(&self) -> PhantomData<fn() -> T>
Trait Implementations§
Source§impl<T> AsReactiveText for Signal<T>
Converts a signal into a reactive text node with listener wiring.
impl<T> AsReactiveText for Signal<T>
Converts a signal into a reactive text node with listener wiring.
Source§fn as_reactive_text(&self) -> VirtualNode
fn as_reactive_text(&self) -> VirtualNode
Creates a reactive text node that auto-updates when the signal changes.
The returned TextNode carries a binder closure instead of an
intermediate bridge signal. The binder runs exactly once per DOM text
node at materialization time: it subscribes the source signal directly
to that node (converting T to String on every change). The
listener self-unsubscribes the first time it observes the node as
detached — a removed text node never comes back (patch materialises
a fresh Text per mount), so without self-unsubscribe the listener
would live on the source signal’s list forever and pay one
is_connected crossing per set per dead node. Mid-notification
unsubscribe is deferred through removed_listener_ids, so the
self-removal is re-entrancy-safe. A kept text node keeps its single
subscription across any number of re-renders of its parent.
§Returns
VirtualNode- A text virtual node with reactive signal binding.
Source§impl<T> Clone for Signal<T>
Clones the signal, sharing the same inner state.
impl<T> Clone for Signal<T>
Clones the signal, sharing the same inner state.
Since Signal is Copy, this simply returns *self.
§Returns
Self- A copy of the signal handle sharing the same inner state.
impl<T> Copy for Signal<T>
Copies the signal, sharing the same inner state.
Safe because only the inner address (a usize) is copied;
the actual heap allocation is owned by the global signal registry.
Source§impl<T> Default for Signal<T>
Provides a safe default for Signal<T> by creating a valid signal
initialized with T::default().
impl<T> Default for Signal<T>
Provides a safe default for Signal<T> by creating a valid signal
initialized with T::default().
This prevents the creation of invalid signals with inner = 0 (null
pointer), which would cause a panic when .get() is called.
§Returns
Self- A valid signal initialized withT::default().
impl<T> Eq for Signal<T>
Source§impl From<Signal<String>> for AttributeValue
Converts a string signal into a reactive attribute value.
impl From<Signal<String>> for AttributeValue
Converts a string signal into a reactive attribute value.
Source§impl<T> From<Signal<T>> for VirtualNode
Converts a signal into a reactive text virtual node.
impl<T> From<Signal<T>> for VirtualNode
Converts a signal into a reactive text virtual node.
Source§impl From<Signal<bool>> for AttributeValue
Converts a mutable bool signal into a reactive attribute value.
impl From<Signal<bool>> for AttributeValue
Converts a mutable bool signal into a reactive attribute value.
The signal is mapped to a Signal<String> that yields "true" or "false",
enabling boolean attributes like checked to reactively update the DOM.