Nodes

BaseNode, slot macros, auto-registration, rapid node creation, and built-in node types.

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

TierLinesWhen to Use
Macro node~5Simple pass-through or data-holding nodes
Helper macro node~15Nodes with custom properties but standard slot patterns
Full custom node30+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:

NodeCategoryPurpose
IfNodeRoutingRoutes data based on a boolean condition
SwitchNodeRoutingRoutes data based on a selector value
GetVariableNodeVariablesOutputs the value of a declared variable
SetVariableNodeVariablesWrites a value to a declared variable

Variable nodes are automatically included in the palette when variablesEnabled = true in the descriptor.