pub struct Graph<W: WireKind> {
pub connections: Vec<Connection>,
pub exposed_ports: IndexMap<String, ExposedPortMeta>,
/* private fields */
}Expand description
A directed acyclic graph of nodes connected by typed wires.
Fields§
§connections: Vec<Connection>§exposed_ports: IndexMap<String, ExposedPortMeta>Ordered set of exposed-port entries. Insertion order is the
brush-bar display order — IndexMap preserves it through every
mutation and JSON/YAML round-trip. Keys come from
exposed_port_key.
Implementations§
Source§impl<W: WireKind> Graph<W>
impl<W: WireKind> Graph<W>
pub fn new() -> Self
Sourcepub fn nodes(&self) -> &HashMap<NodeId, NodeInstance<W>>
pub fn nodes(&self) -> &HashMap<NodeId, NodeInstance<W>>
Read-only access to the node map. The graph owns id assignment
(via add_node) and the invariant that every
connection references existing nodes, so external code must go
through the graph’s methods to mutate the set.
Sourcepub fn add_node(
&mut self,
type_id: impl Into<String>,
ports: Vec<PortDef<W>>,
params: Vec<ParamValue>,
) -> NodeId
pub fn add_node( &mut self, type_id: impl Into<String>, ports: Vec<PortDef<W>>, params: Vec<ParamValue>, ) -> NodeId
Add a node and return its assigned id. Any input port whose
registration PortDef declares .exposed() is auto-appended to
exposed_ports with empty meta — preserves the “size etc. are
exposed by default” affordance.
Sourcepub fn remove_node(&mut self, id: NodeId) -> Result<(), GraphError>
pub fn remove_node(&mut self, id: NodeId) -> Result<(), GraphError>
Remove a node, all its connections, and every brush-bar entry referencing one of its ports.
Sourcepub fn expose_port(
&mut self,
id: NodeId,
port_name: &str,
) -> Result<(), GraphError>
pub fn expose_port( &mut self, id: NodeId, port_name: &str, ) -> Result<(), GraphError>
Add a brush-bar entry for an input port, no-op if already present. The entry starts with empty meta (registration values are used as fallback at render time).
Sourcepub fn unexpose_port(&mut self, id: NodeId, port_name: &str)
pub fn unexpose_port(&mut self, id: NodeId, port_name: &str)
Drop a brush-bar entry by (node, port). Idempotent — missing
entries are not an error.
Sourcepub fn is_port_exposed(&self, id: NodeId, port_name: &str) -> bool
pub fn is_port_exposed(&self, id: NodeId, port_name: &str) -> bool
Returns true when the named input port has a live brush-bar entry.
Sourcepub fn set_exposed_port_meta(
&mut self,
key: &str,
label: String,
description: String,
icon: String,
) -> Result<(), GraphError>
pub fn set_exposed_port_meta( &mut self, key: &str, label: String, description: String, icon: String, ) -> Result<(), GraphError>
Overwrite all three meta fields on a brush-bar entry in one call.
The icon field is restricted to FontAwesome-friendly characters
([a-zA-Z0-9- ]*) — keeps the value safe to bind directly into
an HTML class= attribute on the frontend without further
sanitization. Out-of-shape icon strings are rejected loudly so
the caller learns about the constraint rather than seeing the
icon silently dropped.
Sourcepub fn reorder_exposed_port(
&mut self,
key: &str,
new_index: usize,
) -> Result<(), GraphError>
pub fn reorder_exposed_port( &mut self, key: &str, new_index: usize, ) -> Result<(), GraphError>
Move an exposed-port entry to position new_index. The map’s
iteration order is the brush-bar display order, so this is how
drag-reorder is realised. new_index is clamped to the map’s
length.
Sourcepub fn connect(&mut self, from: PortRef, to: PortRef) -> Result<(), GraphError>
pub fn connect(&mut self, from: PortRef, to: PortRef) -> Result<(), GraphError>
Connect an output port to an input port, checking types and cycles.
Sourcepub fn disconnect(&mut self, from: &PortRef, to: &PortRef)
pub fn disconnect(&mut self, from: &PortRef, to: &PortRef)
Disconnect a specific wire.
Sourcepub fn inputs_for(&self, node_id: NodeId) -> impl Iterator<Item = &Connection>
pub fn inputs_for(&self, node_id: NodeId) -> impl Iterator<Item = &Connection>
All connections whose destination is a port on node_id.
Sourcepub fn outputs_for(&self, node_id: NodeId) -> impl Iterator<Item = &Connection>
pub fn outputs_for(&self, node_id: NodeId) -> impl Iterator<Item = &Connection>
All connections whose source is a port on node_id.
Sourcepub fn set_port_default(
&mut self,
id: NodeId,
port_name: &str,
value: f32,
) -> Result<(), GraphError>
pub fn set_port_default( &mut self, id: NodeId, port_name: &str, value: f32, ) -> Result<(), GraphError>
Update a port’s default value on a node instance.
This changes the value used when the port is disconnected.
Sourcepub fn set_param(
&mut self,
id: NodeId,
index: usize,
value: ParamValue,
) -> Result<(), GraphError>
pub fn set_param( &mut self, id: NodeId, index: usize, value: ParamValue, ) -> Result<(), GraphError>
Update a single parameter value on a node.
Sourcepub fn find_terminal(
&self,
registry: &HashMap<String, NodeRegistration<W>>,
) -> Result<NodeId, FindTerminalError>
pub fn find_terminal( &self, registry: &HashMap<String, NodeRegistration<W>>, ) -> Result<NodeId, FindTerminalError>
Find the unique node in this graph whose registration declares
is_terminal: true. By today’s invariant a brush graph contains
exactly one terminal; deviations are reported via
FindTerminalError rather than silently arbitrated.
Source§impl<W: WireKind> Graph<W>
impl<W: WireKind> Graph<W>
Sourcepub fn auto_layout(&self) -> NodeLayout
pub fn auto_layout(&self) -> NodeLayout
Compute positions for all nodes using a layered layout.
Data flows left-to-right: source nodes at x=0, downstream nodes at increasing x. Nodes within a layer are spaced vertically and ordered to minimize edge crossings.
When no measured sizes are available (tests, freshly loaded brushes), falls back to port-count-based height estimation.
Positions are not stored on the graph — the returned map is the authoritative result and callers (currently the frontend node editor) keep it as UI-only state.
Sourcepub fn auto_layout_with_sizes(
&self,
sizes: &HashMap<NodeId, [f32; 2]>,
) -> NodeLayout
pub fn auto_layout_with_sizes( &self, sizes: &HashMap<NodeId, [f32; 2]>, ) -> NodeLayout
Like [auto_layout], but uses measured [width, height] from
the DOM for any node present in sizes. Nodes not in the map
fall back to port-count estimation.