Proxies: graphs inside graphs#
A graph saved on the disk can be used as a single node of another graph, like a function of a library. This node is called a proxy node.
The interface of a graph#
A graph decides what it shows to the outside:
parameters: input sockets exposed with
Graph::expose_parameter(input, alias, show_as);results: output sockets exposed with
Graph::expose_result(output, alias, show_as).
The alias becomes the socket ID on the proxy node, show_as its name. Unexposed sockets are not
visible from the outside: their value is fixed by the graph itself.
Graph "examples.proxies.scale" Proxy node in another graph
┌──────────────────────────────────┐ ┌───────────────────────┐
│ BinaryOp │ │ scale#707093 │
│ a ◄── parameter "value" │ ===> │ ● value │
│ b ◄── parameter "factor" │ │ ● factor scaled ●
│ operation = "mul" (hidden) │ └───────────────────────┘
│ result ──► result "scaled" │
└──────────────────────────────────┘
Creating a proxy node#
Graph::add_proxy_node(qualifier):
returns
null_nodeifqualifieris the graph’s own qualifier (a graph can’t contain itself);reads the graph from the disk with
GraphManager::instance().raw_read(qualifier)(throwsstd::runtime_errorif it can’t be found or read);creates a node whose ID is
<last chunk>#<random>, whose name is the name of the inner graph, whose qualifier is the qualifier of the graph and whoseis_proxy()is true;for each parameter: copies the inner input socket (type, value, allowed values, linkable, callbacks) and renames it to its alias and
show_as; same for each result with the output sockets.
The proxy node then behaves like any other node: it can be linked, its unlinked inputs can be given a value (checked by the same validators), it can be renamed, removed, serialized.
What is copied is the interface at the time of the creation. Nothing else of the inner graph is stored in the outer graph: the inner graph is read again from the disk when the outer graph is executed.
Execution#
The runtime replaces each proxy node by the operators of its inner graph (recursively). The inputs of the proxy node become the values of the inner parameters, and the inner results become the outputs of the proxy node. See The runtime for the details.
Pitfalls#
The inner graph is always read from the disk, both when creating the proxy and when running: a version modified in memory but not saved is not used.
If the interface of the inner graph changes after a proxy node was created, the existing proxy node keeps its old sockets. New proxy nodes get the new interface. See Known limitations.
Only direct self-inclusion is refused at edition time. A cycle through several graphs (A contains B which contains A) is only detected when building the runtime, which throws.