Crate calc_graph[−][src]
Use this crate to split a calculation into related sub-calculations, known as nodes.
You can push information from outside into one or more source nodes, and you can read results from one or more output nodes. Values are only calculated as they're needed, and cached as long as their inputs don't change. This means that recalculations are efficient when you only change some of the inputs, and if you don't request the value from an output node, its value is never calculated.
To structure your calculation as a graph:
- Create a
Graph
object:let graph = Graph::new()
. - Define one or more source nodes for your inputs:
let mut source = graph.source(initial_value);
. - Call
Node::map
,Node::zip
and related methods to define new nodes whose values are calculated from other nodes:let mut output = source.map(|n| n + 1);
. - Read values from the output nodes:
assert_eq!(initial_value + 1, output.get_mut())
. - As needed, push new values into your source nodes (call
source.set(next_value)
) and re-read your output nodes.
Sharing
Func nodes (created by Node::map
, Node::zip
and related methods) own their inputs (precedent nodes). When you
have a node that acts as an input to two or more func nodes, you need to use let input_node = input_node.shared()
first. This shared node can then be used multiple times via input_node.clone()
.
You can have multiple Graph
objects in the same program, but when you define a new node, its precedents must
come from the same graph.
Boxing
A Node
object remembers the full type information of its precedent nodes as well as the closure used to calculate
its value. This means that the name of the Node
type can be very long, or even impossible to write in the source
code. In this situation you can use let output_node: BoxNode<i32> = input_node.map(|n| n + 1).boxed();
.
A call to boxed()
is also needed if you want a variable that can hold either one or another node; these nodes can
have different concrete types, and calling boxed()
on each of them gives you a pair of nodes that have the same
type.
Threading
Node<Source>
, SharedNode
and BoxedNode
objects are Send
and Sync
, meaning they can be passed between
threads. Calculations are performed on the thread that calls node.get()
; calculations are not parallelised
automatically, although you can read separate output nodes from separate threads, even if they share parts of the
same graph as inputs.
Structs
Const |
Calculates a node's value by returning the same value every time. |
Func1 |
Calculates a value from another node. |
Func2 |
Calculates a value from 2 nodes. |
Func3 |
Calculates a value from 3 nodes. |
Func4 |
Calculates a value from 4 nodes. |
Func5 |
Calculates a value from 5 nodes. |
Func6 |
Calculates a value from 6 nodes. |
Func7 |
Calculates a value from 7 nodes. |
Func8 |
Calculates a value from 8 nodes. |
Graph |
Returns new |
Lazy |
Calculates a node's value by calling a function on demand and caching the result. |
Node |
Represents a value within the graph. |
Source |
Holds a value that can be updated directly from outside the graph. |
Traits
Calc |
Calculates a node's value. |
Functions
const_ |
Returns a node whose value never changes. |
lazy |
Returns a node whose value is calculated once on demand and cached. |
Type Definitions
BoxNode |
A node returned by |
SharedNode |
A node returned by |