#pragma once #if WITH_EDITOR #include "CoreMinimal.h" #include "Engine/Blueprint.h" #include "EdGraph/EdGraph.h" #include "EdGraph/EdGraphNode.h" #include "EdGraph/EdGraphPin.h" class FlxBlueprintExporter { public: FlxBlueprintExporter(UEdGraph* InGraph); const FString GetOutput() { return Output.ToString(); } const FString GetDetails() { return Details.ToString(); } private: //////////////////////////////////////////////////////// // // General utilities for manipulating UEdGraph nodes. // //////////////////////////////////////////////////////// // Sanitize a name: trim whitespace, and replace space // with underscores. // static FString SanitizeName(const FString& Title); // Get the pin type as a string. This is lossy, // we don't differentiate between object reference // or struct, for example. But that's OK, we don't // need precise type info, we just need readability. // static FString FormatPinType(const FEdGraphPinType& PinType); static FString FormatPinType(UEdGraphPin* Pin); // Get the node base name as a sanitized string. // Later, we may append a number to this base name // in order to turn it into a unique string. // static FString FormatNodeBaseName(UEdGraphNode* Node); // Get the pin that this pin is linked to. If the // pin is linked to multiple pins, returns the first. // If the pin is linked to a knot node, follow the // chain of knot nodes and find the pin at the other // end of the chain. Returns nullptr if this pin // is not linked to anything. // static UEdGraphPin* GetLinkedTo(UEdGraphPin *Pin); // Return true if the pin in question defaults // to self. // static bool IsDefaultToSelf(UEdGraphPin* Pin); // Get a subset of the pins in the node, filtered // by direction, category, or both. // static TArray FilterPins(UEdGraphNode* Node, EEdGraphPinDirection Direction = EGPD_MAX, FName Category = FName()); // Return true if the node has an exec pin that points // in the specified direction. // static bool HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction); // Find the first pin that points in the specified direction. // static UEdGraphPin* FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirection Direction); // Given a sanitized pin display name or a sanitized pin // name, find the one pin that matches. If the string // provided doesn't match any pin, or if it matches // multiple pins ambiguously, returns nullptr. If the // string is the sanitized empty string, returns nullptr // even if that matches a pin. // static UEdGraphPin* BestMatchPin(UEdGraphNode* Node, EEdGraphPinDirection Direction, bool Exec, const FString& Name); // Returns either the sanitized display name or // sanitized pin name. Chooses the one that // unambiguously identifies the pin. If neither is // ambiguous, prefers the display name. If both are // ambiguous, returns the display name with a question // mark prepended to indicate that it doesn't uniquely // identify the pin. // static FString FormatPinName(UEdGraphPin *Pin); //////////////////////////////////////////////////////// // // Traverse and Emit the Nodes. // //////////////////////////////////////////////////////// FString FormatNodeName(UEdGraphNode* Node); FString FormatPinSource(UEdGraphPin* Pin); void Traverse(UEdGraphNode* Node); void SortNodes(); void AssignNodeNames(); void EmitNode(UEdGraphNode* Node); void EmitLocalVariables(); void EmitGraph(); void EmitNodeList(); //////////////////////////////////////////////////////// // // Values recorded during traversal. // //////////////////////////////////////////////////////// UEdGraph* Graph; // Data populated by passes. TMap NodeNames; TArray SortedNodes; TSet Visited; // Output buffers. TStringBuilder<4096> Output; TStringBuilder<4096> Details; }; #endif