#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; } } } };