More work on the argv conversion of ue-wingman
This commit is contained in:
@@ -1,60 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingBasics.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingProperty.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "Details_SetMany.generated.h"
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_Details_SetMany : public UWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Target object"))
|
|
||||||
FString Object;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Object mapping property names to new values in Unreal text format"))
|
|
||||||
FWingJsonObject Properties;
|
|
||||||
|
|
||||||
virtual void Register() override
|
|
||||||
{
|
|
||||||
UWingServer::AddHandler(this,
|
|
||||||
TEXT("Set one or more editable properties. Values use Unreal text format."));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F(WingOut::Stdout);
|
|
||||||
UObject* Obj = F.Walk(Object).Cast<UObject>();
|
|
||||||
if (!Obj) return;
|
|
||||||
|
|
||||||
if (!Properties.Json || Properties.Json->Values.Num() == 0)
|
|
||||||
{
|
|
||||||
WingOut::Stdout.Print(TEXT("Error: No properties specified\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, true);
|
|
||||||
|
|
||||||
// Validation pass — resolve all properties before modifying anything.
|
|
||||||
for (const auto& Pair : Properties.Json->Values)
|
|
||||||
{
|
|
||||||
FWingProperty* P = WingUtils::FindOneWithExternalID(Pair.Key, Props, TEXT("Property"), WingOut::Stdout);
|
|
||||||
if (!P) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assignment pass — store the values.
|
|
||||||
int SuccessCount = 0;
|
|
||||||
for (const auto& Pair : Properties.Json->Values)
|
|
||||||
{
|
|
||||||
FWingProperty* P = WingUtils::FindOneWithExternalID(Pair.Key, Props, TEXT("Property"), WingOut::Stdout);
|
|
||||||
if (P->SetJson(*Pair.Value, WingOut::Stdout)) SuccessCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
WingOut::Stdout.Printf(TEXT("Set %d/%d properties.\n"), SuccessCount, Properties.Json->Values.Num());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingBasics.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingProperty.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingGraphActions.h"
|
|
||||||
#include "WingGraphExport.h"
|
|
||||||
#include "EdGraph/EdGraph.h"
|
|
||||||
#include "GraphNode_Add.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct FSpawnNodeEntry
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
FString Type;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
int32 PosX = 0;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
int32 PosY = 0;
|
|
||||||
|
|
||||||
FWingGraphAction *Action;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_GraphNode_Add : public UWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
|
||||||
FString Graph;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Array of {Type, posX, posY} objects. Use GraphNode_SearchTypes to find types."))
|
|
||||||
FWingJsonArray Nodes;
|
|
||||||
|
|
||||||
virtual void Register() override
|
|
||||||
{
|
|
||||||
UWingServer::AddHandler(this,
|
|
||||||
TEXT("Create nodes using the editor's action database. "
|
|
||||||
"Use GraphNode_SearchTypes to find types."));
|
|
||||||
}
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F(WingOut::Stdout);
|
|
||||||
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
|
||||||
if (!TargetGraph) return;
|
|
||||||
|
|
||||||
int32 SuccessCount = 0;
|
|
||||||
int32 TotalCount = Nodes.Array.Num();
|
|
||||||
FWingGraphActions GraphActions(TargetGraph);
|
|
||||||
|
|
||||||
// Parse the json array, turning it into an array of spawn node entries.
|
|
||||||
TArray<FSpawnNodeEntry> Entries;
|
|
||||||
FSpawnNodeEntry Entry;
|
|
||||||
TArray<FWingProperty> Props = FWingProperty::GetAll(nullptr, &Entry, FSpawnNodeEntry::StaticStruct(), true);
|
|
||||||
for (const TSharedPtr<FJsonValue>& Elt : Nodes.Array)
|
|
||||||
{
|
|
||||||
if (!FWingProperty::PopulateFromJson(Props, *Elt, false, WingOut::Stdout)) return;
|
|
||||||
TArray<FWingGraphAction*> Results = GraphActions.Search(Entry.Type, 2, true);
|
|
||||||
if (!WingUtils::CheckExactlyOneNamed(Results.Num(), TEXT("node type"), Entry.Type, WingOut::Stdout)) return;
|
|
||||||
Entry.Action = Results[0];
|
|
||||||
Entries.Add(Entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute all.
|
|
||||||
for (const FSpawnNodeEntry &SpawnEntry : Entries)
|
|
||||||
{
|
|
||||||
UEdGraphNode* NewNode = SpawnEntry.Action->Execute(FVector2D(SpawnEntry.PosX, SpawnEntry.PosY));
|
|
||||||
if (NewNode)
|
|
||||||
{
|
|
||||||
WingOut::Stdout.Printf(TEXT("Spawned: %s\n"), *SpawnEntry.Type);
|
|
||||||
WingGraphExport Export(NewNode, false, true);
|
|
||||||
WingOut::Stdout.Print(Export.GetOutput());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WingOut::Stdout.Printf(TEXT("Failed: %s\n\n"), *SpawnEntry.Type);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingBasics.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingProperty.h"
|
|
||||||
#include "EdGraph/EdGraph.h"
|
|
||||||
#include "EdGraph/EdGraphNode.h"
|
|
||||||
#include "GraphNode_SetPositions.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct FMoveNodeEntry
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
FString Node;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
int32 X = 0;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
int32 Y = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_GraphNode_SetPositions : public UWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
|
||||||
FString Graph;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Array of {node, x, y} objects"))
|
|
||||||
FWingJsonArray Nodes;
|
|
||||||
|
|
||||||
virtual void Register() override
|
|
||||||
{
|
|
||||||
UWingServer::AddHandler(this,
|
|
||||||
TEXT("Reposition one or more nodes in a Blueprint graph."));
|
|
||||||
}
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
WingFetcher F(WingOut::Stdout);
|
|
||||||
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
|
||||||
if (!TargetGraph) return;
|
|
||||||
|
|
||||||
int32 SuccessCount = 0;
|
|
||||||
|
|
||||||
FMoveNodeEntry Entry;
|
|
||||||
TArray<FWingProperty> Props = FWingProperty::GetAll(nullptr, &Entry, FMoveNodeEntry::StaticStruct(), true);
|
|
||||||
for (const TSharedPtr<FJsonValue>& Elt : Nodes.Array)
|
|
||||||
{
|
|
||||||
if (!FWingProperty::PopulateFromJson(Props, *Elt, false, WingOut::Stdout)) continue;
|
|
||||||
WingFetcher FN(TargetGraph, WingOut::Stdout);
|
|
||||||
UEdGraphNode* Node = FN.Node(Entry.Node).Cast<UEdGraphNode>();
|
|
||||||
if (!Node) continue;
|
|
||||||
Node->NodePosX = Entry.X;
|
|
||||||
Node->NodePosY = Entry.Y;
|
|
||||||
SuccessCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
WingOut::Stdout.Printf(TEXT("Moved %d/%d nodes.\n"), SuccessCount, Nodes.Array.Num());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingBasics.h"
|
|
||||||
#include "Sequence.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_Sequence : public UWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description=
|
|
||||||
"Array of subcommand JSON objects to execute in order. Each must contain 'command' and its parameters."))
|
|
||||||
FWingJsonArray Subcommands;
|
|
||||||
|
|
||||||
virtual void Register() override
|
|
||||||
{
|
|
||||||
UWingServer::AddHandler(this,
|
|
||||||
TEXT("Execute multiple commands in one request. Each subcommand "
|
|
||||||
"produces its own content block in the response. The big win "
|
|
||||||
"performance-wise is that fewer MCP calls means fewer "
|
|
||||||
"round-trip invocations of the LLM."));
|
|
||||||
}
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
// The actual code that implements Sequence is hardwired into
|
|
||||||
// WingServer. Because of that, this handler is never actually called
|
|
||||||
// under normal conditions. The handler exists for two reasons: to
|
|
||||||
// provide documentation, and also to catch the case where somebody
|
|
||||||
// nests a sequence inside another sequence.
|
|
||||||
WingOut::Stdout.Print(
|
|
||||||
TEXT("ERROR: Sequence inside a Sequence is not allowed.\n"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
63
Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Add.h
Normal file
63
Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Add.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "WingServer.h"
|
||||||
|
#include "WingBasics.h"
|
||||||
|
#include "WingFetcher.h"
|
||||||
|
#include "WingUtils.h"
|
||||||
|
#include "WingGraphActions.h"
|
||||||
|
#include "WingGraphExport.h"
|
||||||
|
#include "EdGraph/EdGraph.h"
|
||||||
|
#include "GraphNode_Add.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UWing_GraphNode_Add : public UWingHandler
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
||||||
|
FString Graph;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Node type, from GraphNode_SearchTypes"))
|
||||||
|
FString Type;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Node X position"))
|
||||||
|
int32 PosX = 0;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Node Y position"))
|
||||||
|
int32 PosY = 0;
|
||||||
|
|
||||||
|
virtual void Register() override
|
||||||
|
{
|
||||||
|
UWingServer::AddHandler(this,
|
||||||
|
TEXT("Create nodes using the editor's action database. "
|
||||||
|
"Use GraphNode_SearchTypes to find types."));
|
||||||
|
}
|
||||||
|
virtual void Handle() override
|
||||||
|
{
|
||||||
|
WingFetcher F(WingOut::Stdout);
|
||||||
|
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
||||||
|
if (!TargetGraph) return;
|
||||||
|
|
||||||
|
FWingGraphActions GraphActions(TargetGraph);
|
||||||
|
TArray<FWingGraphAction*> Results = GraphActions.Search(Type, 2, true);
|
||||||
|
if (!WingUtils::CheckExactlyOneNamed(Results.Num(), TEXT("node type"), Type, WingOut::Stdout)) return;
|
||||||
|
|
||||||
|
UEdGraphNode* NewNode = Results[0]->Execute(FVector2D(PosX, PosY));
|
||||||
|
if (NewNode)
|
||||||
|
{
|
||||||
|
WingOut::Stdout.Printf(TEXT("Spawned: %s\n"), *Type);
|
||||||
|
WingGraphExport Export(NewNode, false, true);
|
||||||
|
WingOut::Stdout.Print(Export.GetOutput());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WingOut::Stdout.Printf(TEXT("Failed: %s\n"), *Type);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -19,15 +19,15 @@ class UWing_GraphNode_SearchTypes : public UWingHandler
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Array of query strings; each may contain * wildcards"))
|
|
||||||
FWingJsonArray Queries;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Maximum number of results per query (default 50)"))
|
|
||||||
int32 MaxResults = 50;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
||||||
FString Graph;
|
FString Graph;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Maximum number of results per query"))
|
||||||
|
int32 MaxResults = 50;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Query strings; each may contain * wildcards"))
|
||||||
|
FWingRestOfArgv Queries;
|
||||||
|
|
||||||
virtual void Register() override
|
virtual void Register() override
|
||||||
{
|
{
|
||||||
UWingServer::AddHandler(this,
|
UWingServer::AddHandler(this,
|
||||||
@@ -40,22 +40,8 @@ public:
|
|||||||
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
||||||
if (!TargetGraph) return;
|
if (!TargetGraph) return;
|
||||||
|
|
||||||
// Validate all entries are strings before running any searches.
|
|
||||||
TArray<FString> QueryStrings;
|
|
||||||
QueryStrings.Reserve(Queries.Array.Num());
|
|
||||||
for (const TSharedPtr<FJsonValue>& QueryVal : Queries.Array)
|
|
||||||
{
|
|
||||||
FString QueryStr;
|
|
||||||
if (!QueryVal->TryGetString(QueryStr))
|
|
||||||
{
|
|
||||||
WingOut::Stdout.Print(TEXT("ERROR: Queries must be an array of strings.\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QueryStrings.Add(QueryStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
FWingGraphActions GraphActions(TargetGraph);
|
FWingGraphActions GraphActions(TargetGraph);
|
||||||
for (const FString& Query : QueryStrings)
|
for (const FString& Query : Queries.Argv)
|
||||||
{
|
{
|
||||||
WingOut::Stdout.Printf(TEXT("\n=== %s ===\n\n"), *Query);
|
WingOut::Stdout.Printf(TEXT("\n=== %s ===\n\n"), *Query);
|
||||||
TArray<FWingGraphAction*> Results = GraphActions.Search(Query, MaxResults, false);
|
TArray<FWingGraphAction*> Results = GraphActions.Search(Query, MaxResults, false);
|
||||||
@@ -4,36 +4,15 @@
|
|||||||
#include "WingBasics.h"
|
#include "WingBasics.h"
|
||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingProperty.h"
|
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "EdGraph/EdGraphPin.h"
|
||||||
#include "EdGraphSchema_K2.h"
|
#include "EdGraphSchema_K2.h"
|
||||||
#include "MaterialGraph/MaterialGraphSchema.h"
|
#include "MaterialGraph/MaterialGraphSchema.h"
|
||||||
#include "GraphNode_SetDefaults.generated.h"
|
#include "GraphNode_SetDefault.generated.h"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct FSetNodeDefaultEntry
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
FString Node;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
FString Name;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
FString Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_SetDefaults : public UWingHandler
|
class UWing_GraphNode_SetDefault : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -41,8 +20,14 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
||||||
FString Graph;
|
FString Graph;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Array of {node, name, value} objects"))
|
UPROPERTY(EditAnywhere, meta=(Description="Target node"))
|
||||||
FWingJsonArray Pins;
|
FString Node;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Pin or property name"))
|
||||||
|
FString Name;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="New default value"))
|
||||||
|
FString Value;
|
||||||
|
|
||||||
virtual void Register() override
|
virtual void Register() override
|
||||||
{
|
{
|
||||||
@@ -53,15 +38,15 @@ public:
|
|||||||
// K2 graphs: set pin default values.
|
// K2 graphs: set pin default values.
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
void HandleK2Entry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj, const UEdGraphSchema_K2* K2Schema)
|
void HandleK2(UEdGraph* GraphObj, const UEdGraphSchema_K2* K2Schema)
|
||||||
{
|
{
|
||||||
WingFetcher F(GraphObj, WingOut::Stdout);
|
WingFetcher F(GraphObj, WingOut::Stdout);
|
||||||
UWingGraphPinRef* PinRef = F.Node(Entry.Node).Pin(Entry.Name).Cast<UWingGraphPinRef>();
|
UWingGraphPinRef* PinRef = F.Node(Node).Pin(Name).Cast<UWingGraphPinRef>();
|
||||||
if (!PinRef) return;
|
if (!PinRef) return;
|
||||||
UEdGraphPin* Pin = WingUtils::CheckGetPin(PinRef->Node, PinRef->PinName, WingOut::Stdout);
|
UEdGraphPin* Pin = WingUtils::CheckGetPin(PinRef->Node, PinRef->PinName, WingOut::Stdout);
|
||||||
if (!Pin) return;
|
if (!Pin) return;
|
||||||
|
|
||||||
UEdGraphNode* Node = Pin->GetOwningNode();
|
UEdGraphNode* FoundNode = Pin->GetOwningNode();
|
||||||
|
|
||||||
if (Pin->Direction != EGPD_Input)
|
if (Pin->Direction != EGPD_Input)
|
||||||
{
|
{
|
||||||
@@ -72,34 +57,34 @@ public:
|
|||||||
FString UseDefaultValue;
|
FString UseDefaultValue;
|
||||||
TObjectPtr<UObject> UseDefaultObject = nullptr;
|
TObjectPtr<UObject> UseDefaultObject = nullptr;
|
||||||
FText UseDefaultText;
|
FText UseDefaultText;
|
||||||
K2Schema->GetPinDefaultValuesFromString(Pin->PinType, Node, Entry.Value, UseDefaultValue, UseDefaultObject, UseDefaultText, false);
|
K2Schema->GetPinDefaultValuesFromString(Pin->PinType, FoundNode, Value, UseDefaultValue, UseDefaultObject, UseDefaultText, false);
|
||||||
FString Error = K2Schema->IsPinDefaultValid(Pin, UseDefaultValue, UseDefaultObject, UseDefaultText);
|
FString Error = K2Schema->IsPinDefaultValid(Pin, UseDefaultValue, UseDefaultObject, UseDefaultText);
|
||||||
if (!Error.IsEmpty())
|
if (!Error.IsEmpty())
|
||||||
{
|
{
|
||||||
WingOut::Stdout.Printf(TEXT("error: %s: %s\n"), *WingUtils::FormatName(Pin), *Error);
|
WingOut::Stdout.Printf(TEXT("error: %s: %s\n"), *WingUtils::FormatName(Pin), *Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UWingServer::AddTouchedObject(Node);
|
UWingServer::AddTouchedObject(FoundNode);
|
||||||
K2Schema->TrySetDefaultValue(*Pin, Entry.Value);
|
K2Schema->TrySetDefaultValue(*Pin, Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Material graphs: set material expression properties.
|
// Material graphs: set material expression properties.
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
void HandleMaterialEntry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj)
|
void HandleMaterial(UEdGraph* GraphObj)
|
||||||
{
|
{
|
||||||
WingFetcher F(GraphObj, WingOut::Stdout);
|
WingFetcher F(GraphObj, WingOut::Stdout);
|
||||||
UEdGraphNode* Node = F.Node(Entry.Node).Cast<UEdGraphNode>();
|
UEdGraphNode* FoundNode = F.Node(Node).Cast<UEdGraphNode>();
|
||||||
if (!Node) return;
|
if (!FoundNode) return;
|
||||||
|
|
||||||
TArray<FWingProperty> All = FWingProperty::GetDetails(Node, true);
|
TArray<FWingProperty> All = FWingProperty::GetDetails(FoundNode, true);
|
||||||
FWingProperty *P = WingUtils::FindOneWithExternalID(Entry.Name, All, TEXT("Property"), WingOut::Stdout);
|
FWingProperty *P = WingUtils::FindOneWithExternalID(Name, All, TEXT("Property"), WingOut::Stdout);
|
||||||
if (!P) return;
|
if (!P) return;
|
||||||
|
|
||||||
UWingServer::AddTouchedObject(Node);
|
UWingServer::AddTouchedObject(FoundNode);
|
||||||
|
|
||||||
if (!P->SetText(Entry.Value, WingOut::Stdout))
|
if (!P->SetText(Value, WingOut::Stdout))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,14 +107,8 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSetNodeDefaultEntry Entry;
|
if (K2Schema) HandleK2(GraphObj, K2Schema);
|
||||||
TArray<FWingProperty> Props = FWingProperty::GetAll(nullptr, &Entry, FSetNodeDefaultEntry::StaticStruct(), true);
|
else if (MGSchema) HandleMaterial(GraphObj);
|
||||||
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
|
|
||||||
{
|
|
||||||
if (!FWingProperty::PopulateFromJson(Props, *PinVal, false, WingOut::Stdout)) continue;
|
|
||||||
if (K2Schema) HandleK2Entry(Entry, GraphObj, K2Schema);
|
|
||||||
else if (MGSchema) HandleMaterialEntry(Entry, GraphObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
WingOut::Stdout.Printf(TEXT("Done.\n"));
|
WingOut::Stdout.Printf(TEXT("Done.\n"));
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "WingServer.h"
|
||||||
|
#include "WingBasics.h"
|
||||||
|
#include "WingFetcher.h"
|
||||||
|
#include "EdGraph/EdGraph.h"
|
||||||
|
#include "EdGraph/EdGraphNode.h"
|
||||||
|
#include "GraphNode_SetPosition.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UWing_GraphNode_SetPosition : public UWingHandler
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
||||||
|
FString Graph;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Target node"))
|
||||||
|
FString Node;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="New X position"))
|
||||||
|
int32 X = 0;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="New Y position"))
|
||||||
|
int32 Y = 0;
|
||||||
|
|
||||||
|
virtual void Register() override
|
||||||
|
{
|
||||||
|
UWingServer::AddHandler(this,
|
||||||
|
TEXT("Reposition a node in a Blueprint graph."));
|
||||||
|
}
|
||||||
|
virtual void Handle() override
|
||||||
|
{
|
||||||
|
WingFetcher F(WingOut::Stdout);
|
||||||
|
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
||||||
|
if (!TargetGraph) return;
|
||||||
|
|
||||||
|
WingFetcher FN(TargetGraph, WingOut::Stdout);
|
||||||
|
UEdGraphNode* FoundNode = FN.Node(Node).Cast<UEdGraphNode>();
|
||||||
|
if (!FoundNode) return;
|
||||||
|
|
||||||
|
FoundNode->NodePosX = X;
|
||||||
|
FoundNode->NodePosY = Y;
|
||||||
|
WingOut::Stdout.Print(TEXT("Moved node.\n"));
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingBasics.h"
|
#include "WingBasics.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingProperty.h"
|
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
#include "EdGraph/EdGraphSchema.h"
|
#include "EdGraph/EdGraphSchema.h"
|
||||||
@@ -12,23 +11,6 @@
|
|||||||
#include "GraphPin_Connect.generated.h"
|
#include "GraphPin_Connect.generated.h"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct FConnectPinsEntry
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
FString SourcePin;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
FString TargetPin;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphPin_Connect : public UWingHandler
|
class UWing_GraphPin_Connect : public UWingHandler
|
||||||
{
|
{
|
||||||
@@ -38,8 +20,8 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
||||||
FString Graph;
|
FString Graph;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Array of {sourcePin, targetPin} objects"))
|
UPROPERTY(EditAnywhere, meta=(Description="Alternating source pin / target pin strings"))
|
||||||
FWingJsonArray Connections;
|
FWingRestOfArgv SourcePin_TargetPin;
|
||||||
|
|
||||||
virtual void Register() override
|
virtual void Register() override
|
||||||
{
|
{
|
||||||
@@ -54,24 +36,27 @@ public:
|
|||||||
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
||||||
if (!G) return;
|
if (!G) return;
|
||||||
|
|
||||||
int32 SuccessCount = 0;
|
if ((SourcePin_TargetPin.Argv.Num() % 2) != 0)
|
||||||
int32 TotalCount = Connections.Array.Num();
|
|
||||||
|
|
||||||
FConnectPinsEntry Entry;
|
|
||||||
TArray<FWingProperty> EntryProps = FWingProperty::GetAll(nullptr, &Entry, FConnectPinsEntry::StaticStruct(), true);
|
|
||||||
for (const TSharedPtr<FJsonValue>& ConnVal : Connections.Array)
|
|
||||||
{
|
{
|
||||||
if (!FWingProperty::PopulateFromJson(EntryProps, *ConnVal, false, WingOut::Stdout))
|
WingOut::Stdout.Print(TEXT("ERROR: SourcePin_TargetPin must contain an even number of arguments.\n"));
|
||||||
continue;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 SuccessCount = 0;
|
||||||
|
int32 TotalCount = SourcePin_TargetPin.Argv.Num() / 2;
|
||||||
|
for (int32 I = 0; I < SourcePin_TargetPin.Argv.Num(); I += 2)
|
||||||
|
{
|
||||||
|
const FString& SourcePinPath = SourcePin_TargetPin.Argv[I];
|
||||||
|
const FString& TargetPinPath = SourcePin_TargetPin.Argv[I + 1];
|
||||||
|
|
||||||
WingFetcher FS(G, WingOut::Stdout);
|
WingFetcher FS(G, WingOut::Stdout);
|
||||||
UWingGraphPinRef* SourcePinRef = FS.Walk(Entry.SourcePin).Cast<UWingGraphPinRef>();
|
UWingGraphPinRef* SourcePinRef = FS.Walk(SourcePinPath).Cast<UWingGraphPinRef>();
|
||||||
if (!SourcePinRef) continue;
|
if (!SourcePinRef) continue;
|
||||||
UEdGraphPin* SourcePin = WingUtils::CheckGetPin(SourcePinRef->Node, SourcePinRef->PinName, WingOut::Stdout);
|
UEdGraphPin* SourcePin = WingUtils::CheckGetPin(SourcePinRef->Node, SourcePinRef->PinName, WingOut::Stdout);
|
||||||
if (!SourcePin) continue;
|
if (!SourcePin) continue;
|
||||||
|
|
||||||
WingFetcher FT(G, WingOut::Stdout);
|
WingFetcher FT(G, WingOut::Stdout);
|
||||||
UWingGraphPinRef* TargetPinRef = FT.Walk(Entry.TargetPin).Cast<UWingGraphPinRef>();
|
UWingGraphPinRef* TargetPinRef = FT.Walk(TargetPinPath).Cast<UWingGraphPinRef>();
|
||||||
if (!TargetPinRef) continue;
|
if (!TargetPinRef) continue;
|
||||||
UEdGraphPin* TargetPin = WingUtils::CheckGetPin(TargetPinRef->Node, TargetPinRef->PinName, WingOut::Stdout);
|
UEdGraphPin* TargetPin = WingUtils::CheckGetPin(TargetPinRef->Node, TargetPinRef->PinName, WingOut::Stdout);
|
||||||
if (!TargetPin) continue;
|
if (!TargetPin) continue;
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingBasics.h"
|
#include "WingBasics.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingProperty.h"
|
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "EdGraph/EdGraphPin.h"
|
||||||
@@ -24,8 +23,8 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
|
||||||
FString Graph;
|
FString Graph;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Array of pin ID strings"))
|
UPROPERTY(EditAnywhere, meta=(Description="Pin ID strings"))
|
||||||
FWingJsonArray Pins;
|
FWingRestOfArgv Pins;
|
||||||
|
|
||||||
virtual void Register() override
|
virtual void Register() override
|
||||||
{
|
{
|
||||||
@@ -43,15 +42,8 @@ public:
|
|||||||
int32 SuccessCount = 0;
|
int32 SuccessCount = 0;
|
||||||
int32 TotalDisconnected = 0;
|
int32 TotalDisconnected = 0;
|
||||||
|
|
||||||
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
|
for (const FString& PinPath : Pins.Argv)
|
||||||
{
|
{
|
||||||
FString PinPath;
|
|
||||||
if (!PinVal->TryGetString(PinPath))
|
|
||||||
{
|
|
||||||
WingOut::Stdout.Print(TEXT("ERROR: Expected a string pin ID.\n"));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
WingFetcher FP(G, WingOut::Stdout);
|
WingFetcher FP(G, WingOut::Stdout);
|
||||||
UWingGraphPinRef* PinRef = FP.Walk(PinPath).Cast<UWingGraphPinRef>();
|
UWingGraphPinRef* PinRef = FP.Walk(PinPath).Cast<UWingGraphPinRef>();
|
||||||
if (!PinRef) continue;
|
if (!PinRef) continue;
|
||||||
@@ -72,6 +64,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
WingOut::Stdout.Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"),
|
WingOut::Stdout.Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"),
|
||||||
SuccessCount, Pins.Array.Num(), TotalDisconnected);
|
SuccessCount, Pins.Argv.Num(), TotalDisconnected);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -17,12 +17,12 @@ class UWing_Widget_SearchTypes : public UWingHandler
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(EditAnywhere, meta=(Description="Array of query strings; each may contain *"))
|
UPROPERTY(EditAnywhere, meta=(Description="Maximum number of results per query"))
|
||||||
FWingJsonArray Queries;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="Maximum number of results per query (default 50)"))
|
|
||||||
int32 MaxResults = 50;
|
int32 MaxResults = 50;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, meta=(Description="Query strings; each may contain *"))
|
||||||
|
FWingRestOfArgv Queries;
|
||||||
|
|
||||||
virtual void Register() override
|
virtual void Register() override
|
||||||
{
|
{
|
||||||
UWingServer::AddHandler(this,
|
UWingServer::AddHandler(this,
|
||||||
@@ -31,22 +31,8 @@ public:
|
|||||||
}
|
}
|
||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
// Validate all entries are strings before running any searches.
|
|
||||||
TArray<FString> QueryStrings;
|
|
||||||
QueryStrings.Reserve(Queries.Array.Num());
|
|
||||||
for (const TSharedPtr<FJsonValue>& QueryVal : Queries.Array)
|
|
||||||
{
|
|
||||||
FString QueryStr;
|
|
||||||
if (!QueryVal->TryGetString(QueryStr))
|
|
||||||
{
|
|
||||||
WingOut::Stdout.Print(TEXT("ERROR: Queries must be an array of strings.\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QueryStrings.Add(QueryStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
WingWidgets Widgets;
|
WingWidgets Widgets;
|
||||||
for (const FString& Query : QueryStrings)
|
for (const FString& Query : Queries.Argv)
|
||||||
{
|
{
|
||||||
WingOut::Stdout.Printf(TEXT("\n=== %s ===\n\n"), *Query);
|
WingOut::Stdout.Printf(TEXT("\n=== %s ===\n\n"), *Query);
|
||||||
TArray<WingWidgets::Type> Results = Widgets.Search(Query, MaxResults, false);
|
TArray<WingWidgets::Type> Results = Widgets.Search(Query, MaxResults, false);
|
||||||
@@ -204,6 +204,18 @@ void UWingManualSections::VariableGettersAndSetters()
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UWingManualSections::BestPerformance()
|
||||||
|
{
|
||||||
|
WingOut::Stdout.Print(TEXT(
|
||||||
|
"\n BEST PERFORMANCE:"
|
||||||
|
"\n"
|
||||||
|
"\n UE Wingman is much faster than the LLM. Therefore, it is"
|
||||||
|
"\n advantageous to batch: chain multiple ue-wingman commands"
|
||||||
|
"\n together using bash semicolon."
|
||||||
|
"\n"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
void UWingManualSections::ImportantCommands()
|
void UWingManualSections::ImportantCommands()
|
||||||
{
|
{
|
||||||
WingOut::Stdout.Print(TEXT(
|
WingOut::Stdout.Print(TEXT(
|
||||||
|
|||||||
@@ -48,4 +48,7 @@ public:
|
|||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
static void VariableGettersAndSetters();
|
static void VariableGettersAndSetters();
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
static void BestPerformance();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user