149 lines
4.3 KiB
C++
149 lines
4.3 KiB
C++
#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<UBlueprint>();
|
|
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::AllGraphsNamed(BP, DispatcherName).IsEmpty())
|
|
{
|
|
UWingServer::Printf(TEXT("Error: A graph named '%s' already exists.\n"), *DispatcherName);
|
|
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<UEdGraphSchema_K2>();
|
|
|
|
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<UClass*>(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<UK2Node_FunctionEntry>(SigGraph))
|
|
{
|
|
EntryNode = FE;
|
|
break;
|
|
}
|
|
|
|
if (!EntryNode)
|
|
{
|
|
WingUtils::SaveBlueprintPackage(BP);
|
|
UWingServer::Print(TEXT("Error: Event dispatcher created but entry node not found — parameters could not be added.\n"));
|
|
return;
|
|
}
|
|
|
|
for (const TSharedPtr<FJsonValue>& 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++;
|
|
}
|
|
}
|
|
|
|
WingUtils::SaveBlueprintPackage(BP);
|
|
|
|
UWingServer::Printf(TEXT("Created event dispatcher '%s'"), *DispatcherName);
|
|
if (ParamCount > 0)
|
|
UWingServer::Printf(TEXT(" with %d parameter(s)"), ParamCount);
|
|
UWingServer::Print(TEXT(".\n"));
|
|
}
|
|
};
|