Progress on variable modification
This commit is contained in:
BIN
Content/Testing/BP_Test.uasset
LFS
BIN
Content/Testing/BP_Test.uasset
LFS
Binary file not shown.
@@ -41,18 +41,17 @@ public:
|
||||
if (!BP) return;
|
||||
|
||||
// Parse the variable declarations.
|
||||
WingVariables Parsed;
|
||||
if (!WingVariables::ParseString(Variables, Parsed)) return;
|
||||
if (Parsed.IsEmpty()) { UWingServer::Print(TEXT("ERROR: No variables specified.\n")); return; }
|
||||
if (!Parsed.CheckSanity(WingVariables::Cat::Blueprint)) return;
|
||||
WingVariables Vars;
|
||||
if (!Vars.ParseString(Variables)) return;
|
||||
if (Vars.IsEmpty()) { UWingServer::Print(TEXT("ERROR: No variables specified.\n")); return; }
|
||||
|
||||
// Check for name collisions against existing variables, components, and the like.
|
||||
TSet<FName> Names;
|
||||
FBlueprintEditorUtils::GetClassVariableList(BP, Names);
|
||||
if (!WingUtils::FindNoDuplicateNames(Names, Parsed.GetVariables(), TEXT("variable or component"))) return;
|
||||
if (!WingUtils::FindNoDuplicateNames(Names, Vars.GetVariables(), TEXT("variable or component"))) return;
|
||||
|
||||
// Create the variables.
|
||||
for (const WingVariables::Var& V : Parsed.GetVariables())
|
||||
for (const WingVariables::Var& V : Vars.GetVariables())
|
||||
{
|
||||
if (!FBlueprintEditorUtils::AddMemberVariable(BP, V.Name, V.Type))
|
||||
{
|
||||
@@ -63,10 +62,10 @@ public:
|
||||
}
|
||||
|
||||
// Update everything.
|
||||
if (!Parsed.AssociateBlueprintNewVariables(BP)) return;
|
||||
Parsed.UpdateVariableFlags();
|
||||
if (!Vars.AssociateBlueprintVariables(BP)) return;
|
||||
Vars.UpdateVariableFlags();
|
||||
FKismetEditorUtilities::CompileBlueprint(BP);
|
||||
if (!Parsed.UpdateVariableDefaults()) return;
|
||||
if (!Vars.UpdateVariableDefaults()) return;
|
||||
UWingServer::Printf(TEXT("Success.\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,8 +32,9 @@ public:
|
||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||
if (!BP) return;
|
||||
|
||||
WingVariables Vars = WingVariables::ParseBlueprintVariables(BP);
|
||||
WingVariables Vars;
|
||||
Vars.LoadBlueprintVariables(BP);
|
||||
if (Vars.IsEmpty()) { UWingServer::Print(TEXT("No variables.\n")); return; }
|
||||
Vars.PrintAll();
|
||||
Vars.PrintAll(UWingServer::GetPrintBuffer(), true, TEXT("Blueprint Variables:"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,19 +39,19 @@ public:
|
||||
if (!BP) return;
|
||||
|
||||
// Parse the variable declarations.
|
||||
WingVariables Parsed;
|
||||
if (!WingVariables::ParseString(Variables, Parsed)) return;
|
||||
if (Parsed.IsEmpty()) { UWingServer::Print(TEXT("ERROR: No variables specified.\n")); return; }
|
||||
if (!Parsed.CheckSanity(WingVariables::Cat::Blueprint)) return;
|
||||
WingVariables Vars;
|
||||
if (!Vars.ParseString(Variables)) return;
|
||||
if (Vars.IsEmpty()) { UWingServer::Print(TEXT("ERROR: No variables specified.\n")); return; }
|
||||
if (!Vars.CheckSanity(WingVariables::Cat::BlueprintVariables)) return;
|
||||
|
||||
// Associate with existing blueprint variables.
|
||||
if (!Parsed.AssociateBlueprintNewVariables(BP)) return;
|
||||
if (!Vars.AssociateBlueprintVariables(BP)) return;
|
||||
|
||||
// Update types and flags, compile, then update defaults.
|
||||
Parsed.UpdateVariableTypes();
|
||||
Parsed.UpdateVariableFlags();
|
||||
Vars.UpdateVariableTypes();
|
||||
Vars.UpdateVariableFlags();
|
||||
FKismetEditorUtilities::CompileBlueprint(BP);
|
||||
if (!Parsed.UpdateVariableDefaults()) return;
|
||||
if (!Vars.UpdateVariableDefaults()) return;
|
||||
|
||||
UWingServer::Printf(TEXT("Success.\n"));
|
||||
}
|
||||
|
||||
@@ -84,12 +84,9 @@ public:
|
||||
}
|
||||
|
||||
// Variables (new format)
|
||||
WingVariables BlueprintVars = WingVariables::ParseBlueprintVariables(BP);
|
||||
if (!BlueprintVars.IsEmpty())
|
||||
{
|
||||
UWingServer::Print(TEXT("\nVariables (new format):\n"));
|
||||
BlueprintVars.PrintAll(2);
|
||||
}
|
||||
WingVariables BlueprintVars;
|
||||
BlueprintVars.LoadBlueprintVariables(BP);
|
||||
BlueprintVars.PrintAll(UWingServer::GetPrintBuffer(), true, TEXT("Blueprint Variables 2:"));
|
||||
|
||||
// Components
|
||||
TArray<UWingComponentReference*> Components3 = UWingComponentReference::GetAll(BP);
|
||||
|
||||
@@ -33,27 +33,8 @@ public:
|
||||
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
||||
if (!G) return;
|
||||
|
||||
FStringBuilderBase &Output = UWingServer::GetPrintBuffer();
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
||||
FBlueprintEditorUtils::GetEntryAndResultNodes(G, EntryNode, ResultNode);
|
||||
WingVariables Arguments = WingVariables::ParseEditablePinBase(EntryNode.Get());
|
||||
WingVariables ReturnValues = WingVariables::ParseEditablePinBase(EntryNode.Get());
|
||||
WingVariables Locals = WingVariables::ParseFunctionLocalVariables(EntryNode.Get());
|
||||
if (!Arguments.GetVariables().IsEmpty())
|
||||
{
|
||||
Output.Appendf(TEXT("Arguments:\n"));
|
||||
Arguments.PrintAll(Output, 4);
|
||||
}
|
||||
if (!ReturnValues.GetVariables().IsEmpty())
|
||||
{
|
||||
Output.Appendf(TEXT("ReturnValues:\n"));
|
||||
ReturnValues.PrintAll(Output, 4);
|
||||
}
|
||||
if (!Locals.GetVariables().IsEmpty())
|
||||
{
|
||||
Output.Appendf(TEXT("LocalVariables:\n"));
|
||||
Locals.PrintAll(Output, 4);
|
||||
}
|
||||
WingGraphVariables Vars;
|
||||
Vars.LoadGraph(G);
|
||||
Vars.PrintAll(UWingServer::GetPrintBuffer(), true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,15 +18,21 @@ class UWing_GraphVariables_Modify : public UObject, public IWingHandler
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Path to a function graph (e.g. '/Game/MyBP,graph:MyFunction')"))
|
||||
UPROPERTY(meta=(Description="Path to a graph"))
|
||||
FString Graph;
|
||||
|
||||
UPROPERTY(meta=(Description="Variable declarations, one per line. Format: type name = default"))
|
||||
FString Variables;
|
||||
UPROPERTY(meta=(Optional, Description="Argument declarations, one per line."))
|
||||
FString Arguments;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Return Value declarations, one per line."))
|
||||
FString ReturnValues;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Local Variable declarations, one per line."))
|
||||
FString LocalVariables;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Modify existing local variables of a function graph.");
|
||||
return TEXT("Modify existing arguments, return values, and local variables of a graph.");
|
||||
}
|
||||
|
||||
virtual void Handle() override
|
||||
@@ -35,15 +41,13 @@ public:
|
||||
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
||||
if (!G) return;
|
||||
|
||||
WingVariables Parsed;
|
||||
if (!WingVariables::ParseString(Variables, Parsed)) return;
|
||||
if (Parsed.IsEmpty()) { UWingServer::Print(TEXT("ERROR: No variables specified.\n")); return; }
|
||||
if (!Parsed.CheckSanity(WingVariables::Cat::FunctionLocal)) return;
|
||||
|
||||
if (!Parsed.AssociateFunctionLocalVariables(G)) return;
|
||||
Parsed.UpdateVariableTypes();
|
||||
Parsed.UpdateVariableFlags();
|
||||
Parsed.UpdateVariableDefaults();
|
||||
WingGraphVariables Vars;
|
||||
if (!Vars.ParseStrings(Arguments, ReturnValues, LocalVariables)) return;
|
||||
if (!Vars.CheckSanity(G)) return;
|
||||
if (!Vars.AssociateGraph(G)) return;
|
||||
Vars.UpdateVariableTypes();
|
||||
Vars.UpdateVariableFlags();
|
||||
Vars.UpdateVariableDefaults();
|
||||
|
||||
UWingServer::Printf(TEXT("Success.\n"));
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "WingHandler.h"
|
||||
#include "WingServer.h"
|
||||
#include "WingVariables.h"
|
||||
#include "Test_ParseVariables.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
class UWing_Test_ParseVariables : public UObject, public IWingHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Variable declarations, one per line. Format: type name (flags) = default"))
|
||||
FString Variables;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Test: parse variable declarations and print them back out.");
|
||||
}
|
||||
|
||||
virtual void Handle() override
|
||||
{
|
||||
WingVariables Parsed;
|
||||
if (!WingVariables::ParseString(Variables, Parsed)) return;
|
||||
|
||||
UWingServer::Print(TEXT("Parsed variables:\n"));
|
||||
Parsed.PrintAll(1);
|
||||
}
|
||||
};
|
||||
@@ -289,27 +289,9 @@ void WingGraphExport::EmitMaterialProperties(UEdGraphNode* Node, FStringBuilderB
|
||||
|
||||
void WingGraphExport::EmitLocalVariables()
|
||||
{
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
||||
FBlueprintEditorUtils::GetEntryAndResultNodes(Graph, EntryNode, ResultNode);
|
||||
WingVariables Arguments = WingVariables::ParseEditablePinBase(EntryNode.Get());
|
||||
WingVariables ReturnValues = WingVariables::ParseEditablePinBase(EntryNode.Get());
|
||||
WingVariables Locals = WingVariables::ParseFunctionLocalVariables(EntryNode.Get());
|
||||
if (!Arguments.GetVariables().IsEmpty())
|
||||
{
|
||||
Output.Appendf(TEXT("Arguments:\n"));
|
||||
Arguments.PrintAll(Output, 4);
|
||||
}
|
||||
if (!ReturnValues.GetVariables().IsEmpty())
|
||||
{
|
||||
Output.Appendf(TEXT("ReturnValues:\n"));
|
||||
ReturnValues.PrintAll(Output, 4);
|
||||
}
|
||||
if (!Locals.GetVariables().IsEmpty())
|
||||
{
|
||||
Output.Appendf(TEXT("LocalVariables:\n"));
|
||||
Locals.PrintAll(Output, 4);
|
||||
}
|
||||
WingGraphVariables Vars;
|
||||
Vars.LoadGraph(Graph);
|
||||
Vars.PrintAll(Output, false);
|
||||
}
|
||||
|
||||
void WingGraphExport::EmitGraph()
|
||||
|
||||
@@ -21,15 +21,17 @@ 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;
|
||||
case Cat::BlueprintVariables: return Flags_BlueprintVariables;
|
||||
case Cat::LocalVariables: return Flags_None;
|
||||
case Cat::FunctionArguments: return Flags_None;
|
||||
case Cat::FunctionReturnValues: return Flags_None;
|
||||
case Cat::MacroEntry: return Flags_None;
|
||||
case Cat::MacroExit: return Flags_None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,19 +40,36 @@ void WingVariables::Var::AddFlagIfRelevant(FName Flag, WingVariables::Cat C)
|
||||
if (GetRelevantFlagSet(C).Contains(Flag)) Flags.Add(Flag);
|
||||
}
|
||||
|
||||
WingVariables WingVariables::ParseBlueprintVariables(UBlueprint *BP)
|
||||
void WingVariables::Clear()
|
||||
{
|
||||
WingVariables Result;
|
||||
Result.Category = Cat::Blueprint;
|
||||
Result.Blueprint = BP;
|
||||
Variables.Empty();
|
||||
Blueprint = nullptr;
|
||||
FuncEntry = nullptr;
|
||||
PinBase = nullptr;
|
||||
}
|
||||
|
||||
void WingVariables::ClearAssociation()
|
||||
{
|
||||
for (Var V : Variables)
|
||||
{
|
||||
V.BPVar = nullptr;
|
||||
V.Pin = nullptr;
|
||||
}
|
||||
Blueprint = nullptr;
|
||||
FuncEntry = nullptr;
|
||||
PinBase = nullptr;
|
||||
}
|
||||
|
||||
void WingVariables::LoadBlueprintVariables(UBlueprint *BP)
|
||||
{
|
||||
Clear();
|
||||
for (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);
|
||||
V.BPVar = &Desc;
|
||||
Var V = ParseVariableDescription(Desc, Cat::BlueprintVariables);
|
||||
|
||||
// Read default value from CDO if available.
|
||||
if (BP->GeneratedClass)
|
||||
@@ -58,63 +77,51 @@ WingVariables WingVariables::ParseBlueprintVariables(UBlueprint *BP)
|
||||
UObject* CDO = BP->GeneratedClass->GetDefaultObject();
|
||||
FProperty* Prop = BP->GeneratedClass->FindPropertyByName(Desc.VarName);
|
||||
if (CDO && Prop)
|
||||
{
|
||||
V.DefaultValue = FWingProperty(Prop, CDO).GetText();
|
||||
V.DefaultSpecified = true;
|
||||
}
|
||||
}
|
||||
|
||||
Result.Variables.Add(MoveTemp(V));
|
||||
Variables.Add(MoveTemp(V));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
WingVariables WingVariables::ParseFunctionLocalVariables(UK2Node_EditablePinBase *Node)
|
||||
void WingVariables::LoadLocalVariables(UK2Node_EditablePinBase *Node)
|
||||
{
|
||||
WingVariables Result;
|
||||
Clear();
|
||||
if (UK2Node_FunctionEntry *Func = Cast<UK2Node_FunctionEntry>(Node))
|
||||
{
|
||||
Result.Category = Cat::FunctionLocal;
|
||||
Result.PinBase = Node;
|
||||
for (FBPVariableDescription& Desc : Func->LocalVariables)
|
||||
{
|
||||
Var V = ParseVariableDescription(Desc, Cat::FunctionLocal);
|
||||
Var V = ParseVariableDescription(Desc, Cat::LocalVariables);
|
||||
V.DefaultValue = Desc.DefaultValue;
|
||||
V.BPVar = &Desc;
|
||||
Result.Variables.Add(MoveTemp(V));
|
||||
V.DefaultSpecified = true;
|
||||
Variables.Add(MoveTemp(V));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Category = Cat::Empty;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
WingVariables WingVariables::ParseEditablePinBase(UK2Node_EditablePinBase* Node)
|
||||
void WingVariables::LoadEditablePinBase(UK2Node_EditablePinBase* Node)
|
||||
{
|
||||
WingVariables Result;
|
||||
Clear();
|
||||
if (Node != nullptr)
|
||||
{
|
||||
Result.Category = Cat::EditablePinBase;
|
||||
Result.PinBase = Node;
|
||||
for (const TSharedPtr<FUserPinInfo>& PinInfo : Node->UserDefinedPins)
|
||||
{
|
||||
Var V;
|
||||
V.Name = PinInfo->PinName;
|
||||
V.Type = PinInfo->PinType;
|
||||
V.DefaultValue = PinInfo->PinDefaultValue;
|
||||
V.Pin = PinInfo;
|
||||
Result.Variables.Add(MoveTemp(V));
|
||||
V.DefaultSpecified = true;
|
||||
Variables.Add(MoveTemp(V));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Category = Cat::Empty;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool WingVariables::AssociateBlueprintNewVariables(UBlueprint *BP)
|
||||
bool WingVariables::AssociateBlueprintVariables(UBlueprint *BP)
|
||||
{
|
||||
Category = Cat::Blueprint;
|
||||
ClearAssociation();
|
||||
Blueprint = BP;
|
||||
for (Var &V : Variables)
|
||||
{
|
||||
@@ -122,15 +129,15 @@ bool WingVariables::AssociateBlueprintNewVariables(UBlueprint *BP)
|
||||
if (Desc == nullptr) return false;
|
||||
V.BPVar = Desc;
|
||||
}
|
||||
Blueprint = BP;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WingVariables::AssociateFunctionLocalVariables(UK2Node_EditablePinBase *Node)
|
||||
bool WingVariables::AssociateLocalVariables(UK2Node_EditablePinBase *Node)
|
||||
{
|
||||
Category = Cat::FunctionLocal;
|
||||
ClearAssociation();
|
||||
if (UK2Node_FunctionEntry *Func = Cast<UK2Node_FunctionEntry>(Node))
|
||||
{
|
||||
FuncEntry = Func;
|
||||
for (Var &V : Variables)
|
||||
{
|
||||
FBPVariableDescription *Desc = WingUtils::FindOneWithInternalID(V.Name, Func->LocalVariables, TEXT("local variable"));
|
||||
@@ -141,77 +148,75 @@ bool WingVariables::AssociateFunctionLocalVariables(UK2Node_EditablePinBase *Nod
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Variables.IsEmpty()) { return true; }
|
||||
UWingServer::Printf(TEXT("Graph can't have local variables, not a function graph: %s\n"),
|
||||
*WingUtils::FormatName(Node->GetGraph()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WingVariables::AssociateEditablePinBase(UK2Node_EditablePinBase *InPinBase)
|
||||
bool WingVariables::AssociateEditablePinBase(UK2Node_EditablePinBase *Node)
|
||||
{
|
||||
if (!InPinBase || !InPinBase->IsEditable())
|
||||
ClearAssociation();
|
||||
if (Node != nullptr)
|
||||
{
|
||||
UWingServer::Print(TEXT("ERROR: Node does not have editable pins.\n"));
|
||||
return false;
|
||||
PinBase = Node;
|
||||
for (Var &V : Variables)
|
||||
{
|
||||
TSharedPtr<FUserPinInfo> *Found = WingUtils::FindOneWithInternalID(V.Name, Node->UserDefinedPins, TEXT("pin"));
|
||||
if (!Found) return false;
|
||||
V.Pin = *Found;
|
||||
}
|
||||
}
|
||||
Category = Cat::EditablePinBase;
|
||||
PinBase = InPinBase;
|
||||
for (Var &V : Variables)
|
||||
else
|
||||
{
|
||||
TSharedPtr<FUserPinInfo> *Found = WingUtils::FindOneWithInternalID(V.Name, InPinBase->UserDefinedPins, TEXT("pin"));
|
||||
if (!Found) return false;
|
||||
V.Pin = *Found;
|
||||
if (Variables.IsEmpty()) return true;
|
||||
UWingServer::Printf(TEXT("Cannot modify variables, graph node does not exist yet"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WingVariables::UpdateVariableTypes()
|
||||
{
|
||||
switch (Category)
|
||||
{
|
||||
case Cat::Blueprint: UpdateBlueprintVariableTypes(); break;
|
||||
case Cat::FunctionLocal: UpdateLocalVariableTypes(); break;
|
||||
case Cat::EditablePinBase: UpdateEditablePinBaseTypes(); break;
|
||||
default: return;
|
||||
}
|
||||
if (Blueprint) return UpdateBlueprintVariableTypes();
|
||||
if (FuncEntry) return UpdateLocalVariableTypes();
|
||||
if (PinBase) return UpdateEditablePinBaseTypes();
|
||||
}
|
||||
|
||||
void WingVariables::UpdateVariableFlags()
|
||||
{
|
||||
switch (Category)
|
||||
{
|
||||
case Cat::Blueprint: UpdateBlueprintVariableFlags(); break;
|
||||
case Cat::FunctionLocal: UpdateLocalVariableFlags(); break;
|
||||
case Cat::EditablePinBase: UpdateEditablePinBaseFlags(); break;
|
||||
default: return;
|
||||
}
|
||||
if (Blueprint) return UpdateBlueprintVariableFlags();
|
||||
if (FuncEntry) return UpdateLocalVariableFlags();
|
||||
if (PinBase) return UpdateEditablePinBaseFlags();
|
||||
}
|
||||
|
||||
bool WingVariables::UpdateVariableDefaults()
|
||||
{
|
||||
switch (Category)
|
||||
{
|
||||
case Cat::Blueprint: return UpdateBlueprintVariableDefaults(); break;
|
||||
case Cat::FunctionLocal: return UpdateLocalVariableDefaults(); break;
|
||||
case Cat::EditablePinBase: return UpdateEditablePinBaseDefaults(); break;
|
||||
default: return true;
|
||||
}
|
||||
if (Blueprint) return UpdateBlueprintVariableDefaults();
|
||||
if (FuncEntry) return UpdateLocalVariableDefaults();
|
||||
if (PinBase) return UpdateEditablePinBaseDefaults();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WingVariables::CheckEmpty(Cat Category)
|
||||
{
|
||||
if (!Variables.IsEmpty())
|
||||
{
|
||||
UWingServer::Printf(TEXT("This kind of graph is not allowed to have %s"),
|
||||
*StaticEnum<EWingVariableCategory>()->GetNameStringByValue(int(Category)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WingVariables::CheckSanity(Cat Category)
|
||||
{
|
||||
const TSet<FName> &Relevant = GetRelevantFlagSet(Category);
|
||||
TSet<FName> NamesUsed;
|
||||
for (const Var &Variable : Variables)
|
||||
{
|
||||
FString VarName = WingUtils::ExternalizeID(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);
|
||||
@@ -235,7 +240,6 @@ bool WingVariables::CheckSanity(Cat Category)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WingVariables::ParseVariableFlags(WingTokenizer &Tok, TSet<FName> &Out)
|
||||
{
|
||||
Tok.Advance(); // Step over open-paren
|
||||
@@ -346,11 +350,16 @@ WingVariables::Var WingVariables::ParseVariableDescription(const FBPVariableDesc
|
||||
return Result;
|
||||
}
|
||||
|
||||
void WingVariables::PrintAll(FStringBuilderBase &Out, int32 Indent)
|
||||
void WingVariables::PrintAll(FStringBuilderBase &Out, bool Always, const TCHAR *Header)
|
||||
{
|
||||
FString Prefix;
|
||||
for (int32 i = 0; i < Indent; i++) Prefix += TEXT(" ");
|
||||
|
||||
if (Header != nullptr)
|
||||
{
|
||||
if (Always || (!Variables.IsEmpty()))
|
||||
{
|
||||
Out.Append(Header);
|
||||
Out.AppendChar('\n');
|
||||
}
|
||||
}
|
||||
for (const Var& V : Variables)
|
||||
{
|
||||
FString TypeStr = UWingTypes::TypeToText(V.Type);
|
||||
@@ -370,7 +379,7 @@ void WingVariables::PrintAll(FStringBuilderBase &Out, int32 Indent)
|
||||
}
|
||||
|
||||
// Print: type name (flags) = defaultvalue
|
||||
Out.Appendf(TEXT("%s%s %s"), *Prefix, *TypeStr, *NameStr);
|
||||
Out.Appendf(TEXT(" %s %s"), *TypeStr, *NameStr);
|
||||
if (!FlagsStr.IsEmpty())
|
||||
Out.Appendf(TEXT(" (%s)"), *FlagsStr);
|
||||
if (!V.DefaultValue.IsEmpty())
|
||||
@@ -379,11 +388,6 @@ void WingVariables::PrintAll(FStringBuilderBase &Out, int32 Indent)
|
||||
}
|
||||
}
|
||||
|
||||
void WingVariables::PrintAll(int32 Indent)
|
||||
{
|
||||
PrintAll(UWingServer::GetPrintBuffer(), Indent);
|
||||
}
|
||||
|
||||
void WingVariables::UpdateBlueprintVariableTypes()
|
||||
{
|
||||
for (const Var &Input : Variables)
|
||||
@@ -505,17 +509,17 @@ bool WingVariables::UpdateEditablePinBaseDefaults()
|
||||
return true;
|
||||
}
|
||||
|
||||
void WingGraphVariables::ParseGraph(const UEdGraph *Graph)
|
||||
void WingGraphVariables::LoadGraph(const UEdGraph *Graph)
|
||||
{
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
||||
FBlueprintEditorUtils::GetEntryAndResultNodes(Graph, EntryNode, ResultNode);
|
||||
Arguments = WingVariables::ParseEditablePinBase(EntryNode.Get());
|
||||
ReturnValues = WingVariables::ParseEditablePinBase(ResultNode.Get());
|
||||
LocalVariables = WingVariables::ParseLocalVariables(EntryNode.Get());
|
||||
Arguments.LoadEditablePinBase(EntryNode.Get());
|
||||
ReturnValues.LoadEditablePinBase(ResultNode.Get());
|
||||
LocalVariables.LoadLocalVariables(EntryNode.Get());
|
||||
}
|
||||
|
||||
bool WingGraphVariables::ParseAll(const FString &A, const FString &R, const FString &L)
|
||||
bool WingGraphVariables::ParseStrings(const FString &A, const FString &R, const FString &L)
|
||||
{
|
||||
if (!Arguments.ParseString(A)) return false;
|
||||
if (!ReturnValues.ParseString(R)) return false;
|
||||
@@ -523,7 +527,7 @@ bool WingGraphVariables::ParseAll(const FString &A, const FString &R, const FStr
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WingGraphVariables::AssociateAll(const UEdGraph *Graph)
|
||||
bool WingGraphVariables::AssociateGraph(const UEdGraph *Graph)
|
||||
{
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
||||
@@ -534,3 +538,55 @@ bool WingGraphVariables::AssociateAll(const UEdGraph *Graph)
|
||||
if (!LocalVariables.AssociateLocalVariables(EntryNode.Get())) OK = false;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void WingGraphVariables::PrintAll(FStringBuilderBase &Out, bool Always)
|
||||
{
|
||||
Arguments.PrintAll(Out, Always, TEXT("Arguments:"));
|
||||
ReturnValues.PrintAll(Out, Always, TEXT("ReturnValues:"));
|
||||
LocalVariables.PrintAll(Out, Always, TEXT("LocalVariables:"));
|
||||
}
|
||||
|
||||
void WingGraphVariables::UpdateVariableTypes()
|
||||
{
|
||||
Arguments.UpdateVariableTypes();
|
||||
ReturnValues.UpdateVariableTypes();
|
||||
LocalVariables.UpdateVariableTypes();
|
||||
}
|
||||
|
||||
void WingGraphVariables::UpdateVariableFlags()
|
||||
{
|
||||
Arguments.UpdateVariableFlags();
|
||||
ReturnValues.UpdateVariableFlags();
|
||||
LocalVariables.UpdateVariableFlags();
|
||||
}
|
||||
|
||||
bool WingGraphVariables::UpdateVariableDefaults()
|
||||
{
|
||||
return Arguments.UpdateVariableDefaults() &&
|
||||
ReturnValues.UpdateVariableDefaults() &&
|
||||
LocalVariables.UpdateVariableDefaults();
|
||||
}
|
||||
|
||||
bool WingGraphVariables::CheckSanity(const UEdGraph *Graph)
|
||||
{
|
||||
EGraphType Type = Graph->GetSchema()->GetGraphType(Graph);
|
||||
if (Type == EGraphType::GT_Function)
|
||||
{
|
||||
return Arguments.CheckSanity(Cat::FunctionArguments) &&
|
||||
ReturnValues.CheckSanity(Cat::FunctionReturnValues) &&
|
||||
LocalVariables.CheckSanity(Cat::LocalVariables);
|
||||
}
|
||||
else if (Type == EGraphType::GT_Macro)
|
||||
{
|
||||
return Arguments.CheckSanity(Cat::MacroEntry) &&
|
||||
ReturnValues.CheckSanity(Cat::MacroExit) &&
|
||||
LocalVariables.CheckEmpty(Cat::LocalVariables);
|
||||
}
|
||||
else
|
||||
{
|
||||
UWingServer::Printf(
|
||||
TEXT("Graphs of this type may not have arguments, return values, or local variables."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,20 +3,26 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "EdGraph/EdGraphPin.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "K2Node_EditablePinBase.h"
|
||||
|
||||
struct WingTokenizer;
|
||||
class UK2Node_EditablePinBase;
|
||||
class UK2Node_FunctionEntry;
|
||||
|
||||
UENUM()
|
||||
enum class EWingVariableCategory : uint8
|
||||
{
|
||||
BlueprintVariables,
|
||||
LocalVariables,
|
||||
FunctionArguments,
|
||||
FunctionReturnValues,
|
||||
MacroEntry,
|
||||
MacroExit
|
||||
};
|
||||
|
||||
class WingVariables
|
||||
{
|
||||
public:
|
||||
enum class Cat
|
||||
{
|
||||
Empty,
|
||||
Blueprint,
|
||||
LocalVariable,
|
||||
EditablePinBase,
|
||||
};
|
||||
using Cat = EWingVariableCategory;
|
||||
|
||||
struct Var
|
||||
{
|
||||
@@ -48,15 +54,15 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
// The category of these variables.
|
||||
Cat Category;
|
||||
|
||||
// A list of all the variables.
|
||||
TArray<Var> Variables;
|
||||
|
||||
// A pointer to a blueprint.
|
||||
UBlueprint *Blueprint = nullptr;
|
||||
|
||||
// A pointer to a Function entry node.
|
||||
UK2Node_FunctionEntry *FuncEntry = nullptr;
|
||||
|
||||
// A pointer to an editable pin base.
|
||||
UK2Node_EditablePinBase* PinBase = nullptr;
|
||||
|
||||
@@ -71,26 +77,35 @@ public:
|
||||
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);
|
||||
void PrintAll(FStringBuilderBase &Out, bool Always, const TCHAR *Header);
|
||||
|
||||
// Make sure that this variable list makes sense for the given context.
|
||||
bool CheckSanity(Cat Category);
|
||||
// Clear everything
|
||||
void Clear();
|
||||
|
||||
// Clear any association.
|
||||
void ClearAssociation();
|
||||
|
||||
// Check the sanity.
|
||||
bool CheckSanity(Cat C);
|
||||
|
||||
// Check that the variables are empty.
|
||||
bool CheckEmpty(Cat C);
|
||||
|
||||
// Parse variables from a string. One variable per line.
|
||||
// Format: type name (flag1, flag2) = defaultvalue
|
||||
// Returns false on parse error.
|
||||
bool ParseString(const FString &Input);
|
||||
|
||||
// Parse variables from a given source.
|
||||
static WingVariables ParseBlueprintVariables(UBlueprint *BP);
|
||||
static WingVariables ParseLocalVariables(UK2Node_EditablePinBase* Node);
|
||||
static WingVariables ParseEditablePinBase(UK2Node_EditablePinBase* Node);
|
||||
// Make a best effort to load all available existing state.
|
||||
// This does not associate the variables. If you want to manipulate
|
||||
// the variables, you'll have to associate them.
|
||||
void LoadBlueprintVariables(UBlueprint *BP);
|
||||
void LoadLocalVariables(UK2Node_EditablePinBase* Node);
|
||||
void LoadEditablePinBase(UK2Node_EditablePinBase* Node);
|
||||
|
||||
// Associate every variable in the list with an existing blueprint variable.
|
||||
bool AssociateBlueprintNewVariables(UBlueprint *BP);
|
||||
// Associate every variable in the list with an existing
|
||||
// variable in a blueprint or graph.
|
||||
bool AssociateBlueprintVariables(UBlueprint *BP);
|
||||
bool AssociateLocalVariables(UK2Node_EditablePinBase* Node);
|
||||
bool AssociateEditablePinBase(UK2Node_EditablePinBase* Node);
|
||||
|
||||
@@ -123,8 +138,19 @@ struct WingGraphVariables
|
||||
|
||||
WingGraphVariables() {}
|
||||
|
||||
void ParseGraph(const UEdGraph *Graph);
|
||||
bool ParseStrings(const FString &A, const FString &R, const FString &L);
|
||||
using Cat = WingVariables::Cat;
|
||||
|
||||
void LoadGraph(const UEdGraph *Graph);
|
||||
bool AssociateGraph(const UEdGraph *Graph);
|
||||
bool ParseStrings(const FString &A, const FString &R, const FString &L);
|
||||
void PrintAll(FStringBuilderBase &Out, bool Always);
|
||||
void UpdateVariableTypes();
|
||||
void UpdateVariableFlags();
|
||||
bool UpdateVariableDefaults();
|
||||
bool CheckSanity(const UEdGraph *Graph);
|
||||
|
||||
private:
|
||||
static Cat GraphEntryCategory(const UEdGraph *Graph);
|
||||
static Cat GraphExitCategory(const UEdGraph *Graph);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user