Better graph dump that shows exec pin names so that the AI knows how to connect them.
This commit is contained in:
@@ -38,6 +38,13 @@ WingGraphExport::WingGraphExport(UEdGraphNode* InNode, bool Locals, bool Details
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool WingGraphExport::IsLinked(UEdGraphPin* Pin)
|
||||||
|
{
|
||||||
|
if (Pin == nullptr) return false;
|
||||||
|
if (Pin->LinkedTo.IsEmpty()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
UEdGraphPin* WingGraphExport::GetLinkedTo(UEdGraphPin* Pin)
|
UEdGraphPin* WingGraphExport::GetLinkedTo(UEdGraphPin* Pin)
|
||||||
{
|
{
|
||||||
if (Pin == nullptr) return nullptr;
|
if (Pin == nullptr) return nullptr;
|
||||||
@@ -64,13 +71,16 @@ bool WingGraphExport::IsDefaultToSelf(UEdGraphPin* Pin)
|
|||||||
return Pin->PinName.ToString() == DefaultToSelfPinName;
|
return Pin->PinName.ToString() == DefaultToSelfPinName;
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<UEdGraphPin*> WingGraphExport::FilterPins(UEdGraphNode* Node, EEdGraphPinDirection Direction, FName Category)
|
TArray<UEdGraphPin*> WingGraphExport::GetPins(
|
||||||
|
UEdGraphNode* Node, EEdGraphPinDirection Direction, PinKind Kind)
|
||||||
{
|
{
|
||||||
TArray<UEdGraphPin*> Result;
|
TArray<UEdGraphPin*> Result;
|
||||||
for (UEdGraphPin* Pin : Node->Pins)
|
for (UEdGraphPin* Pin : Node->Pins)
|
||||||
{
|
{
|
||||||
if (Direction != EGPD_MAX && Pin->Direction != Direction) continue;
|
if (Pin->bHidden) continue;
|
||||||
if (!Category.IsNone() && Pin->PinType.PinCategory != Category) continue;
|
if (Pin->Direction != Direction) continue;
|
||||||
|
if ((Kind == PK_VALUE) && (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec)) continue;
|
||||||
|
if ((Kind == PK_EXEC) && (Pin->PinType.PinCategory != UEdGraphSchema_K2::PC_Exec)) continue;
|
||||||
Result.Add(Pin);
|
Result.Add(Pin);
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
@@ -78,78 +88,23 @@ TArray<UEdGraphPin*> WingGraphExport::FilterPins(UEdGraphNode* Node, EEdGraphPin
|
|||||||
|
|
||||||
bool WingGraphExport::HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction)
|
bool WingGraphExport::HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction)
|
||||||
{
|
{
|
||||||
return FilterPins(Node, Direction, UEdGraphSchema_K2::PC_Exec).Num() > 0;
|
return GetPins(Node, Direction, PK_EXEC).Num() > 0;
|
||||||
}
|
|
||||||
|
|
||||||
UEdGraphPin* WingGraphExport::FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirection Direction)
|
|
||||||
{
|
|
||||||
for (UEdGraphPin* Pin : Node->Pins)
|
|
||||||
{
|
|
||||||
if (Pin->Direction == Direction) return Pin;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Traverse and Emit the Nodes.
|
// Traversal
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
|
|
||||||
FString WingGraphExport::FormatPinSource(UEdGraphPin* Pin)
|
|
||||||
{
|
|
||||||
// If connected, show source node.pin
|
|
||||||
UEdGraphPin* LinkedTo = GetLinkedTo(Pin);
|
|
||||||
if (LinkedTo != nullptr)
|
|
||||||
{
|
|
||||||
UEdGraphNode* LinkedToNode = LinkedTo->GetOwningNode();
|
|
||||||
FString PinLabel = WingUtils::FormatName(LinkedTo);
|
|
||||||
return FString::Printf(TEXT("%s.%s"), *WingUtils::FormatName(LinkedToNode), *PinLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// String pins: always show in quotes (even if empty).
|
|
||||||
FName Category = Pin->PinType.PinCategory;
|
|
||||||
if (Category == UEdGraphSchema_K2::PC_String ||
|
|
||||||
Category == UEdGraphSchema_K2::PC_Name ||
|
|
||||||
Category == UEdGraphSchema_K2::PC_Text)
|
|
||||||
{
|
|
||||||
return FString::Printf(TEXT("\"%s\""), *Pin->DefaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If has a non-empty default, show it.
|
|
||||||
if (!Pin->DefaultValue.IsEmpty())
|
|
||||||
{
|
|
||||||
return Pin->DefaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pin->DefaultObject)
|
|
||||||
{
|
|
||||||
return Pin->DefaultObject->GetName();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Pin->DefaultTextValue.IsEmpty())
|
|
||||||
{
|
|
||||||
return FString::Printf(TEXT("\"%s\""), *Pin->DefaultTextValue.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDefaultToSelf(Pin))
|
|
||||||
{
|
|
||||||
return TEXT("<self>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return TEXT("<default>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WingGraphExport::Traverse(UEdGraphNode* Node)
|
void WingGraphExport::Traverse(UEdGraphNode* Node)
|
||||||
{
|
{
|
||||||
if (Visited.Contains(Node)) return;
|
if (Visited.Contains(Node)) return;
|
||||||
Visited.Add(Node);
|
Visited.Add(Node);
|
||||||
|
|
||||||
// First, traverse input nodes
|
// First, traverse input nodes
|
||||||
for (UEdGraphPin* Pin : FilterPins(Node, EGPD_Input))
|
for (UEdGraphPin* Pin : GetPins(Node, EGPD_Input, PK_BOTH))
|
||||||
for (UEdGraphPin* LinkedPin : Pin->LinkedTo)
|
for (UEdGraphPin* LinkedPin : Pin->LinkedTo)
|
||||||
Traverse(LinkedPin->GetOwningNode());
|
Traverse(LinkedPin->GetOwningNode());
|
||||||
|
|
||||||
@@ -159,7 +114,7 @@ void WingGraphExport::Traverse(UEdGraphNode* Node)
|
|||||||
// Then, traverse exec output nodes only.
|
// Then, traverse exec output nodes only.
|
||||||
// Data outputs are not followed — data nodes get pulled in
|
// Data outputs are not followed — data nodes get pulled in
|
||||||
// through their consumers' input traversal.
|
// through their consumers' input traversal.
|
||||||
for (UEdGraphPin* Pin : FilterPins(Node, EGPD_Output, UEdGraphSchema_K2::PC_Exec))
|
for (UEdGraphPin* Pin : GetPins(Node, EGPD_Output, PK_EXEC))
|
||||||
for (UEdGraphPin* LinkedPin : Pin->LinkedTo)
|
for (UEdGraphPin* LinkedPin : Pin->LinkedTo)
|
||||||
Traverse(LinkedPin->GetOwningNode());
|
Traverse(LinkedPin->GetOwningNode());
|
||||||
}
|
}
|
||||||
@@ -195,6 +150,62 @@ void WingGraphExport::SortNodes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Text Output
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void WingGraphExport::EmitLinks(UEdGraphPin* Pin)
|
||||||
|
{
|
||||||
|
bool comma = false;
|
||||||
|
for (const UEdGraphPin *Other : Pin->LinkedTo)
|
||||||
|
{
|
||||||
|
if (comma) Output.Append(TEXT(", "));
|
||||||
|
comma = true;
|
||||||
|
Output.Appendf(TEXT("node:%s,pin:%s"),
|
||||||
|
*WingUtils::FormatName(Other->GetOwningNode()), *WingUtils::FormatName(Other));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WingGraphExport::EmitInputPinValue(UEdGraphPin* Pin)
|
||||||
|
{
|
||||||
|
// If connected, show source node and pin
|
||||||
|
if (IsLinked(Pin)) return EmitLinks(Pin);
|
||||||
|
|
||||||
|
// String pins: always show in quotes (even if empty).
|
||||||
|
FName Category = Pin->PinType.PinCategory;
|
||||||
|
if (Category == UEdGraphSchema_K2::PC_String ||
|
||||||
|
Category == UEdGraphSchema_K2::PC_Name ||
|
||||||
|
Category == UEdGraphSchema_K2::PC_Text)
|
||||||
|
{
|
||||||
|
Output.Appendf(TEXT("\"%s\""), *Pin->DefaultValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If has a non-empty default, show it.
|
||||||
|
if (!Pin->DefaultValue.IsEmpty())
|
||||||
|
{
|
||||||
|
Output.Append(Pin->DefaultValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pin->DefaultObject)
|
||||||
|
{
|
||||||
|
Output.Append(Pin->DefaultObject->GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Pin->DefaultTextValue.IsEmpty())
|
||||||
|
{
|
||||||
|
Output.Appendf(TEXT("\"%s\""), *Pin->DefaultTextValue.ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Output.Appendf(TEXT("<default>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WingGraphExport::EmitNode(UEdGraphNode* Node)
|
void WingGraphExport::EmitNode(UEdGraphNode* Node)
|
||||||
{
|
{
|
||||||
if (Node->IsA<UEdGraphNode_Comment>()) return;
|
if (Node->IsA<UEdGraphNode_Comment>()) return;
|
||||||
@@ -218,45 +229,65 @@ void WingGraphExport::EmitNode(UEdGraphNode* Node)
|
|||||||
SuppressedDetails = true;
|
SuppressedDetails = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit the input exec pin(s). Do not show what they're connected to.
|
||||||
|
TArray<UEdGraphPin*> ExecIns = GetPins(Node, EGPD_Input, PK_EXEC);
|
||||||
|
for (UEdGraphPin* Pin : ExecIns)
|
||||||
|
{
|
||||||
|
if (IsLinked(Pin))
|
||||||
|
{
|
||||||
|
Output.Appendf(TEXT(" exec-in %s from "), *WingUtils::FormatName(Pin));
|
||||||
|
EmitLinks(Pin);
|
||||||
|
Output.AppendChar('\n');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Output.Appendf(TEXT(" exec-in %s (unconnected)\n"), *WingUtils::FormatName(Pin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Emit input data pins.
|
// Emit input data pins.
|
||||||
for (UEdGraphPin* Pin : FilterPins(Node, EGPD_Input))
|
for (UEdGraphPin* Pin : GetPins(Node, EGPD_Input, PK_VALUE))
|
||||||
{
|
{
|
||||||
if (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) continue;
|
if (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) continue;
|
||||||
if (Pin->bHidden) continue;
|
|
||||||
|
|
||||||
Output.Appendf(TEXT(" input %s %s = %s\n"),
|
Output.Appendf(TEXT(" input-pin %s %s = "),
|
||||||
*UWingTypes::TypeToText(Pin->PinType),
|
*UWingTypes::TypeToText(Pin->PinType),
|
||||||
*WingUtils::FormatName(Pin),
|
*WingUtils::FormatName(Pin));
|
||||||
*FormatPinSource(Pin));
|
EmitInputPinValue(Pin);
|
||||||
|
Output.AppendChar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit output data pins as a return line.
|
// Emit output data pins as a single 'output-pins' line.
|
||||||
FString ReturnPins;
|
TArray<UEdGraphPin*> OutputPins = GetPins(Node, EGPD_Output, PK_VALUE);
|
||||||
for (UEdGraphPin* Pin : FilterPins(Node, EGPD_Output))
|
if (!OutputPins.IsEmpty())
|
||||||
{
|
{
|
||||||
if (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) continue;
|
Output.Append(TEXT(" output-pins "));
|
||||||
if (Pin->bHidden) continue;
|
bool comma = false;
|
||||||
if (!ReturnPins.IsEmpty()) ReturnPins += TEXT(", ");
|
for (UEdGraphPin *Pin : OutputPins)
|
||||||
ReturnPins += WingUtils::FormatName(Pin);
|
{
|
||||||
}
|
if (comma) Output.Append(TEXT(", "));
|
||||||
if (!ReturnPins.IsEmpty())
|
comma = true;
|
||||||
{
|
Output.Append(UWingTypes::TypeToText(Pin->PinType));
|
||||||
Output.Appendf(TEXT(" output-pins %s\n"), *ReturnPins);
|
Output.AppendChar(' ');
|
||||||
|
Output.Append(WingUtils::FormatName(Pin));
|
||||||
|
}
|
||||||
|
Output.AppendChar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit output exec pins as goto statements.
|
// Emit output exec pins.
|
||||||
TArray<UEdGraphPin*> ExecOuts = FilterPins(Node, EGPD_Output, UEdGraphSchema_K2::PC_Exec);
|
TArray<UEdGraphPin*> ExecOuts = GetPins(Node, EGPD_Output, PK_EXEC);
|
||||||
for (UEdGraphPin* Pin : ExecOuts)
|
for (UEdGraphPin* Pin : ExecOuts)
|
||||||
{
|
{
|
||||||
UEdGraphPin* LinkedTo = GetLinkedTo(Pin);
|
if (IsLinked(Pin))
|
||||||
if (!LinkedTo) continue;
|
{
|
||||||
|
Output.Appendf(TEXT(" exec-out %s to "), *WingUtils::FormatName(Pin));
|
||||||
FString Target = WingUtils::FormatName(LinkedTo->GetOwningNode());
|
EmitLinks(Pin);
|
||||||
|
Output.AppendChar('\n');
|
||||||
if (ExecOuts.Num() == 1)
|
}
|
||||||
Output.Appendf(TEXT(" goto %s\n"), *Target);
|
|
||||||
else
|
else
|
||||||
Output.Appendf(TEXT(" goto-if %s %s\n"), *WingUtils::FormatName(Pin), *Target);
|
{
|
||||||
|
Output.Appendf(TEXT(" exec-out %s (unconnected)\n"), *WingUtils::FormatName(Pin));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Output.Append(TEXT("\n"));
|
Output.Append(TEXT("\n"));
|
||||||
|
|||||||
@@ -22,6 +22,17 @@ private:
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum PinKind
|
||||||
|
{
|
||||||
|
PK_EXEC,
|
||||||
|
PK_VALUE,
|
||||||
|
PK_BOTH
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return true if this pin is connected.
|
||||||
|
//
|
||||||
|
static bool IsLinked(UEdGraphPin *Pin);
|
||||||
|
|
||||||
// Get the pin that this pin is linked to.
|
// Get the pin that this pin is linked to.
|
||||||
//
|
//
|
||||||
static UEdGraphPin* GetLinkedTo(UEdGraphPin *Pin);
|
static UEdGraphPin* GetLinkedTo(UEdGraphPin *Pin);
|
||||||
@@ -32,27 +43,24 @@ private:
|
|||||||
static bool IsDefaultToSelf(UEdGraphPin* Pin);
|
static bool IsDefaultToSelf(UEdGraphPin* Pin);
|
||||||
|
|
||||||
// Get a subset of the pins in the node, filtered
|
// Get a subset of the pins in the node, filtered
|
||||||
// by direction, category, or both.
|
// by direction, Kind, or both.
|
||||||
//
|
//
|
||||||
static TArray<UEdGraphPin*> FilterPins(UEdGraphNode* Node,
|
static TArray<UEdGraphPin*> GetPins(
|
||||||
EEdGraphPinDirection Direction = EGPD_MAX, FName Category = FName());
|
UEdGraphNode* Node, EEdGraphPinDirection Direction, PinKind Kind);
|
||||||
|
|
||||||
// Return true if the node has an exec pin that points
|
// Return true if the node has an exec pin that points
|
||||||
// in the specified direction.
|
// in the specified direction.
|
||||||
//
|
//
|
||||||
static bool HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection 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);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Traverse and Emit the Nodes.
|
// Traverse and Emit the Nodes.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
|
|
||||||
FString FormatPinSource(UEdGraphPin* Pin);
|
void EmitLinks(UEdGraphPin* Pin);
|
||||||
|
void EmitInputPinValue(UEdGraphPin* Pin);
|
||||||
void Traverse(UEdGraphNode* Node);
|
void Traverse(UEdGraphNode* Node);
|
||||||
void SortNodes();
|
void SortNodes();
|
||||||
void EmitNode(UEdGraphNode* Node);
|
void EmitNode(UEdGraphNode* Node);
|
||||||
|
|||||||
Reference in New Issue
Block a user