Controlling Node Pins & Connection
Joint provides a convenient way to dynamically & manually control node pins in your custom nodes & fragments, and to gather their connections as well.
This is especially useful when you want to create nodes or fragments that can adapt their inputs and outputs based on user interactions or other conditions, just like Branch node of Joint Native.
Updating Node Pins
For Both C++ and BP, you can override OnUpdatePinData to update node pins dynamically.
In BP
In BP, you can find this function under the "Overrides" section of your custom node or fragment.
Then you can add your custom logic to update the node pins as needed.
For example, in the image below (UDF_Branching), you can see the custom logic for the node as we wanted to make it have "False" and "True" together when its bUseFalse is set to true, otherwise only "True" pin.

There are some parts you need extra explanations for.
In Joint, each node pin is represented by a FJointEdPinData structure, which contains information about the pin's properties and behavior. If you want to add a pin, then you can make a new FJointEdPinData instance and add it.
But if you make a new structure every time when updating pins, it will work like, replacing the existing pins with new ones, which will lose all the existing connections on the pins, and that's not what we want.
So we provide "Implement Pins" function to help you implement pins properly - you can put the existing pins into this function together with the new pin definition data, and it will reuse the existing pins if they match the new definition, preserving their connections.
For example, in this image below, we wanted to let it have "True" pin, but wanted to preserve the "True" if it already exists, so we put the existing pins into "Implement Pins" function along with the new "True" pin definition.

Here is the final result of Branch fragment's pin update logic. You can see that a node with bUseFalse set to true has both "True" and "False" pins, while a node with bUseFalse set to false has only the "True" pin.

In C++
It's basically the same as BP - what you need to do is to override OnUpdatePinData_Implementation function in your node class that inherits UJointNodeBase or UJointFragmentBase, and implement your custom logic to update the node pins.
virtual void OnUpdatePinData_Implementation(TArray<FJointEdPinData>& PinData);
You can use the same static function we introduced earlier for the implementation. (UJointFunctionLibrary::ImplementPins())
Editor Pin Data Setting
Joint provides some editor-only pin data settings that can help you control the behavior of node pins in the graph editor.
For now, we only provide bAlwaysDisplayNameText boolean property, which determines whetehr to always display the pin name text in the graph editor. If you set this to false, the pin name text will only be displayed when the pin is hovered or selected.

Gathering Node Pin Connections
Once you implemented your own pins, you may want to gather their connections to use them in your node or fragment's logic.
For that, you can override OnPinConnectionChanged_Implementation function in C++ or OnPinConnectionChanged event in BP.

It returns pin -> connections mapping as TMap<FJointEdPinData,FJointNodes>, where you can iterate through each pin and gather its connections from the map.
Use this function/event to update your node or fragment's internal state based on the current connections of its pins.
Joint Native's Branch (DF_Branch) fragment uses this function/event to update its internal branching logic based on the connections of its "True" and "False" pins.
Please check out DF_Branch fragment's implementation for more details.
Where Do We Use The Connected Nodes? (providing next node to play)
Here is one important question: Once you have gathered the connected nodes from the pin connections, what can you do with them?
- Of course, you can use them in various ways depending on your node or fragment's purpose.
- Most Importantly, You can provide the connected nodes to be the next node the graph will play.