More work on the new variable list functionality
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "AnimationGraph.h"
|
||||
#include "AnimationGraphSchema.h"
|
||||
#include "AnimationStateMachineSchema.h"
|
||||
#include "WingVariables.h"
|
||||
#include "WingWidgets.h"
|
||||
#include "WidgetBlueprint.h"
|
||||
#include "Blueprint/WidgetTree.h"
|
||||
@@ -82,6 +83,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Variables (new format)
|
||||
WingVariables BlueprintVars = WingVariables::ParseBlueprintVariables(BP);
|
||||
if (!BlueprintVars.IsEmpty())
|
||||
{
|
||||
UWingServer::Print(TEXT("\nVariables (new format):\n"));
|
||||
BlueprintVars.PrintAll(2);
|
||||
}
|
||||
|
||||
// Components
|
||||
TArray<UWingComponentReference*> Components3 = UWingComponentReference::GetAll(BP);
|
||||
if (!Components3.IsEmpty())
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "K2Node_CallFunction.h"
|
||||
#include "K2Node_FunctionEntry.h"
|
||||
#include "WingFunctionArgs.h"
|
||||
#include "WingVariables.h"
|
||||
#include "MaterialGraph/MaterialGraphNode.h"
|
||||
|
||||
WingGraphExport::WingGraphExport(UEdGraph* InGraph)
|
||||
@@ -292,13 +293,11 @@ void WingGraphExport::EmitLocalVariables()
|
||||
UK2Node_FunctionEntry* EntryNode = Cast<UK2Node_FunctionEntry>(Node);
|
||||
if (!EntryNode) continue;
|
||||
|
||||
for (const FBPVariableDescription& Var : EntryNode->LocalVariables)
|
||||
WingVariables Locals = WingVariables::ParseFunctionLocalVariables(EntryNode);
|
||||
if (!Locals.IsEmpty())
|
||||
{
|
||||
FString Default = Var.DefaultValue.IsEmpty() ? TEXT("<default>") : Var.DefaultValue;
|
||||
Output.Appendf(TEXT("local %s %s = %s\n"),
|
||||
*UWingTypes::TypeToText(Var.VarType),
|
||||
*WingUtils::FormatName(Var),
|
||||
*Default);
|
||||
Output.Appendf(TEXT("Function Local Variables:\n"));
|
||||
Locals.PrintAll(Output, 4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
172
Plugins/UEWingman/Source/UEWingman/Private/WingVariables.cpp
Normal file
172
Plugins/UEWingman/Source/UEWingman/Private/WingVariables.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#include "WingVariables.h"
|
||||
#include "WingServer.h"
|
||||
#include "WingTypes.h"
|
||||
#include "WingUtils.h"
|
||||
#include "EdGraphSchema_K2.h"
|
||||
#include "K2Node_FunctionEntry.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
|
||||
// Flag names used for blueprint variables.
|
||||
static const FName Flag_InstanceEditable(TEXT("InstanceEditable"));
|
||||
static const FName Flag_BlueprintReadOnly(TEXT("BlueprintReadOnly"));
|
||||
static const FName Flag_ExposeOnSpawn(TEXT("ExposeOnSpawn"));
|
||||
static const FName Flag_Private(TEXT("Private"));
|
||||
static const FName Flag_ExposeToCinematics(TEXT("ExposeToCinematics"));
|
||||
|
||||
|
||||
static TSet<FName> Flags_None = { };
|
||||
static TSet<FName> Flags_BlueprintVariables = { Flag_InstanceEditable, Flag_BlueprintReadOnly, Flag_ExposeOnSpawn, Flag_Private, Flag_ExposeToCinematics };
|
||||
static TSet<FName> Flags_FunctionLocalVariables = { };
|
||||
|
||||
const TSet<FName> &WingVariables::GetRelevantFlagSet(WingVariables::Cat C)
|
||||
{
|
||||
switch (C)
|
||||
{
|
||||
case Cat::Blueprint: return Flags_BlueprintVariables;
|
||||
case Cat::FunctionLocal: return Flags_FunctionLocalVariables;
|
||||
default: return Flags_None;
|
||||
}
|
||||
}
|
||||
|
||||
void WingVariables::Var::AddFlagIfRelevant(FName Flag, WingVariables::Cat C)
|
||||
{
|
||||
if (GetRelevantFlagSet(C).Contains(Flag)) Flags.Add(Flag);
|
||||
}
|
||||
|
||||
WingVariables::Var WingVariables::ParseVariableDescription(const FBPVariableDescription &Desc, WingVariables::Cat Category)
|
||||
{
|
||||
Var Result;
|
||||
Result.Name = Desc.VarName;
|
||||
Result.Type = Desc.VarType;
|
||||
|
||||
if (!(Desc.PropertyFlags & CPF_DisableEditOnInstance))
|
||||
Result.AddFlagIfRelevant(Flag_InstanceEditable, Category);
|
||||
|
||||
if (Desc.PropertyFlags & CPF_BlueprintReadOnly)
|
||||
Result.AddFlagIfRelevant(Flag_BlueprintReadOnly, Category);
|
||||
|
||||
if (Desc.PropertyFlags & CPF_Interp)
|
||||
Result.AddFlagIfRelevant(Flag_ExposeToCinematics, Category);
|
||||
|
||||
if (Desc.HasMetaData(FBlueprintMetadata::MD_ExposeOnSpawn))
|
||||
Result.AddFlagIfRelevant(Flag_ExposeOnSpawn, Category);
|
||||
|
||||
if (Desc.HasMetaData(FBlueprintMetadata::MD_Private))
|
||||
Result.AddFlagIfRelevant(Flag_Private, Category);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool WingVariables::CheckSanity(Cat Category)
|
||||
{
|
||||
const TSet<FName> &Relevant = GetRelevantFlagSet(Category);
|
||||
TSet<FName> NamesUsed;
|
||||
for (const Var &Variable : Variables)
|
||||
{
|
||||
FString VarName = WingUtils::SanitizeName(Variable.Name);
|
||||
FString TypeText = UWingTypes::TypeToText(Variable.Type);
|
||||
if (NamesUsed.Contains(Variable.Name))
|
||||
{
|
||||
UWingServer::Printf(TEXT("Variable name appears twice: %s\n"), *VarName);
|
||||
return false;
|
||||
}
|
||||
if (TypeText.IsEmpty())
|
||||
{
|
||||
UWingServer::Printf(TEXT("Type of variable %s is not valid for unknown reasons\n"), *VarName);
|
||||
return false;
|
||||
}
|
||||
if (!UWingTypes::IsBlueprintType(Variable.Type))
|
||||
{
|
||||
UWingServer::Printf(TEXT("Type is not a valid BlueprintType: %s %s\n"), *TypeText, *VarName);
|
||||
return false;
|
||||
}
|
||||
for (FName Flag : Variable.Flags)
|
||||
{
|
||||
if (!Relevant.Contains(Flag))
|
||||
{
|
||||
UWingServer::Printf(TEXT("Flag %s is not valid here. Valid flags are:"), *Flag.ToString());
|
||||
for (FName Rel : Relevant) UWingServer::Printf(TEXT(" %s\n"), *Rel.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
WingVariables WingVariables::ParseBlueprintVariables(const UBlueprint *BP)
|
||||
{
|
||||
WingVariables Result;
|
||||
for (const FBPVariableDescription& Desc : BP->NewVariables)
|
||||
{
|
||||
// Skip event dispatchers.
|
||||
if (Desc.VarType.PinCategory == UEdGraphSchema_K2::PC_MCDelegate) continue;
|
||||
|
||||
// Parse the bulk of the flags.
|
||||
Var V = ParseVariableDescription(Desc, Cat::Blueprint);
|
||||
|
||||
// Read default value from CDO if available.
|
||||
if (BP->GeneratedClass)
|
||||
{
|
||||
UObject* CDO = BP->GeneratedClass->GetDefaultObject();
|
||||
FProperty* Prop = BP->GeneratedClass->FindPropertyByName(Desc.VarName);
|
||||
if (CDO && Prop)
|
||||
V.DefaultValue = FWingProperty(Prop, CDO).GetText();
|
||||
}
|
||||
|
||||
Result.Variables.Add(MoveTemp(V));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
WingVariables WingVariables::ParseFunctionLocalVariables(const UK2Node_FunctionEntry *Func)
|
||||
{
|
||||
WingVariables Result;
|
||||
if (!Func) return Result;
|
||||
|
||||
for (const FBPVariableDescription& Desc : Func->LocalVariables)
|
||||
{
|
||||
Var V = ParseVariableDescription(Desc, Cat::FunctionLocal);
|
||||
V.DefaultValue = Desc.DefaultValue;
|
||||
Result.Variables.Add(MoveTemp(V));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void WingVariables::PrintAll(FStringBuilderBase &Out, int32 Indent)
|
||||
{
|
||||
FString Prefix;
|
||||
for (int32 i = 0; i < Indent; i++) Prefix += TEXT(" ");
|
||||
|
||||
for (const Var& V : Variables)
|
||||
{
|
||||
FString TypeStr = UWingTypes::TypeToText(V.Type);
|
||||
FString NameStr = WingUtils::SanitizeName(V.Name);
|
||||
|
||||
// Build flags string.
|
||||
FString FlagsStr;
|
||||
if (V.Flags.Num() > 0)
|
||||
{
|
||||
TArray<FName> Sorted = V.Flags.Array();
|
||||
Sorted.Sort(FNameLexicalLess());
|
||||
for (const FName& Flag : Sorted)
|
||||
{
|
||||
if (!FlagsStr.IsEmpty()) FlagsStr += TEXT(", ");
|
||||
FlagsStr += Flag.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
// Print: type name (flags) = defaultvalue
|
||||
Out.Appendf(TEXT("%s%s %s"), *Prefix, *TypeStr, *NameStr);
|
||||
if (!FlagsStr.IsEmpty())
|
||||
Out.Appendf(TEXT(" (%s)"), *FlagsStr);
|
||||
if (!V.DefaultValue.IsEmpty())
|
||||
Out.Appendf(TEXT(" = %s"), *V.DefaultValue);
|
||||
Out.Append(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void WingVariables::PrintAll(int32 Indent)
|
||||
{
|
||||
PrintAll(UWingServer::GetPrintBuffer(), Indent);
|
||||
}
|
||||
@@ -60,6 +60,9 @@ public:
|
||||
GWingServer->HandlerOutput.Appendf(Fmt, Forward<ArgTypes>(Args)...);
|
||||
}
|
||||
|
||||
/** Get the handler output buffer directly. */
|
||||
static FStringBuilderBase& GetPrintBuffer() { return GWingServer->HandlerOutput; }
|
||||
|
||||
/** Suggest that a manual section be printed after the handler finishes. */
|
||||
static void SuggestManual(WingManual::Section Section) { GWingServer->SuggestedManualSections.Add(Section); }
|
||||
|
||||
|
||||
64
Plugins/UEWingman/Source/UEWingman/Public/WingVariables.h
Normal file
64
Plugins/UEWingman/Source/UEWingman/Public/WingVariables.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "WingProperty.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
|
||||
class UK2Node_FunctionEntry;
|
||||
|
||||
class WingVariables
|
||||
{
|
||||
enum class Cat
|
||||
{
|
||||
Blueprint,
|
||||
FunctionLocal
|
||||
};
|
||||
|
||||
private:
|
||||
struct Var
|
||||
{
|
||||
// Internal name.
|
||||
FName Name;
|
||||
|
||||
// Type. Must be a BlueprintType.
|
||||
FEdGraphPinType Type;
|
||||
|
||||
// Default Value.
|
||||
FString DefaultValue;
|
||||
|
||||
// Boolean flags.
|
||||
TSet<FName> Flags;
|
||||
|
||||
// Add the flag if it's relevant to category C.
|
||||
void AddFlagIfRelevant(FName Flag, Cat C);
|
||||
};
|
||||
|
||||
private:
|
||||
// A list of all the variables.
|
||||
TArray<Var> Variables;
|
||||
|
||||
public:
|
||||
// Returns the set of flags that are supported by this variable category.
|
||||
static const TSet<FName> &GetRelevantFlagSet(Cat C);
|
||||
|
||||
|
||||
// Check if the variable list is empty.
|
||||
bool IsEmpty() const { return Variables.IsEmpty(); }
|
||||
|
||||
// Print all the variables to a string builder.
|
||||
void PrintAll(FStringBuilderBase &Out, int32 Indent = 0);
|
||||
|
||||
// Print all the variables via UWingServer.
|
||||
void PrintAll(int32 Indent = 0);
|
||||
|
||||
// Make sure that this variable list makes sense for the given context.
|
||||
bool CheckSanity(Cat Category);
|
||||
|
||||
// Parse variables from a given source.
|
||||
static WingVariables ParseBlueprintVariables(const UBlueprint *BP);
|
||||
static WingVariables ParseFunctionLocalVariables(const UK2Node_FunctionEntry *F);
|
||||
|
||||
private:
|
||||
static Var ParseVariableDescription(const FBPVariableDescription &V, Cat C);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user