190 lines
5.9 KiB
C++
190 lines
5.9 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "WingServer.h"
|
|
#include "WingBasics.h"
|
|
#include "WingFetcher.h"
|
|
#include "WingUtils.h"
|
|
#include "Engine/Blueprint.h"
|
|
#include "Animation/AnimBlueprint.h"
|
|
#include "Animation/Skeleton.h"
|
|
#include "WingComponent.h"
|
|
#include "AnimationGraph.h"
|
|
#include "AnimationGraphSchema.h"
|
|
#include "AnimationStateMachineSchema.h"
|
|
#include "WingVariables.h"
|
|
#include "WingWidgets.h"
|
|
#include "WidgetBlueprint.h"
|
|
#include "Blueprint/WidgetTree.h"
|
|
#include "Blueprint_Dump.generated.h"
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
|
|
UCLASS()
|
|
class UWing_Blueprint_Dump : public UWingHandler
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UPROPERTY(EditAnywhere, meta=(Description="Blueprint path"))
|
|
FString Blueprint;
|
|
|
|
virtual void Register() override
|
|
{
|
|
UWingServer::AddHandler(this,
|
|
TEXT("Dump a Blueprint's structure: variables, interfaces, components, "
|
|
"and graph names. Does not include graph contents (use Graph_Dump for that)."));
|
|
}
|
|
virtual void Handle() override
|
|
{
|
|
WingFetcher F(WingOut::Stdout);
|
|
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
if (!BP) return;
|
|
|
|
// Header
|
|
WingOut::Stdout.Printf(TEXT("Blueprint: %s\n"), *WingUtils::FormatName(BP));
|
|
WingOut::Stdout.Printf(TEXT("Parent: %s\n"), BP->ParentClass ? *WingUtils::FormatName(BP->ParentClass) : TEXT("None"));
|
|
WingOut::Stdout.Printf(TEXT("Type: %s\n"), *WingUtils::EnumToString(BP->BlueprintType));
|
|
|
|
// Animation Blueprint
|
|
if (UAnimBlueprint* AnimBP = Cast<UAnimBlueprint>(BP))
|
|
{
|
|
if (AnimBP->TargetSkeleton)
|
|
WingOut::Stdout.Printf(TEXT("TargetSkeleton: %s\n"), *AnimBP->TargetSkeleton->GetPathName());
|
|
}
|
|
|
|
// Interfaces
|
|
for (const FBPInterfaceDescription& I : BP->ImplementedInterfaces)
|
|
{
|
|
if (I.Interface) WingOut::Stdout.Printf(TEXT("Interface: %s\n"), *WingUtils::FormatName(I));
|
|
}
|
|
|
|
// Variables
|
|
WingVariables BlueprintVars;
|
|
BlueprintVars.SetBackingStore(BP, WingOut::Stdout);
|
|
BlueprintVars.Load(WingOut::Stdout);
|
|
BlueprintVars.Print(WingOut::StdoutBuffer);
|
|
|
|
// Components
|
|
TArray<TStrongObjectPtr<UWingComponentRef>> Components = UWingComponent::GetAll(BP);
|
|
if (!Components.IsEmpty()) WingOut::Stdout.Print(TEXT("\nComponents:\n"));
|
|
UWingComponent::PrintAll(BP, WingOut::Stdout);
|
|
|
|
// Widget Tree
|
|
if (UWidgetBlueprint* WidgetBP = Cast<UWidgetBlueprint>(BP))
|
|
{
|
|
WingOut::Stdout.Print(TEXT("\nWidget Tree:\n"));
|
|
WingWidgets::PrintWidgetTree(WidgetBP->WidgetTree->RootWidget, 1);
|
|
}
|
|
|
|
// Event Dispatchers
|
|
if (!BP->DelegateSignatureGraphs.IsEmpty())
|
|
{
|
|
WingOut::Stdout.Print(TEXT("\nEvent Dispatchers:\n"));
|
|
for (UEdGraph* Graph : BP->DelegateSignatureGraphs)
|
|
PrintEventDispatcher(Graph);
|
|
}
|
|
|
|
// Graphs
|
|
TSet<UEdGraph*> Printed;
|
|
|
|
WingOut::Stdout.Print(TEXT("\nGraphs:\n"));
|
|
for (UEdGraph* Graph : BP->UbergraphPages)
|
|
{
|
|
WingOut::Stdout.Printf(TEXT(" EventGraph %s\n"), *WingUtils::FormatName(Graph));
|
|
Printed.Add(Graph);
|
|
}
|
|
for (UEdGraph* Graph : BP->FunctionGraphs)
|
|
{
|
|
if (Graph->IsA<UAnimationGraph>()) continue;
|
|
PrintGraph(Graph, TEXT("Function"));
|
|
Printed.Add(Graph);
|
|
}
|
|
for (UEdGraph* Graph : BP->MacroGraphs)
|
|
{
|
|
PrintGraph(Graph, TEXT("Macro"));
|
|
Printed.Add(Graph);
|
|
}
|
|
for (const FBPInterfaceDescription& I : BP->ImplementedInterfaces)
|
|
for (UEdGraph* Graph : I.Graphs)
|
|
{
|
|
PrintGraph(Graph, TEXT("Interface"), I.Interface);
|
|
Printed.Add(Graph);
|
|
}
|
|
|
|
// Delegate signature graphs are not real graphs, but mark them as printed.
|
|
for (UEdGraph* Graph : BP->DelegateSignatureGraphs)
|
|
Printed.Add(Graph);
|
|
|
|
// Animation graphs and state machines.
|
|
TArray<UEdGraph*> AllGraphs = WingUtils::AllGraphs(BP);
|
|
|
|
FString AnimGraphNames;
|
|
for (UEdGraph* Graph : AllGraphs)
|
|
{
|
|
if (Printed.Contains(Graph)) continue;
|
|
if (!Graph->Schema || !Graph->Schema->IsChildOf(UAnimationGraphSchema::StaticClass())) continue;
|
|
if (!AnimGraphNames.IsEmpty()) AnimGraphNames += TEXT(", ");
|
|
AnimGraphNames += WingUtils::FormatName(Graph);
|
|
Printed.Add(Graph);
|
|
}
|
|
if (!AnimGraphNames.IsEmpty())
|
|
WingOut::Stdout.Printf(TEXT("\nAnimation Graphs: %s\n"), *AnimGraphNames);
|
|
|
|
FString StateMachineNames;
|
|
for (UEdGraph* Graph : AllGraphs)
|
|
{
|
|
if (Printed.Contains(Graph)) continue;
|
|
if (!Graph->Schema || !Graph->Schema->IsChildOf(UAnimationStateMachineSchema::StaticClass())) continue;
|
|
if (!StateMachineNames.IsEmpty()) StateMachineNames += TEXT(", ");
|
|
StateMachineNames += WingUtils::FormatName(Graph);
|
|
Printed.Add(Graph);
|
|
}
|
|
if (!StateMachineNames.IsEmpty())
|
|
WingOut::Stdout.Printf(TEXT("\nAnimation State Machines: %s\n"), *StateMachineNames);
|
|
|
|
// Catch any graphs we missed.
|
|
for (UEdGraph* Graph : AllGraphs)
|
|
{
|
|
if (Printed.Contains(Graph)) continue;
|
|
WingOut::Stdout.Printf(TEXT("WARNING: unlisted graph: %s (%s)\n"),
|
|
*WingUtils::FormatName(Graph),
|
|
*WingUtils::FormatName(Graph->GetSchema()->GetClass()));
|
|
}
|
|
}
|
|
|
|
private:
|
|
void PrintEventDispatcher(UEdGraph* Graph)
|
|
{
|
|
WingVariables Vars;
|
|
Vars.SetBackingStore(Graph, WingOut::Stdout);
|
|
Vars.Load(WingOut::Stdout);
|
|
|
|
WingOut::Stdout.Printf(TEXT(" %s("), *WingUtils::FormatName(Graph));
|
|
Vars.InputVariables.PrintCompact(WingOut::Stdout);
|
|
WingOut::Stdout.Printf(TEXT(")\n"));
|
|
}
|
|
|
|
void PrintGraph(UEdGraph* Graph, const TCHAR* Type, UClass* Interface = nullptr)
|
|
{
|
|
WingVariables Vars;
|
|
Vars.SetBackingStore(Graph, WingOut::Stdout);
|
|
Vars.Load(WingOut::Stdout);
|
|
|
|
FStringBuilderBase &Out = WingOut::StdoutBuffer;
|
|
Out.Appendf(TEXT(" %s %s"), Type, *WingUtils::FormatName(Graph));
|
|
Out.AppendChar('(');
|
|
Vars.InputVariables.PrintCompact(Out);
|
|
Out.Append(TEXT(") -> ("));
|
|
Vars.OutputVariables.PrintCompact(Out);
|
|
Out.AppendChar(')');
|
|
if (Interface)
|
|
Out.Appendf(TEXT(" [%s]"), *WingUtils::FormatName(Interface));
|
|
Out.AppendChar('\n');
|
|
}
|
|
|
|
};
|