ue-mcp 1.3.10-beta.13 → 1.3.10-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tool-counts.json +2 -2
- package/package.json +1 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PCG/PCGHandlers.cpp +13 -14
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/PCGDisconnectNotifyTests.cpp +67 -0
- package/plugin/ue_mcp_bridge/UE_MCP_Bridge.uplugin +1 -1
package/dist/tool-counts.json
CHANGED
package/package.json
CHANGED
|
@@ -786,9 +786,7 @@ TSharedPtr<FJsonValue> FPCGHandlers::ConnectPCGNodes(const TSharedPtr<FJsonObjec
|
|
|
786
786
|
return MCPResult(Result);
|
|
787
787
|
}
|
|
788
788
|
|
|
789
|
-
// #346: per-edge removal
|
|
790
|
-
// finding the matching UPCGEdge on the source pin and clearing it from both
|
|
791
|
-
// pins' Edges arrays, then PostEditChange + save.
|
|
789
|
+
// #346: per-edge removal through UPCGGraph::RemoveEdge, so the graph recompiles.
|
|
792
790
|
TSharedPtr<FJsonValue> FPCGHandlers::DisconnectPCGNodes(const TSharedPtr<FJsonObject>& Params)
|
|
793
791
|
{
|
|
794
792
|
FString AssetPath;
|
|
@@ -842,21 +840,27 @@ TSharedPtr<FJsonValue> FPCGHandlers::DisconnectPCGNodes(const TSharedPtr<FJsonOb
|
|
|
842
840
|
if (!OutPin) continue;
|
|
843
841
|
if (!SourcePinLabel.IsEmpty() && OutPin->Properties.Label != FName(*SourcePinLabel)) continue;
|
|
844
842
|
|
|
845
|
-
//
|
|
846
|
-
TArray<
|
|
843
|
+
// RemoveEdge mutates the Edges array; collect the target labels first.
|
|
844
|
+
TArray<FName> ToRemove;
|
|
847
845
|
for (const TObjectPtr<UPCGEdge>& Edge : OutPin->Edges)
|
|
848
846
|
{
|
|
849
847
|
if (!Edge || !Edge->OutputPin) continue;
|
|
850
848
|
UPCGNode* EdgeDstNode = Edge->OutputPin->Node;
|
|
851
849
|
if (EdgeDstNode != TargetNode) continue;
|
|
852
850
|
if (!TargetPinLabel.IsEmpty() && Edge->OutputPin->Properties.Label != FName(*TargetPinLabel)) continue;
|
|
853
|
-
ToRemove.Add(Edge);
|
|
851
|
+
ToRemove.Add(Edge->OutputPin->Properties.Label);
|
|
854
852
|
}
|
|
855
|
-
for (
|
|
853
|
+
for (const FName& TargetLabel : ToRemove)
|
|
856
854
|
{
|
|
857
|
-
|
|
855
|
+
// The graph's own RemoveEdge notifies a structural change, which recompiles the graph and
|
|
856
|
+
// drops cached results; editing the pins' Edges arrays directly left both stale.
|
|
857
|
+
if (!Graph->RemoveEdge(SourceNode, OutPin->Properties.Label, TargetNode, TargetLabel))
|
|
858
|
+
{
|
|
859
|
+
return MCPError(FString::Printf(TEXT("UPCGGraph::RemoveEdge refused %s.%s -> %s.%s after %d edge(s) were removed"),
|
|
860
|
+
*SourceNodeName, *OutPin->Properties.Label.ToString(), *TargetNodeName, *TargetLabel.ToString(), RemovedCount));
|
|
861
|
+
}
|
|
858
862
|
const FString CutSourcePin = OutPin->Properties.Label.ToString();
|
|
859
|
-
const FString CutTargetPin =
|
|
863
|
+
const FString CutTargetPin = TargetLabel.ToString();
|
|
860
864
|
TSharedPtr<FJsonObject> Cut = MakeShared<FJsonObject>();
|
|
861
865
|
Cut->SetStringField(TEXT("sourcePinLabel"), CutSourcePin);
|
|
862
866
|
Cut->SetStringField(TEXT("targetPinLabel"), CutTargetPin);
|
|
@@ -866,11 +870,6 @@ TSharedPtr<FJsonValue> FPCGHandlers::DisconnectPCGNodes(const TSharedPtr<FJsonOb
|
|
|
866
870
|
FirstRemovedSourcePin = CutSourcePin;
|
|
867
871
|
FirstRemovedTargetPin = CutTargetPin;
|
|
868
872
|
}
|
|
869
|
-
if (Edge->OutputPin)
|
|
870
|
-
{
|
|
871
|
-
Edge->OutputPin->Edges.Remove(Edge);
|
|
872
|
-
}
|
|
873
|
-
OutPin->Edges.Remove(Edge);
|
|
874
873
|
RemovedCount++;
|
|
875
874
|
}
|
|
876
875
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// disconnect_pcg_nodes must tell the graph its structure changed; without that the compiled graph and
|
|
2
|
+
// cached results keep the removed edge until something else invalidates them.
|
|
3
|
+
#if WITH_DEV_AUTOMATION_TESTS
|
|
4
|
+
|
|
5
|
+
#include "HandlerRegistry.h"
|
|
6
|
+
#include "Handlers/PCG/PCGHandlers.h"
|
|
7
|
+
#include "Dom/JsonObject.h"
|
|
8
|
+
#include "Dom/JsonValue.h"
|
|
9
|
+
#include "Elements/PCGAddTag.h"
|
|
10
|
+
#include "Misc/AutomationTest.h"
|
|
11
|
+
#include "Misc/Guid.h"
|
|
12
|
+
#include "PCGEdge.h"
|
|
13
|
+
#include "PCGGraph.h"
|
|
14
|
+
#include "PCGNode.h"
|
|
15
|
+
#include "PCGPin.h"
|
|
16
|
+
#include "UObject/Package.h"
|
|
17
|
+
#include "Tests/MCPScopedTestMount.h"
|
|
18
|
+
|
|
19
|
+
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FMCPPCGDisconnectNotifiesTest,
|
|
20
|
+
"UE.MCP.PCG.Disconnect.NotifiesStructureChange",
|
|
21
|
+
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter)
|
|
22
|
+
|
|
23
|
+
bool FMCPPCGDisconnectNotifiesTest::RunTest(const FString& Parameters)
|
|
24
|
+
{
|
|
25
|
+
FMCPScopedTestMount Mount(
|
|
26
|
+
TEXT("/UEMCPPCGDisconnect_") + FGuid::NewGuid().ToString(EGuidFormats::Digits) + TEXT("/"), TEXT("UEMCPPCGDisconnect"));
|
|
27
|
+
const FString PackageName = Mount.RootPath + TEXT("PG_DisconnectProbe");
|
|
28
|
+
|
|
29
|
+
UPackage* Package = CreatePackage(*PackageName);
|
|
30
|
+
UPCGGraph* Graph = NewObject<UPCGGraph>(Package, TEXT("PG_DisconnectProbe"), RF_Public | RF_Standalone | RF_Transactional);
|
|
31
|
+
if (!TestNotNull(TEXT("PCG graph fixture created"), Graph)) return false;
|
|
32
|
+
|
|
33
|
+
UPCGAddTagSettings* FromSettings = nullptr;
|
|
34
|
+
UPCGAddTagSettings* ToSettings = nullptr;
|
|
35
|
+
UPCGNode* From = Graph->AddNodeOfType(FromSettings);
|
|
36
|
+
UPCGNode* To = Graph->AddNodeOfType(ToSettings);
|
|
37
|
+
if (!TestTrue(TEXT("two nodes added"), From && To)) return false;
|
|
38
|
+
if (!TestNotNull(TEXT("edge added"), Graph->AddEdge(From, PCGPinConstants::DefaultOutputLabel, To, PCGPinConstants::DefaultInputLabel))) return false;
|
|
39
|
+
|
|
40
|
+
int32 StructuralEdgeChanges = 0;
|
|
41
|
+
const FDelegateHandle Handle = Graph->OnGraphChangedDelegate.AddLambda([&StructuralEdgeChanges](UPCGGraphInterface*, EPCGChangeType ChangeType)
|
|
42
|
+
{
|
|
43
|
+
if (EnumHasAnyFlags(ChangeType, EPCGChangeType::Structural | EPCGChangeType::Edge)) ++StructuralEdgeChanges;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
FMCPHandlerRegistry Registry;
|
|
47
|
+
FPCGHandlers::RegisterHandlers(Registry);
|
|
48
|
+
auto Params = MakeShared<FJsonObject>();
|
|
49
|
+
Params->SetStringField(TEXT("assetPath"), PackageName);
|
|
50
|
+
Params->SetStringField(TEXT("sourceNode"), From->GetName());
|
|
51
|
+
Params->SetStringField(TEXT("targetNode"), To->GetName());
|
|
52
|
+
const TSharedPtr<FJsonValue> Value = Registry.ExecuteHandler(TEXT("disconnect_pcg_nodes"), Params);
|
|
53
|
+
Graph->OnGraphChangedDelegate.Remove(Handle);
|
|
54
|
+
|
|
55
|
+
const TSharedPtr<FJsonObject> Result = Value.IsValid() && Value->Type == EJson::Object ? Value->AsObject() : nullptr;
|
|
56
|
+
double Removed = 0;
|
|
57
|
+
if (!TestTrue(TEXT("disconnect_pcg_nodes reports one removed edge"), Result.IsValid() && Result->TryGetNumberField(TEXT("removedEdges"), Removed) && Removed == 1)) return false;
|
|
58
|
+
|
|
59
|
+
const UPCGPin* OutPin = From->GetOutputPin(PCGPinConstants::DefaultOutputLabel);
|
|
60
|
+
const UPCGPin* InPin = To->GetInputPin(PCGPinConstants::DefaultInputLabel);
|
|
61
|
+
TestTrue(TEXT("the source pin has no edges"), OutPin && OutPin->Edges.Num() == 0);
|
|
62
|
+
TestTrue(TEXT("the target pin has no edges"), InPin && InPin->Edges.Num() == 0);
|
|
63
|
+
TestTrue(TEXT("the graph broadcast a structural or edge change"), StructuralEdgeChanges > 0);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#endif
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"FileVersion": 3,
|
|
3
3
|
"Version": 1,
|
|
4
|
-
"VersionName": "1.3.10-beta.
|
|
4
|
+
"VersionName": "1.3.10-beta.14",
|
|
5
5
|
"FriendlyName": "UE MCP Bridge",
|
|
6
6
|
"Description": "C++ WebSocket bridge for UE-MCP, providing 1911+ editor actions over the MCP protocol",
|
|
7
7
|
"Category": "Developer Tools",
|