WingVariables for the win
This commit is contained in:
@@ -5,12 +5,9 @@
|
|||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingFunctionArgs.h"
|
#include "WingVariables.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
#include "EdGraph/EdGraphNode.h"
|
|
||||||
#include "K2Node_EditablePinBase.h"
|
|
||||||
#include "K2Node_FunctionResult.h"
|
|
||||||
#include "EdGraphSchema_K2.h"
|
#include "EdGraphSchema_K2.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
#include "BlueprintGraph_Create.generated.h"
|
#include "BlueprintGraph_Create.generated.h"
|
||||||
@@ -35,11 +32,11 @@ public:
|
|||||||
UPROPERTY(meta=(Description="Type of graph: function or macro"))
|
UPROPERTY(meta=(Description="Type of graph: function or macro"))
|
||||||
FString GraphType;
|
FString GraphType;
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Arguments expressed as: int x,float y"))
|
UPROPERTY(meta=(Optional, Description="Input variables, one per line"))
|
||||||
FString Arguments;
|
FString InputVariables;
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Return values expressed as: int x,float y"))
|
UPROPERTY(meta=(Optional, Description="Output variables, one per line"))
|
||||||
FString ReturnValues;
|
FString OutputVariables;
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
@@ -81,9 +78,10 @@ public:
|
|||||||
if (!WingUtils::FindNoneWithInternalID(InternalID, WingUtils::AllGraphs(BP), TEXT("Graph")))
|
if (!WingUtils::FindNoneWithInternalID(InternalID, WingUtils::AllGraphs(BP), TEXT("Graph")))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Validate argument and return value types before making changes
|
// Parse and validate variables before making changes
|
||||||
if (!Arguments.IsEmpty() && !WingFunctionArgs::CheckArgs(Arguments)) return;
|
WingVariables Vars;
|
||||||
if (!ReturnValues.IsEmpty() && !WingFunctionArgs::CheckArgs(ReturnValues)) return;
|
if (!Vars.InputVariables.ParseString(InputVariables)) return;
|
||||||
|
if (!Vars.OutputVariables.ParseString(OutputVariables)) return;
|
||||||
|
|
||||||
// Create the Graph
|
// Create the Graph
|
||||||
UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(BP, InternalID,
|
UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(BP, InternalID,
|
||||||
@@ -104,17 +102,10 @@ public:
|
|||||||
FBlueprintEditorUtils::AddMacroGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromClass=*/nullptr);
|
FBlueprintEditorUtils::AddMacroGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromClass=*/nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try GetEntryAndResultNodes first (works for both functions and macros)
|
// Create the variables on the new graph
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> Entry;
|
if (!Vars.SetBackingStore(NewGraph)) return;
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> Exit;
|
if (!Vars.Check()) return;
|
||||||
FBlueprintEditorUtils::GetEntryAndResultNodes(NewGraph, Entry, Exit);
|
if (!Vars.Create()) return;
|
||||||
if ((Entry == nullptr) || (Exit == nullptr))
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("Could not get graph entry and exit nodes.\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!WingFunctionArgs::SetArgs(Entry.Get(), Arguments)) return;
|
|
||||||
if (!WingFunctionArgs::SetArgs(Exit.Get(), ReturnValues)) return;
|
|
||||||
|
|
||||||
UWingServer::Printf(TEXT("Created %s graph: %s\n"), *GraphType, *WingUtils::FormatName(NewGraph));
|
UWingServer::Printf(TEXT("Created %s graph: %s\n"), *GraphType, *WingUtils::FormatName(NewGraph));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingTypes.h"
|
|
||||||
#include "WingVariables.h"
|
|
||||||
#include "Engine/Blueprint.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
|
||||||
#include "BlueprintVariable_Create.generated.h"
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_BlueprintVariable_Create : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Variable declarations"))
|
|
||||||
FString Variables;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Add new member variables to a Blueprint. "
|
|
||||||
"Format: 'type name (flags) = default', one per line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
// Parse the variable declarations.
|
|
||||||
WingVariables Vars(BP);
|
|
||||||
if (!Vars.BlueprintVariables.ParseString(Variables)) return;
|
|
||||||
if (!Vars.Check()) return;
|
|
||||||
if (!Vars.Create()) return;
|
|
||||||
UWingServer::Printf(TEXT("Success.\n"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingBlueprintVar.h"
|
|
||||||
#include "Engine/Blueprint.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
|
||||||
#include "BlueprintVariable_Delete.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_BlueprintVariable_Delete : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Name of the variable to delete"))
|
|
||||||
FString Variable;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Remove a member variable from a Blueprint.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
FWingBlueprintVar Editor(BP, Variable);
|
|
||||||
if (Editor.NotFound()) return;
|
|
||||||
|
|
||||||
FBlueprintEditorUtils::RemoveMemberVariable(BP, Editor.Desc->VarName);
|
|
||||||
|
|
||||||
UWingServer::Printf(TEXT("Removed variable %s from %s\n"),
|
|
||||||
*Variable, *WingUtils::FormatName(BP));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingVariables.h"
|
|
||||||
#include "BlueprintVariable_Dump.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_BlueprintVariable_Dump : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("List all member variables of a Blueprint.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
WingVariables Vars(BP);
|
|
||||||
Vars.Load();
|
|
||||||
Vars.Print(UWingServer::GetPrintBuffer());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingVariables.h"
|
|
||||||
#include "Engine/Blueprint.h"
|
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
|
||||||
#include "BlueprintVariable_Modify.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_BlueprintVariable_Modify : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Variable declarations, one per line. Format: type name (flags) = default"))
|
|
||||||
FString Variables;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Modify existing Blueprint variables. Format: 'type name (flags) = default', one per line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
// Parse the variable declarations.
|
|
||||||
WingVariables Vars(BP);
|
|
||||||
if (!Vars.BlueprintVariables.ParseString(Variables)) return;
|
|
||||||
if (!Vars.Check()) return;
|
|
||||||
if (!Vars.Modify()) return;
|
|
||||||
UWingServer::Printf(TEXT("Success.\n"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingVariables.h"
|
|
||||||
#include "BlueprintVariable_Remove.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_BlueprintVariable_Remove : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Variable names to remove, comma-separated"))
|
|
||||||
FString Variables;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Remove member variables from a Blueprint.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
WingVariables Vars(BP);
|
|
||||||
if (!Vars.BlueprintVariables.ParseNamesString(Variables)) return;
|
|
||||||
if (!Vars.Remove()) return;
|
|
||||||
UWingServer::Printf(TEXT("Success.\n"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
#include "Animation/AnimBlueprint.h"
|
#include "Animation/AnimBlueprint.h"
|
||||||
#include "Animation/Skeleton.h"
|
#include "Animation/Skeleton.h"
|
||||||
#include "WingActorComponent.h"
|
#include "WingActorComponent.h"
|
||||||
#include "WingFunctionArgs.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
#include "AnimationGraph.h"
|
#include "AnimationGraph.h"
|
||||||
#include "AnimationGraphSchema.h"
|
#include "AnimationGraphSchema.h"
|
||||||
@@ -66,25 +65,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
if (!BP->NewVariables.IsEmpty())
|
WingVariables BlueprintVars;
|
||||||
{
|
BlueprintVars.SetBackingStore(BP);
|
||||||
UWingServer::Print(TEXT("\nVariables:\n"));
|
|
||||||
for (const FBPVariableDescription& V : BP->NewVariables)
|
|
||||||
{
|
|
||||||
if (V.VarType.PinCategory == UEdGraphSchema_K2::PC_MCDelegate) continue;
|
|
||||||
UWingServer::Printf(TEXT(" %s %s"),
|
|
||||||
*UWingTypes::TypeToText(V.VarType),
|
|
||||||
*WingUtils::FormatName(V));
|
|
||||||
if (!V.DefaultValue.IsEmpty())
|
|
||||||
UWingServer::Printf(TEXT(" = %s"), *V.DefaultValue);
|
|
||||||
if (!V.Category.IsEmpty() && V.Category.ToString() != TEXT("Default"))
|
|
||||||
UWingServer::Printf(TEXT(" [%s]"), *V.Category.ToString());
|
|
||||||
UWingServer::Print(TEXT("\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variables (new format)
|
|
||||||
WingVariables BlueprintVars(BP);
|
|
||||||
BlueprintVars.Load();
|
BlueprintVars.Load();
|
||||||
BlueprintVars.Print(UWingServer::GetPrintBuffer());
|
BlueprintVars.Print(UWingServer::GetPrintBuffer());
|
||||||
|
|
||||||
@@ -192,38 +174,32 @@ public:
|
|||||||
private:
|
private:
|
||||||
void PrintEventDispatcher(UEdGraph* Graph)
|
void PrintEventDispatcher(UEdGraph* Graph)
|
||||||
{
|
{
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
WingVariables Vars;
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
Vars.SetBackingStore(Graph);
|
||||||
FBlueprintEditorUtils::GetEntryAndResultNodes(Graph, EntryNode, ResultNode);
|
Vars.Load();
|
||||||
|
|
||||||
FString Args;
|
FStringBuilderBase &Out = UWingServer::GetPrintBuffer();
|
||||||
if (EntryNode.IsValid() && WingFunctionArgs::HasArgs(EntryNode.Get()))
|
Out.Appendf(TEXT(" %s("), *WingUtils::FormatName(Graph));
|
||||||
Args = WingFunctionArgs::GetArgs(EntryNode.Get());
|
Vars.InputVariables.PrintCompact(Out);
|
||||||
|
Out.Append(TEXT(")\n"));
|
||||||
UWingServer::Printf(TEXT(" %s(%s)\n"), *WingUtils::FormatName(Graph), *Args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintGraph(UEdGraph* Graph, const TCHAR* Type, UClass* Interface = nullptr)
|
void PrintGraph(UEdGraph* Graph, const TCHAR* Type, UClass* Interface = nullptr)
|
||||||
{
|
{
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
WingVariables Vars;
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
Vars.SetBackingStore(Graph);
|
||||||
FBlueprintEditorUtils::GetEntryAndResultNodes(Graph, EntryNode, ResultNode);
|
Vars.Load();
|
||||||
|
|
||||||
FString InputArgs;
|
FStringBuilderBase &Out = UWingServer::GetPrintBuffer();
|
||||||
FString OutputArgs;
|
Out.Appendf(TEXT(" %s %s"), Type, *WingUtils::FormatName(Graph));
|
||||||
if (EntryNode.IsValid() && WingFunctionArgs::HasArgs(EntryNode.Get()))
|
Out.AppendChar('(');
|
||||||
InputArgs = WingFunctionArgs::GetArgs(EntryNode.Get());
|
Vars.InputVariables.PrintCompact(Out);
|
||||||
if (ResultNode.IsValid() && WingFunctionArgs::HasArgs(ResultNode.Get()))
|
Out.Append(TEXT(") -> ("));
|
||||||
OutputArgs = WingFunctionArgs::GetArgs(ResultNode.Get());
|
Vars.OutputVariables.PrintCompact(Out);
|
||||||
|
Out.AppendChar(')');
|
||||||
UWingServer::Printf(TEXT(" %s %s"), Type, *WingUtils::FormatName(Graph));
|
|
||||||
if (!InputArgs.IsEmpty())
|
|
||||||
UWingServer::Printf(TEXT("(%s)"), *InputArgs);
|
|
||||||
if (!OutputArgs.IsEmpty())
|
|
||||||
UWingServer::Printf(TEXT(" -> (%s)"), *OutputArgs);
|
|
||||||
if (Interface)
|
if (Interface)
|
||||||
UWingServer::Printf(TEXT(" [%s]"), *WingUtils::FormatName(Interface));
|
Out.Appendf(TEXT(" [%s]"), *WingUtils::FormatName(Interface));
|
||||||
UWingServer::Print(TEXT("\n"));
|
Out.AppendChar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingFunctionArgs.h"
|
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraphSchema_K2.h"
|
#include "EdGraphSchema_K2.h"
|
||||||
@@ -28,8 +27,8 @@ public:
|
|||||||
UPROPERTY(meta=(Description="Name of the new event dispatcher"))
|
UPROPERTY(meta=(Description="Name of the new event dispatcher"))
|
||||||
FString Dispatcher;
|
FString Dispatcher;
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Arguments expressed as: int x,float y"))
|
UPROPERTY(meta=(Description="Input Variables, one per line, expressed as: type var = value"))
|
||||||
FString Arguments;
|
FString InputVariables;
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
@@ -45,11 +44,13 @@ public:
|
|||||||
// Check for valid proposed name
|
// Check for valid proposed name
|
||||||
FName InternalID = WingUtils::CheckProposedName(Dispatcher);
|
FName InternalID = WingUtils::CheckProposedName(Dispatcher);
|
||||||
if (InternalID.IsNone()) return;
|
if (InternalID.IsNone()) return;
|
||||||
if (!WingUtils::FindNoneWithInternalID(InternalID, BP->NewVariables, TEXT("Variable"))) return;
|
TSet<FName> Names;
|
||||||
if (!WingUtils::FindNoneWithInternalID(InternalID, WingUtils::AllGraphs(BP), TEXT("Graph"))) return;
|
FBlueprintEditorUtils::GetClassVariableList(BP, Names);
|
||||||
|
if (!WingUtils::FindNoDuplicateName(Names, InternalID, TEXT("variable or component"))) return;
|
||||||
|
|
||||||
// Make sure the argument types are valid.
|
// Parse the arguments.
|
||||||
if (!WingFunctionArgs::CheckArgs(Arguments)) return;
|
WingVariables Vars;
|
||||||
|
if (!Vars.InputVariables.ParseString(InputVariables)) return;
|
||||||
|
|
||||||
// Add the delegate variable
|
// Add the delegate variable
|
||||||
FEdGraphPinType DelegateType;
|
FEdGraphPinType DelegateType;
|
||||||
@@ -78,16 +79,9 @@ public:
|
|||||||
BP->DelegateSignatureGraphs.Add(SigGraph);
|
BP->DelegateSignatureGraphs.Add(SigGraph);
|
||||||
|
|
||||||
// Store the function arguments
|
// Store the function arguments
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
if (!Vars.SetBackingStore(SigGraph)) return;
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
if (!Vars.Check()) return;
|
||||||
FBlueprintEditorUtils::GetEntryAndResultNodes(SigGraph, EntryNode, ResultNode);
|
if (!Vars.Create()) return;
|
||||||
if (!EntryNode.IsValid())
|
|
||||||
{
|
|
||||||
UWingServer::Print(TEXT("ERROR: Entry node not found in delegate signature graph\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!WingFunctionArgs::SetArgs(EntryNode.Get(), Arguments)) return;
|
|
||||||
|
|
||||||
UWingServer::Printf(TEXT("Created event dispatcher %s in %s\n"), *Dispatcher, *WingUtils::FormatName(BP));
|
UWingServer::Printf(TEXT("Created event dispatcher %s in %s\n"), *Dispatcher, *WingUtils::FormatName(BP));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingBlueprintVar.h"
|
|
||||||
#include "Engine/Blueprint.h"
|
|
||||||
#include "WingFunctionArgs.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
|
||||||
#include "EventDispatcher_Dump.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_EventDispatcher_Dump : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Name of the event dispatcher to inspect"))
|
|
||||||
FString Dispatcher;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Show all editable properties of a Blueprint event dispatcher.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
FBPVariableDescription* Var = WingUtils::FindOneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
|
|
||||||
if (!Var) return;
|
|
||||||
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindOneWithExternalID(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
|
|
||||||
if (!SigGraph) return;
|
|
||||||
|
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
|
||||||
FBlueprintEditorUtils::GetEntryAndResultNodes(*SigGraph, EntryNode, ResultNode);
|
|
||||||
if (!EntryNode.IsValid())
|
|
||||||
{
|
|
||||||
UWingServer::Print(TEXT("ERROR: Entry node not found in delegate signature graph\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FString Args = WingFunctionArgs::GetArgs(EntryNode.Get());
|
|
||||||
|
|
||||||
UWingServer::Printf(TEXT("Event dispatcher %s in %s:\n"), *Dispatcher, *WingUtils::FormatName(BP));
|
|
||||||
UWingServer::Printf(TEXT(" Arguments: %s\n"), *Args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingFunctionArgs.h"
|
|
||||||
#include "Engine/Blueprint.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
|
||||||
#include "EventDispatcher_Modify.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_EventDispatcher_Modify : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Name of the event dispatcher to modify"))
|
|
||||||
FString Dispatcher;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="New arguments expressed as: int x,float y"))
|
|
||||||
FString Arguments;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Modify the arguments of an existing Blueprint event dispatcher.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
FBPVariableDescription* Var = WingUtils::FindOneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
|
|
||||||
if (!Var) return;
|
|
||||||
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindOneWithExternalID(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
|
|
||||||
if (!SigGraph) return;
|
|
||||||
|
|
||||||
// Make sure the argument types are valid.
|
|
||||||
if (!WingFunctionArgs::CheckArgs(Arguments)) return;
|
|
||||||
|
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;
|
|
||||||
TWeakObjectPtr<UK2Node_EditablePinBase> ResultNode;
|
|
||||||
FBlueprintEditorUtils::GetEntryAndResultNodes(*SigGraph, EntryNode, ResultNode);
|
|
||||||
if (!EntryNode.IsValid())
|
|
||||||
{
|
|
||||||
UWingServer::Print(TEXT("ERROR: Entry node not found in delegate signature graph\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!WingFunctionArgs::SetArgs(EntryNode.Get(), Arguments)) return;
|
|
||||||
|
|
||||||
UWingServer::Printf(TEXT("Modified event dispatcher %s in %s\n"), *Dispatcher, *WingUtils::FormatName(BP));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingFunctionArgs.h"
|
|
||||||
#include "GraphNode_SetArgs.generated.h"
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_GraphNode_SetArgs : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Path to a graph node (FunctionEntry, FunctionResult, CustomEvent, or Tunnel)"))
|
|
||||||
FString Node;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Parameter list, such as 'int x,float y'"))
|
|
||||||
FString Args;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Also rename the node (which renames a Function or Custom Event)"))
|
|
||||||
FString Rename;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Set the parameter list of a FunctionEntry, FunctionResult, CustomEvent, or Tunnel node.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F;
|
|
||||||
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>();
|
|
||||||
if (!NodeObj) return;
|
|
||||||
|
|
||||||
if (!WingFunctionArgs::HasArgs(NodeObj))
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("ERROR: Node does not support editable args\n"));
|
|
||||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Rename.IsEmpty())
|
|
||||||
{
|
|
||||||
if (!WingUtils::CheckCanRename(NodeObj, Rename)) return;
|
|
||||||
NodeObj->OnRenameNode(Rename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!WingFunctionArgs::SetArgs(NodeObj, Args)) return;
|
|
||||||
|
|
||||||
UWingServer::Printf(TEXT("Args set to: %s\n"), *WingFunctionArgs::GetArgs(NodeObj));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -5,11 +5,7 @@
|
|||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingVariables.h"
|
#include "WingVariables.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Variables_Create.generated.h"
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
|
||||||
#include "K2Node_EditablePinBase.h"
|
|
||||||
#include "K2Node_FunctionEntry.h"
|
|
||||||
#include "GraphVariables_Create.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -17,36 +13,40 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphVariables_Create : public UObject, public IWingHandler
|
class UWing_Variables_Create : public UObject, public IWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(meta=(Description="Path to a function or macro graph (e.g. '/Game/MyBP,graph:MyFunction')"))
|
UPROPERTY(meta=(Description="Path to a blueprint, graph, or custom event node"))
|
||||||
FString Graph;
|
FString Object;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Inputs to the graph"))
|
UPROPERTY(meta=(Optional, Description="Blueprint variables, one per line"))
|
||||||
|
FString BlueprintVariables;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Optional, Description="Input variables, one per line"))
|
||||||
FString InputVariables;
|
FString InputVariables;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Outputs to the graph"))
|
UPROPERTY(meta=(Optional, Description="Output variables, one per line"))
|
||||||
FString OutputVariables;
|
FString OutputVariables;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Locals to the graph"))
|
UPROPERTY(meta=(Optional, Description="Local variables, one per line"))
|
||||||
FString LocalVariables;
|
FString LocalVariables;
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
return TEXT("Add new inputs, outputs, and local variables to a graph. "
|
return TEXT("Add new variables. Format: 'type name (flags) = default', one per line.");
|
||||||
"Format: 'type name (flags) = default', one per line");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
WingFetcher F;
|
WingFetcher F;
|
||||||
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
UObject* Obj = F.Walk(Object).Cast<UObject>();
|
||||||
if (!G) return;
|
if (!Obj) return;
|
||||||
|
|
||||||
WingVariables Vars(G);
|
WingVariables Vars;
|
||||||
|
if (!Vars.SetBackingStore(Obj)) return;
|
||||||
|
if (!Vars.BlueprintVariables.ParseString(BlueprintVariables)) return;
|
||||||
if (!Vars.InputVariables.ParseString(InputVariables)) return;
|
if (!Vars.InputVariables.ParseString(InputVariables)) return;
|
||||||
if (!Vars.OutputVariables.ParseString(OutputVariables)) return;
|
if (!Vars.OutputVariables.ParseString(OutputVariables)) return;
|
||||||
if (!Vars.LocalVariables.ParseString(LocalVariables)) return;
|
if (!Vars.LocalVariables.ParseString(LocalVariables)) return;
|
||||||
@@ -5,8 +5,7 @@
|
|||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingVariables.h"
|
#include "WingVariables.h"
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
#include "Variables_Dump.generated.h"
|
||||||
#include "GraphVariables_Dump.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -14,26 +13,28 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphVariables_Dump : public UObject, public IWingHandler
|
class UWing_Variables_Dump : public UObject, public IWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(meta=(Description="Path to a function graph (e.g. '/Game/MyBP,graph:MyFunction')"))
|
UPROPERTY(meta=(Description="Path to a blueprint, graph, or custom event node"))
|
||||||
FString Graph;
|
FString Object;
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
return TEXT("List all arguments, return values, and local variables of a function graph.");
|
return TEXT("List all variables of a blueprint, function graph,"
|
||||||
|
"macro graph, event dispatcher graph, or custom event node");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
WingFetcher F;
|
WingFetcher F;
|
||||||
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
UObject* Obj = F.Walk(Object).Cast<UObject>();
|
||||||
if (!G) return;
|
if (!Obj) return;
|
||||||
|
|
||||||
WingVariables Vars(G);
|
WingVariables Vars;
|
||||||
|
if (!Vars.SetBackingStore(Obj)) return;
|
||||||
Vars.Load();
|
Vars.Load();
|
||||||
Vars.Print(UWingServer::GetPrintBuffer());
|
Vars.Print(UWingServer::GetPrintBuffer());
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingVariables.h"
|
#include "WingVariables.h"
|
||||||
#include "GraphVariables_Modify.generated.h"
|
#include "Variables_Modify.generated.h"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -13,35 +13,41 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphVariables_Modify : public UObject, public IWingHandler
|
class UWing_Variables_Modify : public UObject, public IWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(meta=(Description="Path to a graph"))
|
UPROPERTY(meta=(Description="Path to a blueprint, graph, or custom event node"))
|
||||||
FString Graph;
|
FString Object;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Inputs to the graph"))
|
UPROPERTY(meta=(Optional, Description="Blueprint variables, one per line"))
|
||||||
|
FString BlueprintVariables;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Optional, Description="Input variables, one per line"))
|
||||||
FString InputVariables;
|
FString InputVariables;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Outputs to the graph"))
|
UPROPERTY(meta=(Optional, Description="Output variables, one per line"))
|
||||||
FString OutputVariables;
|
FString OutputVariables;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Locals to the graph"))
|
UPROPERTY(meta=(Optional, Description="Local variables, one per line"))
|
||||||
FString LocalVariables;
|
FString LocalVariables;
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
return TEXT("Modify existing arguments, return values, and local variables of a graph.");
|
return TEXT("Modify variables of a blueprint, function graph, "
|
||||||
|
"macro graph, event dispatcher graph, or custom event node. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
WingFetcher F;
|
WingFetcher F;
|
||||||
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
UObject* Obj = F.Walk(Object).Cast<UObject>();
|
||||||
if (!G) return;
|
if (!Obj) return;
|
||||||
|
|
||||||
WingVariables Vars(G);
|
WingVariables Vars;
|
||||||
|
if (!Vars.SetBackingStore(Obj)) return;
|
||||||
|
if (!Vars.BlueprintVariables.ParseString(BlueprintVariables)) return;
|
||||||
if (!Vars.InputVariables.ParseString(InputVariables)) return;
|
if (!Vars.InputVariables.ParseString(InputVariables)) return;
|
||||||
if (!Vars.OutputVariables.ParseString(OutputVariables)) return;
|
if (!Vars.OutputVariables.ParseString(OutputVariables)) return;
|
||||||
if (!Vars.LocalVariables.ParseString(LocalVariables)) return;
|
if (!Vars.LocalVariables.ParseString(LocalVariables)) return;
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingVariables.h"
|
#include "WingVariables.h"
|
||||||
#include "GraphVariables_Remove.generated.h"
|
#include "Variables_Remove.generated.h"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -13,13 +13,16 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphVariables_Remove : public UObject, public IWingHandler
|
class UWing_Variables_Remove : public UObject, public IWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(meta=(Description="Path to a function or macro graph"))
|
UPROPERTY(meta=(Description="Path to a blueprint, graph, or custom event node"))
|
||||||
FString Graph;
|
FString Object;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Optional, Description="Blueprint variable names to remove, comma-separated"))
|
||||||
|
FString BlueprintVariables;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Input variable names to remove, comma-separated"))
|
UPROPERTY(meta=(Optional, Description="Input variable names to remove, comma-separated"))
|
||||||
FString InputVariables;
|
FString InputVariables;
|
||||||
@@ -32,16 +35,18 @@ public:
|
|||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
return TEXT("Remove inputs, outputs, and local variables from a graph.");
|
return TEXT("Remove variables from a blueprint, graph, or custom event node.");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
WingFetcher F;
|
WingFetcher F;
|
||||||
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
UObject* Obj = F.Walk(Object).Cast<UObject>();
|
||||||
if (!G) return;
|
if (!Obj) return;
|
||||||
|
|
||||||
WingVariables Vars(G);
|
WingVariables Vars;
|
||||||
|
if (!Vars.SetBackingStore(Obj)) return;
|
||||||
|
if (!Vars.BlueprintVariables.ParseNamesString(BlueprintVariables)) return;
|
||||||
if (!Vars.InputVariables.ParseNamesString(InputVariables)) return;
|
if (!Vars.InputVariables.ParseNamesString(InputVariables)) return;
|
||||||
if (!Vars.OutputVariables.ParseNamesString(OutputVariables)) return;
|
if (!Vars.OutputVariables.ParseNamesString(OutputVariables)) return;
|
||||||
if (!Vars.LocalVariables.ParseNamesString(LocalVariables)) return;
|
if (!Vars.LocalVariables.ParseNamesString(LocalVariables)) return;
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
#include "WingBlueprintVar.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingTypes.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "EdGraphSchema_K2.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
|
||||||
|
|
||||||
FWingBlueprintVar::FWingBlueprintVar(UBlueprint* BP, const FString& VarName)
|
|
||||||
{
|
|
||||||
Desc = WingUtils::FindOneWithExternalID(VarName, BP->NewVariables, TEXT("Variable"));
|
|
||||||
if (!Desc) return;
|
|
||||||
if (Desc->VarType.PinCategory == UEdGraphSchema_K2::PC_MCDelegate)
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("Cannot edit event dispatchers using BlueprintVariable functions.\n"));
|
|
||||||
Desc = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find the default value property on the CDO.
|
|
||||||
if (BP->GeneratedClass)
|
|
||||||
{
|
|
||||||
UObject* CDO = BP->GeneratedClass->GetDefaultObject();
|
|
||||||
FProperty* Prop = BP->GeneratedClass->FindPropertyByName(Desc->VarName);
|
|
||||||
if (CDO && Prop)
|
|
||||||
DefaultValueProp = FWingProperty(Prop, CDO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FWingBlueprintVar::Dump()
|
|
||||||
{
|
|
||||||
LoadFlags();
|
|
||||||
LoadDefault();
|
|
||||||
TArray<FWingProperty> Props = MergedProperties();
|
|
||||||
for (FWingProperty& P : Props)
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT(" %s %s = %s\n"),
|
|
||||||
*UWingTypes::TypeToText(P.Prop),
|
|
||||||
*WingUtils::FormatName(P.Prop),
|
|
||||||
*P.GetText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FWingBlueprintVar::ApplyJson(const FJsonObject* Json)
|
|
||||||
{
|
|
||||||
bool bHasDefault = Json->HasField(TEXT("DefaultValue"));
|
|
||||||
bool bHasType = Json->HasField(TEXT("VarType"));
|
|
||||||
if (bHasDefault && bHasType)
|
|
||||||
{
|
|
||||||
UWingServer::Print(TEXT(
|
|
||||||
"ERROR: Cannot set VarType and DefaultValue in the same call.\n"
|
|
||||||
"Change the type first, then recompile the blueprint,\n"
|
|
||||||
"then set the default.\n"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadFlags();
|
|
||||||
|
|
||||||
TArray<FWingProperty> Props = MergedProperties();
|
|
||||||
if (!FWingProperty::PopulateFromJson(Props, Json, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SaveFlags();
|
|
||||||
if (bHasDefault)
|
|
||||||
return SaveDefault();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FWingBlueprintVar::LoadFlags()
|
|
||||||
{
|
|
||||||
InstanceEditable = !(Desc->PropertyFlags & CPF_DisableEditOnInstance);
|
|
||||||
BlueprintReadOnly = (Desc->PropertyFlags & CPF_BlueprintReadOnly) != 0;
|
|
||||||
ExposeToCinematics = (Desc->PropertyFlags & CPF_Interp) != 0;
|
|
||||||
ExposeOnSpawn = Desc->HasMetaData(FBlueprintMetadata::MD_ExposeOnSpawn);
|
|
||||||
Private = Desc->HasMetaData(FBlueprintMetadata::MD_Private);
|
|
||||||
|
|
||||||
if (Desc->HasMetaData(TEXT("tooltip")))
|
|
||||||
Description = Desc->GetMetaData(TEXT("tooltip"));
|
|
||||||
else
|
|
||||||
Description.Empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FWingBlueprintVar::LoadDefault()
|
|
||||||
{
|
|
||||||
if (DefaultValueProp)
|
|
||||||
DefaultValue = DefaultValueProp.GetText();
|
|
||||||
else
|
|
||||||
DefaultValue.Empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FWingBlueprintVar::SaveFlags()
|
|
||||||
{
|
|
||||||
// CPF flags
|
|
||||||
if (InstanceEditable)
|
|
||||||
Desc->PropertyFlags &= ~CPF_DisableEditOnInstance;
|
|
||||||
else
|
|
||||||
Desc->PropertyFlags |= CPF_DisableEditOnInstance;
|
|
||||||
|
|
||||||
if (BlueprintReadOnly)
|
|
||||||
Desc->PropertyFlags |= CPF_BlueprintReadOnly;
|
|
||||||
else
|
|
||||||
Desc->PropertyFlags &= ~CPF_BlueprintReadOnly;
|
|
||||||
|
|
||||||
if (ExposeToCinematics)
|
|
||||||
Desc->PropertyFlags |= CPF_Interp;
|
|
||||||
else
|
|
||||||
Desc->PropertyFlags &= ~CPF_Interp;
|
|
||||||
|
|
||||||
// Metadata flags
|
|
||||||
if (ExposeOnSpawn)
|
|
||||||
Desc->SetMetaData(FBlueprintMetadata::MD_ExposeOnSpawn, TEXT("true"));
|
|
||||||
else
|
|
||||||
Desc->RemoveMetaData(FBlueprintMetadata::MD_ExposeOnSpawn);
|
|
||||||
|
|
||||||
if (Private)
|
|
||||||
Desc->SetMetaData(FBlueprintMetadata::MD_Private, TEXT("true"));
|
|
||||||
else
|
|
||||||
Desc->RemoveMetaData(FBlueprintMetadata::MD_Private);
|
|
||||||
|
|
||||||
// Description/tooltip
|
|
||||||
if (!Description.IsEmpty())
|
|
||||||
Desc->SetMetaData(TEXT("tooltip"), Description);
|
|
||||||
else
|
|
||||||
Desc->RemoveMetaData(TEXT("tooltip"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FWingBlueprintVar::SaveDefault()
|
|
||||||
{
|
|
||||||
if (DefaultValueProp)
|
|
||||||
return DefaultValueProp.SetText(DefaultValue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TArray<FWingProperty> FWingBlueprintVar::MergedProperties()
|
|
||||||
{
|
|
||||||
TArray<FWingProperty> Props = FWingProperty::GetAll(
|
|
||||||
FBPVariableDescription::StaticStruct(), Desc, CPF_Edit);
|
|
||||||
|
|
||||||
FWingProperty::Remove(Props, TEXT("PropertyFlags"));
|
|
||||||
FWingProperty::Remove(Props, TEXT("MetaDataArray"));
|
|
||||||
FWingProperty::Remove(Props, TEXT("VarName"));
|
|
||||||
FWingProperty::Remove(Props, TEXT("VarGuid"));
|
|
||||||
FWingProperty::Remove(Props, TEXT("DefaultValue"));
|
|
||||||
|
|
||||||
Props.Append(FWingProperty::GetAll(
|
|
||||||
FWingBlueprintVar::StaticStruct(), this, (EPropertyFlags)0));
|
|
||||||
|
|
||||||
// Remove DefaultValue if we don't have a CDO property to back it.
|
|
||||||
if (!DefaultValueProp)
|
|
||||||
FWingProperty::Remove(Props, TEXT("DefaultValue"));
|
|
||||||
|
|
||||||
return Props;
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#include "WingFunctionArgs.h"
|
|
||||||
#include "K2Node_EditablePinBase.h"
|
|
||||||
#include "K2Node_FunctionResult.h"
|
|
||||||
#include "K2Node_Tunnel.h"
|
|
||||||
#include "WingTypes.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
|
||||||
|
|
||||||
bool WingFunctionArgs::HasArgs(UEdGraphNode* Node)
|
|
||||||
{
|
|
||||||
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
|
|
||||||
if (!Editable) return false;
|
|
||||||
return Editable->IsEditable();
|
|
||||||
}
|
|
||||||
|
|
||||||
FString WingFunctionArgs::GetArgs(UEdGraphNode* Node)
|
|
||||||
{
|
|
||||||
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
|
|
||||||
if (!Editable) return FString();
|
|
||||||
|
|
||||||
TStringBuilder<256> SB;
|
|
||||||
for (const TSharedPtr<FUserPinInfo>& Pin : Editable->UserDefinedPins)
|
|
||||||
{
|
|
||||||
if (SB.Len() > 0) SB << TEXT(",");
|
|
||||||
SB << UWingTypes::TypeToText(Pin->PinType) << TEXT(" ") << WingUtils::FormatName(*Pin);
|
|
||||||
}
|
|
||||||
return FString(SB);
|
|
||||||
}
|
|
||||||
|
|
||||||
EEdGraphPinDirection WingFunctionArgs::GetPinDirection(UK2Node_EditablePinBase* Node)
|
|
||||||
{
|
|
||||||
// FunctionResult takes inputs; Tunnel depends on its flags; everything else outputs.
|
|
||||||
if (Node->IsA<UK2Node_FunctionResult>())
|
|
||||||
return EGPD_Input;
|
|
||||||
if (UK2Node_Tunnel* Tunnel = Cast<UK2Node_Tunnel>(Node))
|
|
||||||
return Tunnel->bCanHaveInputs ? EGPD_Input : EGPD_Output;
|
|
||||||
return EGPD_Output;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WingFunctionArgs::ParseArgs(const FString& Args, TArray<FParsedArg>& OutArgs)
|
|
||||||
{
|
|
||||||
FString Trimmed = Args.TrimStartAndEnd();
|
|
||||||
if (Trimmed.IsEmpty()) return true;
|
|
||||||
|
|
||||||
TArray<FString> Parts;
|
|
||||||
Trimmed.ParseIntoArray(Parts, TEXT(","));
|
|
||||||
|
|
||||||
for (const FString& Part : Parts)
|
|
||||||
{
|
|
||||||
FString Token = Part.TrimStartAndEnd();
|
|
||||||
if (Token.IsEmpty()) continue;
|
|
||||||
|
|
||||||
// Split "type name"
|
|
||||||
FString TypeStr, NameStr;
|
|
||||||
if (!Token.Split(TEXT(" "), &TypeStr, &NameStr))
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("ERROR: Malformed parameter list near '%s'\n"), *Token);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeStr.TrimStartAndEndInline();
|
|
||||||
NameStr.TrimStartAndEndInline();
|
|
||||||
|
|
||||||
if (TypeStr.IsEmpty() || NameStr.IsEmpty())
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("ERROR: Malformed parameter list near '%s'\n"), *Token);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FParsedArg Arg;
|
|
||||||
UWingTypes::Requirements Req;
|
|
||||||
Req.BlueprintType = true;
|
|
||||||
Req.Blueprintable = false;
|
|
||||||
Req.AllowContainer = true;
|
|
||||||
if (!UWingTypes::TextToType(TypeStr, Arg.PinType, Req)) return false;
|
|
||||||
Arg.PinName = FName(*NameStr);
|
|
||||||
OutArgs.Add(MoveTemp(Arg));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WingFunctionArgs::SetArgs(UEdGraphNode* Node, const FString& Args)
|
|
||||||
{
|
|
||||||
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
|
|
||||||
if (!Editable || !Editable->IsEditable())
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("ERROR: Node does not contain an editable parameter list\n"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the args string.
|
|
||||||
TArray<FParsedArg> NewArgs;
|
|
||||||
if (!ParseArgs(Args, NewArgs))
|
|
||||||
{
|
|
||||||
UWingServer::SuggestManual(WingManual::Section::ParameterLists);
|
|
||||||
UWingServer::SuggestManual(WingManual::Section::Types);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EEdGraphPinDirection Direction = GetPinDirection(Editable);
|
|
||||||
|
|
||||||
// Replace the UserDefinedPins array directly.
|
|
||||||
Editable->UserDefinedPins.Empty();
|
|
||||||
for (const FParsedArg& Arg : NewArgs)
|
|
||||||
{
|
|
||||||
TSharedPtr<FUserPinInfo> PinInfo = MakeShareable(new FUserPinInfo());
|
|
||||||
PinInfo->PinName = Arg.PinName;
|
|
||||||
PinInfo->PinType = Arg.PinType;
|
|
||||||
PinInfo->DesiredPinDirection = Direction;
|
|
||||||
Editable->UserDefinedPins.Add(PinInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReconstructNode rebuilds real pins from UserDefinedPins
|
|
||||||
// and rewires old connections by matching pin names.
|
|
||||||
Editable->ReconstructNode();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WingFunctionArgs::CheckArgs(const FString &Args)
|
|
||||||
{
|
|
||||||
TArray<FParsedArg> NewArgs;
|
|
||||||
if (!ParseArgs(Args, NewArgs))
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("ERROR: Invalid parameter list: %s\n"), *Args);
|
|
||||||
UWingServer::SuggestManual(WingManual::Section::ParameterLists);
|
|
||||||
UWingServer::SuggestManual(WingManual::Section::Types);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
#include "EdGraphNode_Comment.h"
|
#include "EdGraphNode_Comment.h"
|
||||||
#include "K2Node_CallFunction.h"
|
#include "K2Node_CallFunction.h"
|
||||||
#include "K2Node_FunctionEntry.h"
|
#include "K2Node_FunctionEntry.h"
|
||||||
#include "WingFunctionArgs.h"
|
|
||||||
#include "WingVariables.h"
|
#include "WingVariables.h"
|
||||||
#include "MaterialGraph/MaterialGraphNode.h"
|
#include "MaterialGraph/MaterialGraphNode.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
@@ -205,10 +204,6 @@ void WingGraphExport::EmitNode(UEdGraphNode* Node)
|
|||||||
|
|
||||||
Output.Appendf(TEXT("\nnode %s: %s\n"), *WingUtils::FormatName(Node), *WingUtils::FormatNodeTitle(Node));
|
Output.Appendf(TEXT("\nnode %s: %s\n"), *WingUtils::FormatName(Node), *WingUtils::FormatNodeTitle(Node));
|
||||||
|
|
||||||
// Emit function args (if applicable).
|
|
||||||
if (WingFunctionArgs::HasArgs(Node))
|
|
||||||
Output.Appendf(TEXT(" args %s\n"), *WingFunctionArgs::GetArgs(Node));
|
|
||||||
|
|
||||||
// Emit material expression properties (if applicable).
|
// Emit material expression properties (if applicable).
|
||||||
EmitMaterialProperties(Node, Output, true);
|
EmitMaterialProperties(Node, Output, true);
|
||||||
|
|
||||||
@@ -289,7 +284,8 @@ void WingGraphExport::EmitMaterialProperties(UEdGraphNode* Node, FStringBuilderB
|
|||||||
|
|
||||||
void WingGraphExport::EmitLocalVariables()
|
void WingGraphExport::EmitLocalVariables()
|
||||||
{
|
{
|
||||||
WingVariables Vars(Graph);
|
WingVariables Vars;
|
||||||
|
Vars.SetBackingStore(Graph);
|
||||||
Vars.Load();
|
Vars.Load();
|
||||||
Vars.Print(Output);
|
Vars.Print(Output);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "EdGraphSchema_K2.h"
|
#include "EdGraphSchema_K2.h"
|
||||||
#include "K2Node_FunctionEntry.h"
|
#include "K2Node_FunctionEntry.h"
|
||||||
#include "K2Node_FunctionResult.h"
|
#include "K2Node_FunctionResult.h"
|
||||||
|
#include "K2Node_CustomEvent.h"
|
||||||
#include "K2Node_Tunnel.h"
|
#include "K2Node_Tunnel.h"
|
||||||
#include "K2Node_EditablePinBase.h"
|
#include "K2Node_EditablePinBase.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
@@ -59,6 +60,17 @@ void WingVariableList::Print(FStringBuilderBase &Out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WingVariableList::PrintCompact(FStringBuilderBase &Out)
|
||||||
|
{
|
||||||
|
bool First = true;
|
||||||
|
for (const Var& V : Variables)
|
||||||
|
{
|
||||||
|
if (!First) Out << TEXT(",");
|
||||||
|
First = false;
|
||||||
|
Out << UWingTypes::TypeToText(V.Type) << TEXT(" ") << WingUtils::ExternalizeID(V.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WingVariableList::ClearLinks()
|
void WingVariableList::ClearLinks()
|
||||||
{
|
{
|
||||||
for (Var &V : Variables)
|
for (Var &V : Variables)
|
||||||
@@ -241,6 +253,8 @@ void WingVariables::Load()
|
|||||||
Empty();
|
Empty();
|
||||||
if (Blueprint != nullptr) return LoadBlueprint();
|
if (Blueprint != nullptr) return LoadBlueprint();
|
||||||
if (Graph != nullptr) return LoadGraph();
|
if (Graph != nullptr) return LoadGraph();
|
||||||
|
if (CustomEvent != nullptr) return LoadCustomEvent();
|
||||||
|
ErrorNoBackingStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingVariables::LoadBlueprint()
|
void WingVariables::LoadBlueprint()
|
||||||
@@ -337,12 +351,17 @@ void WingVariables::LoadEditablePinBase(UK2Node_EditablePinBase* Node, WingVaria
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WingVariables::LoadCustomEvent()
|
||||||
|
{
|
||||||
|
LoadEditablePinBase(CustomEvent, InputVariables);
|
||||||
|
}
|
||||||
|
|
||||||
bool WingVariables::Check()
|
bool WingVariables::Check()
|
||||||
{
|
{
|
||||||
if (Blueprint) return CheckBlueprint();
|
if (Blueprint) return CheckBlueprint();
|
||||||
if (Graph) return CheckGraph();
|
if (Graph) return CheckGraph();
|
||||||
check(false);
|
if (CustomEvent) return CheckCustomEvent();
|
||||||
return false;
|
return ErrorNoBackingStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingVariables::CheckBlueprint()
|
bool WingVariables::CheckBlueprint()
|
||||||
@@ -363,7 +382,7 @@ bool WingVariables::CheckGraph()
|
|||||||
bool AllowOutput = (T == EGraphType::GT_Function) || (T == EGraphType::GT_Macro);
|
bool AllowOutput = (T == EGraphType::GT_Function) || (T == EGraphType::GT_Macro);
|
||||||
if ((!AllowLocal) && (!AllowInput) && (!AllowOutput))
|
if ((!AllowLocal) && (!AllowInput) && (!AllowOutput))
|
||||||
{
|
{
|
||||||
UWingServer::Printf(TEXT("This graph has no editable variables."));
|
UWingServer::Printf(TEXT("This graph type has no variables."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,12 +394,22 @@ bool WingVariables::CheckGraph()
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WingVariables::CheckCustomEvent()
|
||||||
|
{
|
||||||
|
bool OK = true;
|
||||||
|
if (!BlueprintVariables.CheckSanity(Flags_None, false)) OK = false;
|
||||||
|
if (!LocalVariables.CheckSanity(Flags_None, false)) OK = false;
|
||||||
|
if (!InputVariables.CheckSanity(Flags_None, true)) OK = false;
|
||||||
|
if (!OutputVariables.CheckSanity(Flags_None, false)) OK = false;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
bool WingVariables::Modify()
|
bool WingVariables::Modify()
|
||||||
{
|
{
|
||||||
if (Blueprint) return ModifyBlueprint();
|
if (Blueprint) return ModifyBlueprint();
|
||||||
if (Graph) return ModifyGraph();
|
if (Graph) return ModifyGraph();
|
||||||
check(false);
|
if (CustomEvent) return ModifyCustomEvent();
|
||||||
return false;
|
return ErrorNoBackingStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingVariables::ModifyBlueprint()
|
bool WingVariables::ModifyBlueprint()
|
||||||
@@ -488,28 +517,36 @@ bool WingVariables::ModifyGraph()
|
|||||||
Desc->VarType = V.Type;
|
Desc->VarType = V.Type;
|
||||||
if (V.DefaultSpecified) Desc->DefaultValue = V.DefaultValue;
|
if (V.DefaultSpecified) Desc->DefaultValue = V.DefaultValue;
|
||||||
}
|
}
|
||||||
for (Var &V : InputVariables.Variables)
|
if (!ModifyEditablePinBase(InputVariables, InputNode)) return false;
|
||||||
{
|
if (!ModifyEditablePinBase(OutputVariables, OutputNode)) return false;
|
||||||
TSharedPtr<FUserPinInfo> *Found =
|
|
||||||
WingUtils::FindOneWithInternalID(V.Name, InputNode->UserDefinedPins, TEXT("input variable"));
|
|
||||||
if (!Found) return false;
|
|
||||||
(*Found)->PinType = V.Type;
|
|
||||||
if (V.DefaultSpecified) (*Found)->PinDefaultValue = V.DefaultValue;
|
|
||||||
}
|
|
||||||
for (Var &V : OutputVariables.Variables)
|
|
||||||
{
|
|
||||||
TSharedPtr<FUserPinInfo> *Found =
|
|
||||||
WingUtils::FindOneWithInternalID(V.Name, OutputNode->UserDefinedPins, TEXT("output variable"));
|
|
||||||
if (!Found) return false;
|
|
||||||
(*Found)->PinType = V.Type;
|
|
||||||
if (V.DefaultSpecified) (*Found)->PinDefaultValue = V.DefaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InputNode) InputNode->ReconstructNode();
|
if (InputNode) InputNode->ReconstructNode();
|
||||||
if (OutputNode) OutputNode->ReconstructNode();
|
if (OutputNode) OutputNode->ReconstructNode();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WingVariables::ModifyCustomEvent()
|
||||||
|
{
|
||||||
|
if (!CheckCustomEvent()) return false;
|
||||||
|
ClearLinks();
|
||||||
|
if (!ModifyEditablePinBase(InputVariables, CustomEvent)) return false;
|
||||||
|
CustomEvent->ReconstructNode();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WingVariables::ModifyEditablePinBase(WingVariableList &List, UK2Node_EditablePinBase *Node)
|
||||||
|
{
|
||||||
|
for (Var &V : List.Variables)
|
||||||
|
{
|
||||||
|
TSharedPtr<FUserPinInfo> *Found =
|
||||||
|
WingUtils::FindOneWithInternalID(V.Name, Node->UserDefinedPins, List.ListName);
|
||||||
|
if (!Found) return false;
|
||||||
|
(*Found)->PinType = V.Type;
|
||||||
|
if (V.DefaultSpecified) (*Found)->PinDefaultValue = V.DefaultValue;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool WingVariables::GetGraphNodes(
|
bool WingVariables::GetGraphNodes(
|
||||||
UK2Node_EditablePinBase *&InputNode,
|
UK2Node_EditablePinBase *&InputNode,
|
||||||
UK2Node_EditablePinBase *&OutputNode,
|
UK2Node_EditablePinBase *&OutputNode,
|
||||||
@@ -554,8 +591,8 @@ bool WingVariables::Create()
|
|||||||
{
|
{
|
||||||
if (Blueprint) return CreateBlueprint();
|
if (Blueprint) return CreateBlueprint();
|
||||||
if (Graph) return CreateGraph();
|
if (Graph) return CreateGraph();
|
||||||
check(false);
|
if (CustomEvent) return CreateCustomEvent();
|
||||||
return false;
|
return ErrorNoBackingStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingVariables::CreateBlueprint()
|
bool WingVariables::CreateBlueprint()
|
||||||
@@ -635,6 +672,25 @@ bool WingVariables::CreateGraph()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WingVariables::CreateCustomEvent()
|
||||||
|
{
|
||||||
|
if (!CheckCustomEvent()) return false;
|
||||||
|
ClearLinks();
|
||||||
|
|
||||||
|
// Check for name collisions against existing pins.
|
||||||
|
TSet<FName> Names;
|
||||||
|
if (!WingUtils::FindNoDuplicateNames(
|
||||||
|
Names, CustomEvent->UserDefinedPins, TEXT("event parameter"))) return false;
|
||||||
|
if (!WingUtils::FindNoDuplicateNames(
|
||||||
|
Names, InputVariables.Variables, TEXT("event parameter"))) return false;
|
||||||
|
|
||||||
|
for (const Var& V : InputVariables.Variables)
|
||||||
|
AddUserPinInfo(V, EGPD_Output, CustomEvent);
|
||||||
|
|
||||||
|
CustomEvent->ReconstructNode();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void WingVariables::AddUserPinInfo(const Var &V, EEdGraphPinDirection Dir, UK2Node_EditablePinBase *Node)
|
void WingVariables::AddUserPinInfo(const Var &V, EEdGraphPinDirection Dir, UK2Node_EditablePinBase *Node)
|
||||||
{
|
{
|
||||||
TSharedPtr<FUserPinInfo> Result = MakeShareable( new FUserPinInfo() );
|
TSharedPtr<FUserPinInfo> Result = MakeShareable( new FUserPinInfo() );
|
||||||
@@ -649,8 +705,8 @@ bool WingVariables::Remove()
|
|||||||
{
|
{
|
||||||
if (Blueprint) return RemoveBlueprint();
|
if (Blueprint) return RemoveBlueprint();
|
||||||
if (Graph) return RemoveGraph();
|
if (Graph) return RemoveGraph();
|
||||||
check(false);
|
if (CustomEvent) return RemoveCustomEvent();
|
||||||
return false;
|
return ErrorNoBackingStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingVariables::RemoveBlueprint()
|
bool WingVariables::RemoveBlueprint()
|
||||||
@@ -715,3 +771,55 @@ bool WingVariables::RemoveGraph()
|
|||||||
if (OutputNode) OutputNode->ReconstructNode();
|
if (OutputNode) OutputNode->ReconstructNode();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WingVariables::RemoveCustomEvent()
|
||||||
|
{
|
||||||
|
// Verify that all named parameters exist before removing anything.
|
||||||
|
for (const Var& V : InputVariables.Variables)
|
||||||
|
{
|
||||||
|
TSharedPtr<FUserPinInfo>* Found =
|
||||||
|
WingUtils::FindOneWithInternalID(V.Name, CustomEvent->UserDefinedPins, TEXT("event parameter"));
|
||||||
|
if (!Found) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Var& V : InputVariables.Variables)
|
||||||
|
CustomEvent->RemoveUserDefinedPinByName(V.Name);
|
||||||
|
|
||||||
|
CustomEvent->ReconstructNode();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WingVariables::SetBackingStore(UObject *Obj)
|
||||||
|
{
|
||||||
|
Blueprint = nullptr;
|
||||||
|
Graph = nullptr;
|
||||||
|
CustomEvent = nullptr;
|
||||||
|
if (UBlueprint *BP = Cast<UBlueprint>(Obj))
|
||||||
|
{
|
||||||
|
Blueprint = BP;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (UEdGraph *G = Cast<UEdGraph>(Obj))
|
||||||
|
{
|
||||||
|
Graph = G;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (UK2Node_CustomEvent *E = Cast<UK2Node_CustomEvent>(Obj))
|
||||||
|
{
|
||||||
|
CustomEvent = E;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
UWingServer::Printf(TEXT(
|
||||||
|
"ERROR: The variable editor can only edit blueprints, "
|
||||||
|
"graphs, and custom event nodes. Passed in: %s"),
|
||||||
|
*WingUtils::FormatName(Obj->GetClass()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WingVariables::ErrorNoBackingStore()
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT(
|
||||||
|
"ERROR: The variable editor was not successfully "
|
||||||
|
"set up with an object to edit."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingProperty.h"
|
|
||||||
#include "Engine/Blueprint.h"
|
|
||||||
#include "WingBlueprintVar.generated.h"
|
|
||||||
|
|
||||||
// Editor-friendly view of a blueprint variable's properties.
|
|
||||||
// Wraps an FBPVariableDescription, exposing commonly-used flags
|
|
||||||
// and metadata as simple UPROPERTYs that the property system can
|
|
||||||
// populate from JSON.
|
|
||||||
USTRUCT()
|
|
||||||
struct FWingBlueprintVar
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
FBPVariableDescription* Desc = nullptr;
|
|
||||||
FWingProperty DefaultValueProp;
|
|
||||||
|
|
||||||
FWingBlueprintVar() = default;
|
|
||||||
FWingBlueprintVar(UBlueprint* BP, const FString& VarName);
|
|
||||||
|
|
||||||
bool NotFound() const { return Desc == nullptr; }
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Default value in Unreal text format"))
|
|
||||||
FString DefaultValue;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Variable description/tooltip"))
|
|
||||||
FString Description;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Allow editing on instances"))
|
|
||||||
bool InstanceEditable = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Read-only in blueprints"))
|
|
||||||
bool BlueprintReadOnly = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Expose as a pin when spawning"))
|
|
||||||
bool ExposeOnSpawn = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Private to this blueprint"))
|
|
||||||
bool Private = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Expose to cinematics/sequencer"))
|
|
||||||
bool ExposeToCinematics = false;
|
|
||||||
|
|
||||||
// Load from Desc, populate from JSON, save back to Desc.
|
|
||||||
bool ApplyJson(const FJsonObject* Json);
|
|
||||||
|
|
||||||
// Print all properties and their current values.
|
|
||||||
void Dump();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void LoadFlags();
|
|
||||||
void LoadDefault();
|
|
||||||
void SaveFlags();
|
|
||||||
bool SaveDefault();
|
|
||||||
TArray<FWingProperty> MergedProperties();
|
|
||||||
};
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "EdGraph/EdGraphPin.h"
|
|
||||||
|
|
||||||
class UEdGraphNode;
|
|
||||||
class UK2Node_EditablePinBase;
|
|
||||||
|
|
||||||
struct WingFunctionArgs
|
|
||||||
{
|
|
||||||
// Returns true if the node is an EditablePinBase subclass that
|
|
||||||
// actually supports user-defined pins (FunctionEntry, FunctionResult,
|
|
||||||
// CustomEvent, or Tunnel).
|
|
||||||
static bool HasArgs(UEdGraphNode* Node);
|
|
||||||
|
|
||||||
// Returns the user-defined pins as a string like "int x,float y".
|
|
||||||
static FString GetArgs(UEdGraphNode* Node);
|
|
||||||
|
|
||||||
// Sets the user-defined pins from a string like "int x,float y".
|
|
||||||
// Returns true on success.
|
|
||||||
static bool SetArgs(UEdGraphNode* Node, const FString& Args);
|
|
||||||
|
|
||||||
// Returns true if the arguments are valid, if not prints error.
|
|
||||||
static bool CheckArgs(const FString &Args);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// A parsed argument: type + name.
|
|
||||||
struct FParsedArg
|
|
||||||
{
|
|
||||||
FEdGraphPinType PinType;
|
|
||||||
FName PinName;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse "int x,float y" into an array of FParsedArg.
|
|
||||||
// Returns false and prints an error on failure.
|
|
||||||
static bool ParseArgs(const FString& Args, TArray<FParsedArg>& OutArgs);
|
|
||||||
|
|
||||||
// Determine the pin direction for user-defined pins on this node.
|
|
||||||
static EEdGraphPinDirection GetPinDirection(UK2Node_EditablePinBase* Node);
|
|
||||||
};
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
|
|
||||||
struct WingTokenizer;
|
struct WingTokenizer;
|
||||||
|
class UK2Node_CustomEvent;
|
||||||
class UK2Node_EditablePinBase;
|
class UK2Node_EditablePinBase;
|
||||||
class UK2Node_FunctionEntry;
|
class UK2Node_FunctionEntry;
|
||||||
struct FUserPinInfo;
|
struct FUserPinInfo;
|
||||||
@@ -55,6 +56,9 @@ public:
|
|||||||
// Print the variables to a string builder.
|
// Print the variables to a string builder.
|
||||||
void Print(FStringBuilderBase &Out);
|
void Print(FStringBuilderBase &Out);
|
||||||
|
|
||||||
|
// Print compact: "type name,type name,..."
|
||||||
|
void PrintCompact(FStringBuilderBase &Out);
|
||||||
|
|
||||||
// Clear the BPVar and Pin fields.
|
// Clear the BPVar and Pin fields.
|
||||||
void ClearLinks();
|
void ClearLinks();
|
||||||
|
|
||||||
@@ -77,11 +81,13 @@ class WingVariables
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Var = WingVariableList::Var;
|
using Var = WingVariableList::Var;
|
||||||
|
WingVariables() {}
|
||||||
|
|
||||||
// The backing store. Only one of these should be set.
|
// The backing store. Only one of these should be set.
|
||||||
|
|
||||||
UBlueprint *Blueprint = nullptr;
|
UBlueprint *Blueprint = nullptr;
|
||||||
UEdGraph *Graph = nullptr;
|
UEdGraph *Graph = nullptr;
|
||||||
|
UK2Node_CustomEvent *CustomEvent = nullptr;
|
||||||
|
|
||||||
// The Workspace. At any given time, these may or may not contain
|
// The Workspace. At any given time, these may or may not contain
|
||||||
// the same data as the backing store.
|
// the same data as the backing store.
|
||||||
@@ -91,10 +97,10 @@ public:
|
|||||||
WingVariableList InputVariables{TEXT("Input Variables")};
|
WingVariableList InputVariables{TEXT("Input Variables")};
|
||||||
WingVariableList OutputVariables{TEXT("Output Variables")};
|
WingVariableList OutputVariables{TEXT("Output Variables")};
|
||||||
|
|
||||||
// Constructors. Just initialize the pointers to the backing store.
|
// Configure the backing store. On failure,
|
||||||
|
// prints a message and returns false.
|
||||||
|
|
||||||
WingVariables(UBlueprint *BP) : Blueprint(BP) {}
|
bool SetBackingStore(UObject *Obj);
|
||||||
WingVariables(UEdGraph *G) : Graph(G) {}
|
|
||||||
|
|
||||||
// Clear the workspace. Doesn't affect the backing store.
|
// Clear the workspace. Doesn't affect the backing store.
|
||||||
|
|
||||||
@@ -155,11 +161,20 @@ private:
|
|||||||
bool RemoveBlueprint();
|
bool RemoveBlueprint();
|
||||||
bool RemoveGraph();
|
bool RemoveGraph();
|
||||||
|
|
||||||
|
void LoadCustomEvent();
|
||||||
|
bool CheckCustomEvent();
|
||||||
|
bool ModifyCustomEvent();
|
||||||
|
bool CreateCustomEvent();
|
||||||
|
bool RemoveCustomEvent();
|
||||||
|
|
||||||
bool GetGraphNodes(
|
bool GetGraphNodes(
|
||||||
UK2Node_EditablePinBase *&InputNode,
|
UK2Node_EditablePinBase *&InputNode,
|
||||||
UK2Node_EditablePinBase *&OutputNode,
|
UK2Node_EditablePinBase *&OutputNode,
|
||||||
UK2Node_FunctionEntry *&LocalNode);
|
UK2Node_FunctionEntry *&LocalNode);
|
||||||
|
|
||||||
|
bool ModifyEditablePinBase(WingVariableList &List, UK2Node_EditablePinBase *Node);
|
||||||
void AddUserPinInfo(const Var &V, EEdGraphPinDirection Dir, UK2Node_EditablePinBase *Node);
|
void AddUserPinInfo(const Var &V, EEdGraphPinDirection Dir, UK2Node_EditablePinBase *Node);
|
||||||
|
|
||||||
|
bool ErrorNoBackingStore();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
"""
|
"""
|
||||||
Human-friendly MCP test client.
|
Human-friendly MCP test client.
|
||||||
|
|
||||||
Usage: ue-wingman.py UserManual
|
Usage: ue-wingman.py <command> [key=value ...]
|
||||||
|
ue-wingman.py (reads JSON with "command" from stdin)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@@ -17,27 +18,28 @@ TIMEOUT = 120
|
|||||||
def main():
|
def main():
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
if not args:
|
if not args:
|
||||||
print("Usage: ue-wingman.py ShowCommands [key=value ...]")
|
# No arguments: read a complete JSON object from stdin.
|
||||||
sys.exit(1)
|
# The JSON must already contain a "command" key.
|
||||||
|
|
||||||
no_args_commands = {"ShowCommands", "UserManual"}
|
|
||||||
if len(args) == 1 and args[0] not in no_args_commands:
|
|
||||||
# No extra arguments: read JSON object from stdin.
|
|
||||||
# Accumulate lines and try to parse after each one.
|
|
||||||
decoder = json.JSONDecoder()
|
decoder = json.JSONDecoder()
|
||||||
raw = ""
|
raw = ""
|
||||||
msg = None
|
msg = None
|
||||||
for line in sys.stdin:
|
for line in sys.stdin:
|
||||||
raw += line
|
raw += line
|
||||||
|
stripped = raw.strip()
|
||||||
try:
|
try:
|
||||||
msg, _ = decoder.raw_decode(raw.lstrip())
|
msg, _ = decoder.raw_decode(stripped)
|
||||||
break
|
break
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError as e:
|
||||||
|
if e.pos < len(stripped):
|
||||||
|
print(f"Malformed JSON: {e.msg}")
|
||||||
|
sys.exit(1)
|
||||||
continue
|
continue
|
||||||
if msg is None:
|
if msg is None:
|
||||||
print("Could not parse a complete JSON object from stdin")
|
print("Could not parse a complete JSON object from stdin")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
msg["command"] = args[0]
|
if "command" not in msg:
|
||||||
|
print("JSON object must contain a \"command\" key")
|
||||||
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
msg = {"command": args[0]}
|
msg = {"command": args[0]}
|
||||||
for arg in args[1:]:
|
for arg in args[1:]:
|
||||||
|
|||||||
Reference in New Issue
Block a user