pub struct RxDAG<'c>(_, _);
Expand description

The centralized structure which contains all your interconnected reactive values.

This structure is a directed-acyclic-graph (DAG), hence why its called RxDAG. We don’t support computed values recursively depending on each other, which is why it’s acyclic. At the root/top of the DAG are your variables (Var), which you can explicitly set. All other values are CRxs, which are computed. CRx incoming edges are inputs, which are Vars and other CRxs. CRx outgoing edges are outputs, which are more CRxs, but there are also “edges” which just go nowhere, those are side-effects.

Performance notes

Currently no nodes (Vars or CRxs) are deallocated until the entire DAG is deallocated, so if you keep creating and discarding nodes you will leak memory (TODO fix this?)

Implementation

Internally this is a vector of interspersed nodes and edges. The edges refer to other nodes relative to their own position. Later Rxs must depend on earlier Rxs. “edges” can have zero outputs, those are side-effects as mentioned above.

When the DAG recomputes, it simply iterates through each node and edge in order and calls [RxDAGElem::recompute]. If the nodes were changed (directly or as edge output), they set their new value, and mark that they got recomputed. The edges will recompute and change their output nodes if any of their inputs got recomputed.

The DAG has interior mutability, in that it can add nodes without a mutable borrow. See elsa crate for why this is sound (though actually the soundness argument is contested). Internally we use a modified version of elsa and stable-deref-trait. which lets us return lifetime-parameterized values instead of references among other things.

Setting Vars is also interior mutability, and OK because we don’t use those values until [RxDAGElem::recompute].

The DAG and refs have an ID so that you can’t use one ref on another DAG, however this is checked at runtime. The lifetimes are checked at compile-time though.

Implementations

Create an empty DAG

Create a variable (Var) in this DAG.

Run a closure when inputs change, without creating any outputs (for side-effects).

Create a computed value (CRx) in this DAG.

Create 2 computed values (CRxs) in this DAG which are created from the same function.

Create 3 computed values (CRxs) in this DAG which are created from the same function.

Create 4 computed values (CRxs) in this DAG which are created from the same function.

Create 5 computed values (CRxs) in this DAG which are created from the same function.

Update all Vars with their new values and recompute CRxs.

This requires a shared reference and actually does the “reactive updates”.

Recomputes if necessary and then returns an RxContext you can use to get the current value.

Returns an RxContext you can use to get the current value. However any newly-set values or computations will not be returned until RxDAG::recompute is called.

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.