Skip to main content

Implementing Compilation Logic For Custom Fragments

Joint provide a built-in compilation & error reporting system for Joint Graphs.

In this document, we will explore how to implement compilation logic for your custom fragments by overriding the relevant functions.

What is Compilation & Error Reporting System of Joint?

Joint Manager has a built-in compilation feature that informs you some info about the graph settings, warns you about the possible issues and errors on the graph and nodes.

info

As the name "compilation" suggests, this system is not only for checking out errors and warnings, but also for optimizing the graph and nodes for runtime execution behind the scenes - but it's not available to be customized yet, thus we focus on error reporting feature for now.

Any modification on the graph and Joint manager asset will execute compilation, and automatically check out the possible errors for the Joint manager.

Joint Editor now has Compile Result tab that displays the result of the compilation. You can double-click the row or hyperlink to go to the node that caused the issue.

img_1.png

Graph nodes will display the compile result indicator on the overlay. You can check out the issues have been raised for the node by hovering over the indicator directly.

img.png

img_2.png

Error and warning will be displayed on the content cooking and packaging process of the project. Especially when the error has been raised, it will abort the cooking and packaging process.

img_6.png

img_7.png

How to make your custom fragment compile-aware

If your fragment needs to implement custom compilation logic, you have to override relevant functions to attach messages to the compilation result.

info

You don't need to implement compilation logic for the "properties" of your fragment (e.g., FJointNodePointer's validity)- Joint's compilation system will check them out even if you don't implement custom compilation logic for your fragment.

There are various ways to implement compilation logic for your custom fragments. You can implement it on either C++ side (using both runtime node instance or custom Editor node) or Blueprint side.

For C++ (Runtime Node Instance Side)

It's straight-forward.

You can override virtual void OnCompileNode_Implementation(TArray<FJointEdLogMessage>& LogMessages); function in your runtime node class (fragment) and attach messages to the LogMessages array.

The FJointEdLogMessage structure contains the following members:

PropertyTypeDescription / Notes
SeverityEJointEdMessageSeverityEnum specifying the message severity level. (Info / Warning / PerformanceWarning / Error)
MessageFTextLocalized text content of the message.

For C++ (Editor Node Side)

You can override virtual void OnCompileNode(); function in your custom Editor node class (derived from UJointEdGraphNode) and attach messages to the CompileMessages array.

For example, See how Joint Native's UJointEdFragment_Branch implements custom error reporting when there is no condition fragment attached to the branch node.

void UJointEdFragment_Branch::OnCompileNode()
{

Super::OnCompileNode();

if (GetCastedNodeInstance())
{
if (!GetCastedNodeInstance()->FindFragmentByClass(UDF_Condition::StaticClass()))
{
TSharedRef<FTokenizedMessage> TokenizedMessage = FTokenizedMessage::Create(EMessageSeverity::Info);
TokenizedMessage->AddToken(FAssetNameToken::Create(GetJointManager() ? GetJointManager()->GetName() : "NONE"));
TokenizedMessage->AddToken(FTextToken::Create(FText::FromString(":")));
TokenizedMessage->AddToken(FUObjectToken::Create(this));
TokenizedMessage->AddToken(FTextToken::Create(LOCTEXT("Compile_NoCondition","No condition node has been attached. Branch node must have one condition fragment as sub node to work properly. It will always return the nodes at the true pins if it has been played.")) );
TokenizedMessage.Get().SetMessageLink(FUObjectToken::Create(this));

CompileMessages.Add(TokenizedMessage);

}
}
}

For Blueprints

You can override On Compile Node event in your custom fragment Blueprint to implement compilation logic.

img_3.png

What you have to do is simply attaching messages to the output LogMessages array.

img_4.png

LogMessages is an array of FJointEdLogMessage structure.

The FJointEdLogMessage structure contains the following members (same as C++ side):

PropertyTypeDescription / Notes
SeverityEJointEdMessageSeverityEnum specifying the message severity level. (Info / Warning / PerformanceWarning / Error)
MessageFTextLocalized text content of the message.