// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Array.h" #include "Containers/Map.h" #include "Containers/UnrealString.h" #include "CoreTypes.h" #include "Math/Color.h" #include "Misc/Optional.h" #include "Templates/Function.h" #include "UObject/NameTypes.h" #include "UObject/UnrealNames.h" #include "VisualGraphEdge.h" #include "VisualGraphElement.h" #include "VisualGraphNode.h" class FVisualGraph; class VISUALGRAPHUTILS_API FVisualGraphSubGraph : public FVisualGraphElement { public: FVisualGraphSubGraph() : FVisualGraphElement() , ParentGraphIndex(INDEX_NONE) {} virtual ~FVisualGraphSubGraph() override {} int32 GetParentGraphIndex() const { return ParentGraphIndex; } const TArray& GetNodes() const { return Nodes; } protected: virtual FString DumpDot(const FVisualGraph* InGraph, int32 InIndendation) const override; int32 ParentGraphIndex; TArray Nodes; friend class FVisualGraph; }; class VISUALGRAPHUTILS_API FVisualGraph : public FVisualGraphElement { public: FVisualGraph() : FVisualGraphElement() {} virtual ~FVisualGraph() override {} FVisualGraph(const FName& InName, const FName& InDisplayName = NAME_None); const TArray& GetNodes() const { return Nodes; } const TArray& GetEdges() const { return Edges; } const TArray& GetSubGraphs() const { return SubGraphs; } int32 AddNode( const FName& InName, TOptional InDisplayName = TOptional(), TOptional InColor = TOptional(), TOptional InShape = TOptional(), TOptional InStyle = TOptional()); int32 AddEdge( int32 InSourceNode, int32 InTargetNode, EVisualGraphEdgeDirection InDirection, const FName& InName = NAME_None, TOptional InDisplayName = TOptional(), TOptional InColor = TOptional(), TOptional InStyle = TOptional()); int32 AddSubGraph( const FName& InName, TOptional InDisplayName = TOptional(), int32 InParentGraphIndex = INDEX_NONE, TOptional InColor = TOptional(), TOptional InStyle = TOptional(), const TArray InNodes = TArray()); int32 FindNode(const FName& InName) const; int32 FindEdge(const FName& InName) const; int32 FindSubGraph(const FName& InName) const; bool AddNodeToSubGraph(int32 InNodeIndex, int32 InSubGraphIndex); bool RemoveNodeFromSubGraph(int32 InNodeIndex); void TransitiveReduction(TFunction KeepEdgeFunction); FORCEINLINE FString DumpDot() const { return DumpDot(this, 0); } protected: virtual FString DumpDot(const FVisualGraph* InGraph, int32 InIndendation) const override; template FORCEINLINE static void RefreshNameMap(const TArray& InElements, TMap& OutMap) { OutMap.Reset(); for(const T& Element: InElements) { OutMap.Add(Element.Name, Element.Index); } } template FORCEINLINE static void RefreshNameMapIfNeeded(const TArray& InElements, TMap& OutMap) { if(OutMap.Num() == InElements.Num()) { return; } RefreshNameMap(InElements, OutMap); } template FORCEINLINE static int32 AddElement(const T& InElement, TArray& OutElements, TMap& OutMap) { const int32 AddedIndex = OutElements.Add(InElement); if(OutElements.IsValidIndex(AddedIndex)) { OutElements[AddedIndex].Index = AddedIndex; OutMap.Add(InElement.Name, AddedIndex); } return AddedIndex; } static bool IsNameAvailable(const FName& InName, const TMap& InMap); static FName GetUniqueName(const FName& InName, const TMap& InMap); TArray Nodes; TArray Edges; TArray SubGraphs; TMap NodeNameMap; TMap EdgeNameMap; TMap SubGraphNameMap; };