Split MCP handlers
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssetFinder.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "Engine/World.h"
|
||||
#include "EdGraph/EdGraph.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
#include "EdGraph/EdGraphPin.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
#include "UMCPHandler_DisconnectBlueprintPins.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
USTRUCT()
|
||||
struct FDisconnectPinEntry
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
FString Node;
|
||||
|
||||
UPROPERTY()
|
||||
FString PinName;
|
||||
|
||||
UPROPERTY(meta=(Optional))
|
||||
FString TargetNode;
|
||||
|
||||
UPROPERTY(meta=(Optional))
|
||||
FString TargetPinName;
|
||||
};
|
||||
|
||||
|
||||
UCLASS()
|
||||
class UMCPHandler_DisconnectBlueprintPins : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
||||
FString Blueprint;
|
||||
|
||||
UPROPERTY(meta=(Description="Array of {node, pinName, targetNode?, targetPinName?} objects. If target is omitted, all connections on the pin are broken."))
|
||||
FMCPJsonArray Disconnections;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Disconnect pins in a Blueprint graph. "
|
||||
"Can disconnect a specific link or all links on a pin.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override
|
||||
{
|
||||
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
||||
UBlueprint* BP = Assets.Object();
|
||||
|
||||
TArray<TSharedPtr<FJsonValue>> Results;
|
||||
int32 SuccessCount = 0;
|
||||
int32 TotalDisconnected = 0;
|
||||
|
||||
for (const TSharedPtr<FJsonValue>& DiscVal : Disconnections.Array)
|
||||
{
|
||||
TSharedRef<FJsonObject> EntryResult = MakeShared<FJsonObject>();
|
||||
Results.Add(MakeShared<FJsonValueObject>(EntryResult));
|
||||
|
||||
FDisconnectPinEntry Entry;
|
||||
if (!MCPUtils::PopulateFromJson(FDisconnectPinEntry::StaticStruct(), &Entry, DiscVal, &*EntryResult)) continue;
|
||||
|
||||
UEdGraphNode* Node = MCPUtils::FindNodeByGuid(BP, Entry.Node);
|
||||
if (!Node)
|
||||
{
|
||||
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Node '%s' not found"), *Entry.Node));
|
||||
continue;
|
||||
}
|
||||
|
||||
UEdGraphPin* Pin = Node->FindPin(FName(*Entry.PinName));
|
||||
if (!Pin)
|
||||
{
|
||||
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Pin '%s' not found on node '%s'"), *Entry.PinName, *Entry.Node));
|
||||
continue;
|
||||
}
|
||||
|
||||
int32 DisconnectedCount = 0;
|
||||
|
||||
if (!Entry.TargetNode.IsEmpty() && !Entry.TargetPinName.IsEmpty())
|
||||
{
|
||||
UEdGraphNode* TargetNode = MCPUtils::FindNodeByGuid(BP, Entry.TargetNode);
|
||||
if (!TargetNode)
|
||||
{
|
||||
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Target node '%s' not found"), *Entry.TargetNode));
|
||||
continue;
|
||||
}
|
||||
|
||||
UEdGraphPin* TargetPin = TargetNode->FindPin(FName(*Entry.TargetPinName));
|
||||
if (!TargetPin)
|
||||
{
|
||||
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Target pin '%s' not found on node '%s'"), *Entry.TargetPinName, *Entry.TargetNode));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Pin->LinkedTo.Contains(TargetPin))
|
||||
{
|
||||
EntryResult->SetStringField(TEXT("error"), TEXT("The specified pins are not connected to each other"));
|
||||
continue;
|
||||
}
|
||||
|
||||
Pin->BreakLinkTo(TargetPin);
|
||||
DisconnectedCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisconnectedCount = Pin->LinkedTo.Num();
|
||||
if (DisconnectedCount > 0)
|
||||
{
|
||||
Pin->BreakAllPinLinks(true);
|
||||
}
|
||||
}
|
||||
|
||||
EntryResult->SetNumberField(TEXT("disconnectedCount"), DisconnectedCount);
|
||||
SuccessCount++;
|
||||
TotalDisconnected += DisconnectedCount;
|
||||
}
|
||||
|
||||
if (TotalDisconnected > 0)
|
||||
{
|
||||
FBlueprintEditorUtils::MarkBlueprintAsModified(BP);
|
||||
}
|
||||
|
||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: DisconnectPin — %d/%d succeeded, %d links broken in '%s'"),
|
||||
SuccessCount, Disconnections.Array.Num(), TotalDisconnected, *Blueprint);
|
||||
|
||||
Result->SetNumberField(TEXT("successCount"), SuccessCount);
|
||||
Result->SetNumberField(TEXT("totalCount"), Disconnections.Array.Num());
|
||||
Result->SetNumberField(TEXT("totalDisconnected"), TotalDisconnected);
|
||||
Result->SetArrayField(TEXT("results"), Results);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user