Nodes
Categories:
All gs_graphcanvas nodes inherit from BaseNode, which extends GraphModel::Node. BaseNode provides slot registration helpers, flow slot support, inspector property reflection, and transition descriptor management for state machines.
Slot Registration
Slots are registered in the RegisterSlots() override using helper macros:
GS_INPUT_SLOT_TYPED("slot_name", "Display Name", DataTypeEnum, DefaultValue)
GS_OUTPUT_SLOT_TYPED("slot_name", "Display Name", DataTypeEnum)
GS_INPUT_SLOT_CONNECTION("slot_name", "Display Name") // Connection-only, no inline editor
GS_MULTI_INPUT_SLOT_CONNECTION("slot_name", "Display Name") // Multiple connections allowed
All input slots use editableOnNode=true by default, providing inline value editing directly on the node in the graph canvas.
For flow-based graphs, call RegisterFlowSlots() to add FlowIn and FlowOut slots. Override HasFlowIn() or HasFlowOut() to control which flow slots appear (e.g., a Start node has no FlowIn).
For state machine graphs, call RegisterTransitionSlots() to add transition_in and transition_out perimeter slots. Override HasTransitionIn() / HasTransitionOut() to control slot presence.
Auto-Registration
Nodes self-register into the node palette via macros:
// Register for ALL graph systems:
GS_AUTO_REGISTER_NODE(MyNode)
// Register for a specific system only:
GS_AUTO_REGISTER_NODE_FOR(MyNode, "dialogue")
Each registered node includes a category string (from CATEGORY constant), display name (from TITLE), and a creation lambda. The NodeRegistry singleton manages all registrations and handles MIME event reflection for drag-drop.
Rapid Node Creation
For simple nodes with no custom logic, a single macro generates the entire class:
DEFINE_SIMPLE_NODE_WITH_SLOTS(
MyNode,
"{UNIQUE-UUID}",
"My Node",
"My Category",
{INPUT_SLOT("input", GS_Text, "Input text")},
{OUTPUT_SLOT("output", GS_Text, "Output text")}
)
This generates the class with TITLE, CATEGORY, Reflect(), RegisterSlots(), and the constructor.
Three Tiers of Node Complexity
| Tier | Lines | When to Use |
|---|---|---|
| Macro node | ~5 | Simple pass-through or data-holding nodes |
| Helper macro node | ~15 | Nodes with custom properties but standard slot patterns |
| Full custom node | 30+ | Nodes with custom execution logic, dynamic slots, or complex behavior |
Reflect Pattern
Every node’s Reflect() method must include a FindClassData guard because gs_graphcanvas is a static library and types can be registered from multiple DLLs:
void MyNode::Reflect(AZ::ReflectContext* context)
{
if (auto* sc = azrtti_cast<AZ::SerializeContext*>(context))
{
if (sc->FindClassData(azrtti_typeid<MyNode>())) { return; } // MANDATORY guard
sc->Class<MyNode, GS_GraphCanvas::BaseNode>()
->Version(1)
->Field("MyProperty", &MyNode::m_myProperty)
;
}
if (auto* ec = azrtti_cast<AZ::EditContext*>(context))
{
ec->Class<MyNode>("My Node", "Description")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &MyNode::m_myProperty,
"My Property", "Tooltip")
;
}
}
Built-in Nodes
gs_graphcanvas includes several utility nodes available to all graph systems:
| Node | Category | Purpose |
|---|---|---|
| IfNode | Routing | Routes data based on a boolean condition |
| SwitchNode | Routing | Routes data based on a selector value |
| GetVariableNode | Variables | Outputs the value of a declared variable |
| SetVariableNode | Variables | Writes a value to a declared variable |
Variable nodes are automatically included in the palette when variablesEnabled = true in the descriptor.