More work on the new variable list functionality
This commit is contained in:
BIN
Content/Testing/BP_Test.uasset
LFS
BIN
Content/Testing/BP_Test.uasset
LFS
Binary file not shown.
@@ -15,6 +15,7 @@
|
|||||||
#include "AnimationGraph.h"
|
#include "AnimationGraph.h"
|
||||||
#include "AnimationGraphSchema.h"
|
#include "AnimationGraphSchema.h"
|
||||||
#include "AnimationStateMachineSchema.h"
|
#include "AnimationStateMachineSchema.h"
|
||||||
|
#include "WingVariables.h"
|
||||||
#include "WingWidgets.h"
|
#include "WingWidgets.h"
|
||||||
#include "WidgetBlueprint.h"
|
#include "WidgetBlueprint.h"
|
||||||
#include "Blueprint/WidgetTree.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
|
// Components
|
||||||
TArray<UWingComponentReference*> Components3 = UWingComponentReference::GetAll(BP);
|
TArray<UWingComponentReference*> Components3 = UWingComponentReference::GetAll(BP);
|
||||||
if (!Components3.IsEmpty())
|
if (!Components3.IsEmpty())
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "K2Node_CallFunction.h"
|
#include "K2Node_CallFunction.h"
|
||||||
#include "K2Node_FunctionEntry.h"
|
#include "K2Node_FunctionEntry.h"
|
||||||
#include "WingFunctionArgs.h"
|
#include "WingFunctionArgs.h"
|
||||||
|
#include "WingVariables.h"
|
||||||
#include "MaterialGraph/MaterialGraphNode.h"
|
#include "MaterialGraph/MaterialGraphNode.h"
|
||||||
|
|
||||||
WingGraphExport::WingGraphExport(UEdGraph* InGraph)
|
WingGraphExport::WingGraphExport(UEdGraph* InGraph)
|
||||||
@@ -292,13 +293,11 @@ void WingGraphExport::EmitLocalVariables()
|
|||||||
UK2Node_FunctionEntry* EntryNode = Cast<UK2Node_FunctionEntry>(Node);
|
UK2Node_FunctionEntry* EntryNode = Cast<UK2Node_FunctionEntry>(Node);
|
||||||
if (!EntryNode) continue;
|
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("Function Local Variables:\n"));
|
||||||
Output.Appendf(TEXT("local %s %s = %s\n"),
|
Locals.PrintAll(Output, 4);
|
||||||
*UWingTypes::TypeToText(Var.VarType),
|
|
||||||
*WingUtils::FormatName(Var),
|
|
||||||
*Default);
|
|
||||||
}
|
}
|
||||||
break;
|
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)...);
|
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. */
|
/** Suggest that a manual section be printed after the handler finishes. */
|
||||||
static void SuggestManual(WingManual::Section Section) { GWingServer->SuggestedManualSections.Add(Section); }
|
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