Node
A node in the SystemGraph editor represents the visual representation of the data model of a NodeRuntime script. The data model is a collection of fields that are contained within Ports on the node.
Synchronous and Asynchronous nodes
SystemGraph uses two types of nodes:
- Synchronous nodes
- Asynchronous nodes
Synchronous Nodes
A synchronous node in the editor is represented by a clock icon, as shown in the image below. Synchronous nodes are handled by the scheduler. They receive an OnTick
callback for every scheduler waveform event set in the Scheduler Editor for this node instance in the graph.
The heading color and icon of a synchronous node will be the same color as the node row in the Scheduler Editor.
Asynchronous Nodes
An asynchronous node in the editor is represented by a lightning icon, as shown in the image below.
An asynchronous node is purely reactive and doesn't receive an OnTick
callback by the scheduler.
NodeRuntime
The node runtime interface developed by the user provides functionality that processes input ports and propagates information to other nodes through the output ports. NodeRuntime
is created by the System Graph Component.
Node events
NodeRuntime
receives events from the System Graph Component. These events follow the SystemGraph asset definition. The order of execution of nodes strictly follows waveforms of the scheduler, for synchronous nodes, or change events in the graph, for asynchronous nodes. The order of initialization is also assessed for synchronous nodes, related to how the scheduler is configured for node order (displayed row order in the scheduler editor).
Implement a node using a C# script
You can implement a node using a C# class with special attributes to mark nodes, ports, and bindings.
Here is part of the implementation of the synchronous node shown earlier:
[NodeCategory("3D Printer", "Controller", NodeTick.Synchronous)]
public class UM2Controller : NodeRuntime
{
[Field("LCD Display", PortDirection.Left, FieldExtra.Read)]
[SerializeField]
private PortType<GameObject> lcdDisplayObject = new PortType<GameObject>();
[Field("Button Press", PortDirection.Left, FieldExtra.Read | FieldExtra.ChangeEvent)]
[SerializeField]
private PortType<bool> buttonPressed = new PortType<bool>();
[Field("Button Rotate", PortDirection.Left, FieldExtra.Read | FieldExtra.ChangeEvent)]
[SerializeField]
private PortType<float> buttonRotateAngle = new PortType<float>();
// ...
}