diff --git a/Plugins/UEWingman/Source/UEWingman/HalfBaked/Blueprint_AddEventDispatcher.h b/Plugins/UEWingman/Source/UEWingman/HalfBaked/Blueprint_AddEventDispatcher.h deleted file mode 100644 index 4d59f9ef..00000000 --- a/Plugins/UEWingman/Source/UEWingman/HalfBaked/Blueprint_AddEventDispatcher.h +++ /dev/null @@ -1,142 +0,0 @@ -#pragma once - -#include "CoreMinimal.h" -#include "WingServer.h" -#include "WingHandler.h" -#include "WingTypes.h" -#include "WingFetcher.h" -#include "WingJson.h" -#include "WingUtils.h" -#include "Engine/Blueprint.h" -#include "EdGraph/EdGraph.h" -#include "EdGraph/EdGraphPin.h" -#include "K2Node_FunctionEntry.h" -#include "K2Node_EditablePinBase.h" -#include "Kismet2/BlueprintEditorUtils.h" -#include "Blueprint_AddEventDispatcher.generated.h" - - -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- - -USTRUCT() -struct FDispatcherParamEntry -{ - GENERATED_BODY() - - UPROPERTY() - FString Name; - - UPROPERTY() - FString Type; -}; - -UCLASS() -class UWing_Blueprint_AddEventDispatcher : public UObject, public IWingHandler -{ - GENERATED_BODY() - -public: - UPROPERTY(meta=(Description="Path to a blueprint, e.g. /Game/Foo/MyBlueprint")) - FString Blueprint; - - UPROPERTY(meta=(Description="Name for the new event dispatcher")) - FString DispatcherName; - - UPROPERTY(meta=(Optional, Description="Array of parameter objects, each with 'name' and 'type' fields")) - FWingJsonArray Parameters; - - virtual FString GetDescription() const override - { - return TEXT("Create a new multicast event dispatcher on a Blueprint, optionally with parameters."); - } - - virtual void Handle() override - { - WingFetcher F; - UBlueprint* BP = F.Walk(Blueprint).Cast(); - if (!BP) return; - - FName DispatcherFName(*DispatcherName); - - // Check for name uniqueness against existing variables - for (const FBPVariableDescription& Var : BP->NewVariables) - { - if (Var.VarName == DispatcherFName) - { - UWingServer::Printf(TEXT("Error: A variable or dispatcher named '%s' already exists.\n"), *DispatcherName); - return; - } - } - - // Check against existing graphs (functions, macros, etc.) - if (!WingUtils::FindExactlyNoneNamed(DispatcherName, WingUtils::AllGraphs(BP), TEXT("Graph"))) - return; - - // Add a member variable with PC_MCDelegate pin type - FEdGraphPinType DelegateType; - DelegateType.PinCategory = UEdGraphSchema_K2::PC_MCDelegate; - if (!FBlueprintEditorUtils::AddMemberVariable(BP, DispatcherFName, DelegateType)) - { - UWingServer::Printf(TEXT("Error: Failed to add delegate variable for '%s'.\n"), *DispatcherName); - return; - } - - // Create the signature graph - const UEdGraphSchema_K2* K2Schema = GetDefault(); - - UEdGraph* SigGraph = FBlueprintEditorUtils::CreateNewGraph(BP, DispatcherFName, - UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass()); - if (!SigGraph) - { - UWingServer::Print(TEXT("Error: Failed to create delegate signature graph.\n")); - return; - } - - K2Schema->CreateDefaultNodesForGraph(*SigGraph); - K2Schema->CreateFunctionGraphTerminators(*SigGraph, static_cast(nullptr)); - K2Schema->AddExtraFunctionFlags(SigGraph, FUNC_BlueprintCallable | FUNC_BlueprintEvent | FUNC_Public); - K2Schema->MarkFunctionEntryAsEditable(SigGraph, true); - - BP->DelegateSignatureGraphs.Add(SigGraph); - - // Add parameters if provided - int32 ParamCount = 0; - - if (Parameters.Array.Num() > 0) - { - UK2Node_EditablePinBase* EntryNode = nullptr; - for (UK2Node_FunctionEntry* FE : WingUtils::AllNodes(SigGraph)) - { - EntryNode = FE; - break; - } - - if (!EntryNode) - { - UWingServer::Print(TEXT("Error: Event dispatcher created but entry node not found — parameters could not be added.\n")); - return; - } - - for (const TSharedPtr& ParamVal : Parameters.Array) - { - FDispatcherParamEntry Entry; - if (!WingJson::PopulateFromJson(FDispatcherParamEntry::StaticStruct(), &Entry, ParamVal)) return; - if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue; - - FEdGraphPinType PinType; - if (!UWingTypes::TextToType(Entry.Type, PinType)) - return; - - EntryNode->CreateUserDefinedPin(FName(*Entry.Name), PinType, EGPD_Output); - ParamCount++; - } - } - - UWingServer::Printf(TEXT("Created event dispatcher '%s'"), *DispatcherName); - if (ParamCount > 0) - UWingServer::Printf(TEXT(" with %d parameter(s)"), ParamCount); - UWingServer::Print(TEXT(".\n")); - } -}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Create.h index cf8a563e..0c3f2f78 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Create.h @@ -27,7 +27,7 @@ public: FString Blueprint; UPROPERTY(meta=(Description="Name of the new event dispatcher")) - FString Name; + FString Dispatcher; UPROPERTY(meta=(Description="Arguments expressed as: int x,float y")) FString Arguments; @@ -44,9 +44,9 @@ public: if (!BP) return; // Check for valid proposed name - if (!WingUtils::FindExactlyNoneNamed(Name, BP->NewVariables, TEXT("Variable"))) return; - if (!WingUtils::FindExactlyNoneNamed(Name, WingUtils::AllGraphs(BP), TEXT("Graph"))) return; - FString InternalName = WingUtils::CheckProposedName(Name); + if (!WingUtils::FindExactlyNoneNamed(Dispatcher, BP->NewVariables, TEXT("Variable"))) return; + if (!WingUtils::FindExactlyNoneNamed(Dispatcher, WingUtils::AllGraphs(BP), TEXT("Graph"))) return; + FString InternalName = WingUtils::CheckProposedName(Dispatcher); if (InternalName.IsEmpty()) return; FName VarFName(InternalName); @@ -58,7 +58,7 @@ public: DelegateType.PinCategory = UEdGraphSchema_K2::PC_MCDelegate; if (!FBlueprintEditorUtils::AddMemberVariable(BP, VarFName, DelegateType)) { - UWingServer::Printf(TEXT("ERROR: Failed to add event dispatcher '%s' to %s\n"), *Name, *WingUtils::FormatName(BP)); + UWingServer::Printf(TEXT("ERROR: Failed to add event dispatcher '%s' to %s\n"), *Dispatcher, *WingUtils::FormatName(BP)); return; } @@ -68,7 +68,7 @@ public: UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass()); if (!SigGraph) { - UWingServer::Printf(TEXT("ERROR: Failed to create signature graph for '%s'\n"), *Name); + UWingServer::Printf(TEXT("ERROR: Failed to create signature graph for '%s'\n"), *Dispatcher); return; } @@ -90,6 +90,6 @@ public: } if (!WingFunctionArgs::SetArgs(EntryNode.Get(), Arguments)) return; - UWingServer::Printf(TEXT("Created event dispatcher %s in %s\n"), *Name, *WingUtils::FormatName(BP)); + UWingServer::Printf(TEXT("Created event dispatcher %s in %s\n"), *Dispatcher, *WingUtils::FormatName(BP)); } }; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Delete.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Delete.h new file mode 100644 index 00000000..41f0d58a --- /dev/null +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Delete.h @@ -0,0 +1,59 @@ +#pragma once + +#include "CoreMinimal.h" +#include "WingServer.h" +#include "WingHandler.h" +#include "WingFetcher.h" +#include "WingUtils.h" +#include "Engine/Blueprint.h" +#include "Kismet2/BlueprintEditorUtils.h" +#include "BlueprintDispatcher_Delete.generated.h" + + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- + +UCLASS() +class UWing_BlueprintDispatcher_Delete : 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 delete")) + FString Dispatcher; + + virtual FString GetDescription() const override + { + return TEXT("Delete an event dispatcher from a Blueprint."); + } + + virtual void Handle() override + { + WingFetcher F; + UBlueprint* BP = F.Walk(Blueprint).Cast(); + if (!BP) return; + + FBPVariableDescription* Var = WingUtils::FindExactlyOneNamed(Dispatcher, BP->NewVariables, TEXT("Dispatcher")); + if (!Var) return; + TObjectPtr* SigGraph = WingUtils::FindExactlyOneNamed(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph")); + if (!SigGraph) return; + + UEdGraph* Graph = *SigGraph; + FName VarFName = Var->VarName; + + BP->Modify(); + Graph->Modify(); + + // Remove the member variable (also destroys referencing nodes) + FBlueprintEditorUtils::RemoveMemberVariable(BP, VarFName); + + // Remove the signature graph + FBlueprintEditorUtils::RemoveGraph(BP, Graph, EGraphRemoveFlags::Recompile); + + UWingServer::Printf(TEXT("Deleted event dispatcher %s from %s\n"), *Dispatcher, *WingUtils::FormatName(BP)); + } +}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Modify.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Modify.h new file mode 100644 index 00000000..080817ba --- /dev/null +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintDispatcher_Modify.h @@ -0,0 +1,64 @@ +#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 "BlueprintDispatcher_Modify.generated.h" + + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- + +UCLASS() +class UWing_BlueprintDispatcher_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(); + if (!BP) return; + + FBPVariableDescription* Var = WingUtils::FindExactlyOneNamed(Dispatcher, BP->NewVariables, TEXT("Dispatcher")); + if (!Var) return; + TObjectPtr* SigGraph = WingUtils::FindExactlyOneNamed(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph")); + if (!SigGraph) return; + + // Make sure the argument types are valid. + if (!WingFunctionArgs::CheckArgs(Arguments)) return; + + TWeakObjectPtr EntryNode; + TWeakObjectPtr 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)); + } +};