From 5d2377df1d50fcdbae450151874b0f091d39d3b5 Mon Sep 17 00:00:00 2001 From: jyelon Date: Wed, 13 May 2026 22:03:19 -0400 Subject: [PATCH] More work on the argv conversion of ue-wingman --- .../BrokenHandlers/Details_SetMany.h | 60 ------------ .../UEWingman/BrokenHandlers/GraphNode_Add.h | 95 ------------------- .../BrokenHandlers/GraphNode_SetPositions.h | 73 -------------- Plugins/UEWingman/BrokenHandlers/Sequence.h | 41 -------- .../Source/UEWingman/Handlers/GraphNode_Add.h | 63 ++++++++++++ .../Handlers}/GraphNode_SearchTypes.h | 28 ++---- .../Handlers/GraphNode_SetDefault.h} | 71 +++++--------- .../Handlers/GraphNode_SetPosition.h | 49 ++++++++++ .../UEWingman/Handlers}/GraphPin_Connect.h | 45 +++------ .../UEWingman/Handlers}/GraphPin_Disconnect.h | 16 +--- .../UEWingman/Handlers}/Widget_SearchTypes.h | 24 +---- .../Source/UEWingman/Private/WingManual.cpp | 12 +++ .../Source/UEWingman/Public/WingManual.h | 3 + 13 files changed, 183 insertions(+), 397 deletions(-) delete mode 100644 Plugins/UEWingman/BrokenHandlers/Details_SetMany.h delete mode 100644 Plugins/UEWingman/BrokenHandlers/GraphNode_Add.h delete mode 100644 Plugins/UEWingman/BrokenHandlers/GraphNode_SetPositions.h delete mode 100644 Plugins/UEWingman/BrokenHandlers/Sequence.h create mode 100644 Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Add.h rename Plugins/UEWingman/{BrokenHandlers => Source/UEWingman/Handlers}/GraphNode_SearchTypes.h (70%) rename Plugins/UEWingman/{BrokenHandlers/GraphNode_SetDefaults.h => Source/UEWingman/Handlers/GraphNode_SetDefault.h} (56%) create mode 100644 Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPosition.h rename Plugins/UEWingman/{BrokenHandlers => Source/UEWingman/Handlers}/GraphPin_Connect.h (65%) rename Plugins/UEWingman/{BrokenHandlers => Source/UEWingman/Handlers}/GraphPin_Disconnect.h (82%) rename Plugins/UEWingman/{BrokenHandlers => Source/UEWingman/Handlers}/Widget_SearchTypes.h (65%) diff --git a/Plugins/UEWingman/BrokenHandlers/Details_SetMany.h b/Plugins/UEWingman/BrokenHandlers/Details_SetMany.h deleted file mode 100644 index 053b290f..00000000 --- a/Plugins/UEWingman/BrokenHandlers/Details_SetMany.h +++ /dev/null @@ -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(); - if (!Obj) return; - - if (!Properties.Json || Properties.Json->Values.Num() == 0) - { - WingOut::Stdout.Print(TEXT("Error: No properties specified\n")); - return; - } - - TArray 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()); - } -}; diff --git a/Plugins/UEWingman/BrokenHandlers/GraphNode_Add.h b/Plugins/UEWingman/BrokenHandlers/GraphNode_Add.h deleted file mode 100644 index ef451e43..00000000 --- a/Plugins/UEWingman/BrokenHandlers/GraphNode_Add.h +++ /dev/null @@ -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(); - 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 Entries; - FSpawnNodeEntry Entry; - TArray Props = FWingProperty::GetAll(nullptr, &Entry, FSpawnNodeEntry::StaticStruct(), true); - for (const TSharedPtr& Elt : Nodes.Array) - { - if (!FWingProperty::PopulateFromJson(Props, *Elt, false, WingOut::Stdout)) return; - TArray 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; - } - } - } -}; diff --git a/Plugins/UEWingman/BrokenHandlers/GraphNode_SetPositions.h b/Plugins/UEWingman/BrokenHandlers/GraphNode_SetPositions.h deleted file mode 100644 index 8e7daa93..00000000 --- a/Plugins/UEWingman/BrokenHandlers/GraphNode_SetPositions.h +++ /dev/null @@ -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(); - if (!TargetGraph) return; - - int32 SuccessCount = 0; - - FMoveNodeEntry Entry; - TArray Props = FWingProperty::GetAll(nullptr, &Entry, FMoveNodeEntry::StaticStruct(), true); - for (const TSharedPtr& Elt : Nodes.Array) - { - if (!FWingProperty::PopulateFromJson(Props, *Elt, false, WingOut::Stdout)) continue; - WingFetcher FN(TargetGraph, WingOut::Stdout); - UEdGraphNode* Node = FN.Node(Entry.Node).Cast(); - 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()); - } -}; diff --git a/Plugins/UEWingman/BrokenHandlers/Sequence.h b/Plugins/UEWingman/BrokenHandlers/Sequence.h deleted file mode 100644 index 86e4aba4..00000000 --- a/Plugins/UEWingman/BrokenHandlers/Sequence.h +++ /dev/null @@ -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")); - } -}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Add.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Add.h new file mode 100644 index 00000000..3fe06d0c --- /dev/null +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Add.h @@ -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(); + if (!TargetGraph) return; + + FWingGraphActions GraphActions(TargetGraph); + TArray 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); + } +}; diff --git a/Plugins/UEWingman/BrokenHandlers/GraphNode_SearchTypes.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SearchTypes.h similarity index 70% rename from Plugins/UEWingman/BrokenHandlers/GraphNode_SearchTypes.h rename to Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SearchTypes.h index 4a3e915a..7d67b818 100644 --- a/Plugins/UEWingman/BrokenHandlers/GraphNode_SearchTypes.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SearchTypes.h @@ -19,15 +19,15 @@ class UWing_GraphNode_SearchTypes : public UWingHandler GENERATED_BODY() 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")) 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 { UWingServer::AddHandler(this, @@ -40,22 +40,8 @@ public: UEdGraph* TargetGraph = F.Walk(Graph).Cast(); if (!TargetGraph) return; - // Validate all entries are strings before running any searches. - TArray QueryStrings; - QueryStrings.Reserve(Queries.Array.Num()); - for (const TSharedPtr& 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); - for (const FString& Query : QueryStrings) + for (const FString& Query : Queries.Argv) { WingOut::Stdout.Printf(TEXT("\n=== %s ===\n\n"), *Query); TArray Results = GraphActions.Search(Query, MaxResults, false); diff --git a/Plugins/UEWingman/BrokenHandlers/GraphNode_SetDefaults.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetDefault.h similarity index 56% rename from Plugins/UEWingman/BrokenHandlers/GraphNode_SetDefaults.h rename to Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetDefault.h index da6ac140..ee659127 100644 --- a/Plugins/UEWingman/BrokenHandlers/GraphNode_SetDefaults.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetDefault.h @@ -4,36 +4,15 @@ #include "WingBasics.h" #include "WingServer.h" #include "WingFetcher.h" -#include "WingProperty.h" #include "WingUtils.h" #include "EdGraph/EdGraphPin.h" #include "EdGraphSchema_K2.h" #include "MaterialGraph/MaterialGraphSchema.h" -#include "GraphNode_SetDefaults.generated.h" - - -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- - -USTRUCT() -struct FSetNodeDefaultEntry -{ - GENERATED_BODY() - - UPROPERTY() - FString Node; - - UPROPERTY() - FString Name; - - UPROPERTY() - FString Value; -}; +#include "GraphNode_SetDefault.generated.h" UCLASS() -class UWing_GraphNode_SetDefaults : public UWingHandler +class UWing_GraphNode_SetDefault : public UWingHandler { GENERATED_BODY() @@ -41,8 +20,14 @@ public: UPROPERTY(EditAnywhere, meta=(Description="Target graph")) FString Graph; - UPROPERTY(EditAnywhere, meta=(Description="Array of {node, name, value} objects")) - FWingJsonArray Pins; + UPROPERTY(EditAnywhere, meta=(Description="Target node")) + 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 { @@ -53,15 +38,15 @@ public: // 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); - UWingGraphPinRef* PinRef = F.Node(Entry.Node).Pin(Entry.Name).Cast(); + UWingGraphPinRef* PinRef = F.Node(Node).Pin(Name).Cast(); if (!PinRef) return; UEdGraphPin* Pin = WingUtils::CheckGetPin(PinRef->Node, PinRef->PinName, WingOut::Stdout); if (!Pin) return; - UEdGraphNode* Node = Pin->GetOwningNode(); + UEdGraphNode* FoundNode = Pin->GetOwningNode(); if (Pin->Direction != EGPD_Input) { @@ -72,34 +57,34 @@ public: FString UseDefaultValue; TObjectPtr UseDefaultObject = nullptr; 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); if (!Error.IsEmpty()) { WingOut::Stdout.Printf(TEXT("error: %s: %s\n"), *WingUtils::FormatName(Pin), *Error); return; } - UWingServer::AddTouchedObject(Node); - K2Schema->TrySetDefaultValue(*Pin, Entry.Value); + UWingServer::AddTouchedObject(FoundNode); + K2Schema->TrySetDefaultValue(*Pin, Value); } // ----------------------------------------------------------------------- // Material graphs: set material expression properties. // ----------------------------------------------------------------------- - void HandleMaterialEntry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj) + void HandleMaterial(UEdGraph* GraphObj) { WingFetcher F(GraphObj, WingOut::Stdout); - UEdGraphNode* Node = F.Node(Entry.Node).Cast(); - if (!Node) return; + UEdGraphNode* FoundNode = F.Node(Node).Cast(); + if (!FoundNode) return; - TArray All = FWingProperty::GetDetails(Node, true); - FWingProperty *P = WingUtils::FindOneWithExternalID(Entry.Name, All, TEXT("Property"), WingOut::Stdout); + TArray All = FWingProperty::GetDetails(FoundNode, true); + FWingProperty *P = WingUtils::FindOneWithExternalID(Name, All, TEXT("Property"), WingOut::Stdout); if (!P) return; - UWingServer::AddTouchedObject(Node); + UWingServer::AddTouchedObject(FoundNode); - if (!P->SetText(Entry.Value, WingOut::Stdout)) + if (!P->SetText(Value, WingOut::Stdout)) return; } @@ -122,14 +107,8 @@ public: return; } - FSetNodeDefaultEntry Entry; - TArray Props = FWingProperty::GetAll(nullptr, &Entry, FSetNodeDefaultEntry::StaticStruct(), true); - for (const TSharedPtr& PinVal : Pins.Array) - { - if (!FWingProperty::PopulateFromJson(Props, *PinVal, false, WingOut::Stdout)) continue; - if (K2Schema) HandleK2Entry(Entry, GraphObj, K2Schema); - else if (MGSchema) HandleMaterialEntry(Entry, GraphObj); - } + if (K2Schema) HandleK2(GraphObj, K2Schema); + else if (MGSchema) HandleMaterial(GraphObj); WingOut::Stdout.Printf(TEXT("Done.\n")); } diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPosition.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPosition.h new file mode 100644 index 00000000..f7c91712 --- /dev/null +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPosition.h @@ -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(); + if (!TargetGraph) return; + + WingFetcher FN(TargetGraph, WingOut::Stdout); + UEdGraphNode* FoundNode = FN.Node(Node).Cast(); + if (!FoundNode) return; + + FoundNode->NodePosX = X; + FoundNode->NodePosY = Y; + WingOut::Stdout.Print(TEXT("Moved node.\n")); + } +}; diff --git a/Plugins/UEWingman/BrokenHandlers/GraphPin_Connect.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Connect.h similarity index 65% rename from Plugins/UEWingman/BrokenHandlers/GraphPin_Connect.h rename to Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Connect.h index 823e9c74..1fcde977 100644 --- a/Plugins/UEWingman/BrokenHandlers/GraphPin_Connect.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Connect.h @@ -4,7 +4,6 @@ #include "WingServer.h" #include "WingBasics.h" #include "WingFetcher.h" -#include "WingProperty.h" #include "WingUtils.h" #include "EdGraph/EdGraph.h" #include "EdGraph/EdGraphSchema.h" @@ -12,23 +11,6 @@ #include "GraphPin_Connect.generated.h" -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- - -USTRUCT() -struct FConnectPinsEntry -{ - GENERATED_BODY() - - UPROPERTY() - FString SourcePin; - - UPROPERTY() - FString TargetPin; -}; - - UCLASS() class UWing_GraphPin_Connect : public UWingHandler { @@ -38,8 +20,8 @@ public: UPROPERTY(EditAnywhere, meta=(Description="Target graph")) FString Graph; - UPROPERTY(EditAnywhere, meta=(Description="Array of {sourcePin, targetPin} objects")) - FWingJsonArray Connections; + UPROPERTY(EditAnywhere, meta=(Description="Alternating source pin / target pin strings")) + FWingRestOfArgv SourcePin_TargetPin; virtual void Register() override { @@ -54,24 +36,27 @@ public: UEdGraph* G = F.Walk(Graph).Cast(); if (!G) return; - int32 SuccessCount = 0; - int32 TotalCount = Connections.Array.Num(); - - FConnectPinsEntry Entry; - TArray EntryProps = FWingProperty::GetAll(nullptr, &Entry, FConnectPinsEntry::StaticStruct(), true); - for (const TSharedPtr& ConnVal : Connections.Array) + if ((SourcePin_TargetPin.Argv.Num() % 2) != 0) { - if (!FWingProperty::PopulateFromJson(EntryProps, *ConnVal, false, WingOut::Stdout)) - continue; + WingOut::Stdout.Print(TEXT("ERROR: SourcePin_TargetPin must contain an even number of arguments.\n")); + 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); - UWingGraphPinRef* SourcePinRef = FS.Walk(Entry.SourcePin).Cast(); + UWingGraphPinRef* SourcePinRef = FS.Walk(SourcePinPath).Cast(); if (!SourcePinRef) continue; UEdGraphPin* SourcePin = WingUtils::CheckGetPin(SourcePinRef->Node, SourcePinRef->PinName, WingOut::Stdout); if (!SourcePin) continue; WingFetcher FT(G, WingOut::Stdout); - UWingGraphPinRef* TargetPinRef = FT.Walk(Entry.TargetPin).Cast(); + UWingGraphPinRef* TargetPinRef = FT.Walk(TargetPinPath).Cast(); if (!TargetPinRef) continue; UEdGraphPin* TargetPin = WingUtils::CheckGetPin(TargetPinRef->Node, TargetPinRef->PinName, WingOut::Stdout); if (!TargetPin) continue; diff --git a/Plugins/UEWingman/BrokenHandlers/GraphPin_Disconnect.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Disconnect.h similarity index 82% rename from Plugins/UEWingman/BrokenHandlers/GraphPin_Disconnect.h rename to Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Disconnect.h index d630fd8e..b45a8707 100644 --- a/Plugins/UEWingman/BrokenHandlers/GraphPin_Disconnect.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Disconnect.h @@ -4,7 +4,6 @@ #include "WingServer.h" #include "WingBasics.h" #include "WingFetcher.h" -#include "WingProperty.h" #include "WingUtils.h" #include "EdGraph/EdGraph.h" #include "EdGraph/EdGraphPin.h" @@ -24,8 +23,8 @@ public: UPROPERTY(EditAnywhere, meta=(Description="Target graph")) FString Graph; - UPROPERTY(EditAnywhere, meta=(Description="Array of pin ID strings")) - FWingJsonArray Pins; + UPROPERTY(EditAnywhere, meta=(Description="Pin ID strings")) + FWingRestOfArgv Pins; virtual void Register() override { @@ -43,15 +42,8 @@ public: int32 SuccessCount = 0; int32 TotalDisconnected = 0; - for (const TSharedPtr& 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); UWingGraphPinRef* PinRef = FP.Walk(PinPath).Cast(); if (!PinRef) continue; @@ -72,6 +64,6 @@ public: } WingOut::Stdout.Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"), - SuccessCount, Pins.Array.Num(), TotalDisconnected); + SuccessCount, Pins.Argv.Num(), TotalDisconnected); } }; diff --git a/Plugins/UEWingman/BrokenHandlers/Widget_SearchTypes.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_SearchTypes.h similarity index 65% rename from Plugins/UEWingman/BrokenHandlers/Widget_SearchTypes.h rename to Plugins/UEWingman/Source/UEWingman/Handlers/Widget_SearchTypes.h index 082abd2d..230ef5e6 100644 --- a/Plugins/UEWingman/BrokenHandlers/Widget_SearchTypes.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_SearchTypes.h @@ -17,12 +17,12 @@ class UWing_Widget_SearchTypes : public UWingHandler GENERATED_BODY() public: - UPROPERTY(EditAnywhere, meta=(Description="Array of query strings; each may contain *")) - FWingJsonArray Queries; - - UPROPERTY(EditAnywhere, meta=(Optional, Description="Maximum number of results per query (default 50)")) + UPROPERTY(EditAnywhere, meta=(Description="Maximum number of results per query")) int32 MaxResults = 50; + UPROPERTY(EditAnywhere, meta=(Description="Query strings; each may contain *")) + FWingRestOfArgv Queries; + virtual void Register() override { UWingServer::AddHandler(this, @@ -31,22 +31,8 @@ public: } virtual void Handle() override { - // Validate all entries are strings before running any searches. - TArray QueryStrings; - QueryStrings.Reserve(Queries.Array.Num()); - for (const TSharedPtr& 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; - for (const FString& Query : QueryStrings) + for (const FString& Query : Queries.Argv) { WingOut::Stdout.Printf(TEXT("\n=== %s ===\n\n"), *Query); TArray Results = Widgets.Search(Query, MaxResults, false); diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp index 4e1fa225..4e4bf303 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp @@ -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() { WingOut::Stdout.Print(TEXT( diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h b/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h index 70758d5d..757ce179 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h @@ -48,4 +48,7 @@ public: UFUNCTION() static void VariableGettersAndSetters(); + + UFUNCTION() + static void BestPerformance(); };