ComboInput/Source/ComboInputEditor/Private/ComboActionGraphSchema.h
2023-09-27 00:21:59 -04:00

165 lines
5.0 KiB
C++

// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "ComboActionGraphSchema.generated.h"
class FComboActionNodeVisitorCycleChecker
{
public:
/** Check whether a loop in the graph would be caused by linking the passed-in nodes */
bool CheckForLoop(UEdGraphNode *StartNode, UEdGraphNode *EndNode)
{
VisitedNodes.Add(StartNode);
if (!QuiCheckDirectConnections(StartNode, EndNode))
{
return false;
}
return TraverseInputNodesToRoot(EndNode);
}
private:
bool TraverseInputNodesToRoot(UEdGraphNode *Node)
{
VisitedNodes.Add(Node);
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin *MyPin = Node->Pins[PinIndex];
if (MyPin->Direction == EGPD_Output)
{
for (int32 LinkedPinIndex = 0; LinkedPinIndex < MyPin->LinkedTo.Num(); ++LinkedPinIndex)
{
UEdGraphPin *OtherPin = MyPin->LinkedTo[LinkedPinIndex];
if (OtherPin)
{
UEdGraphNode *OtherNode = OtherPin->GetOwningNode();
if (VisitedNodes.Contains(OtherNode))
{
return false;
}
else
{
return TraverseInputNodesToRoot(OtherNode);
}
}
}
}
}
return true;
}
bool QuiCheckDirectConnections(UEdGraphNode *A, UEdGraphNode *B)
{
for (auto Itr : B->Pins)
{
if (A->Pins.Contains(Itr))
{
return false;
}
}
for (auto Itr : A->Pins)
{
if (B->Pins.Contains(Itr))
{
return false;
}
}
return true;
}
TSet<UEdGraphNode *> VisitedNodes;
};
/** Action to add a node to the graph */
USTRUCT()
struct FAssetSchemaAction_ComboActionGraphSchema_NewNode : public FEdGraphSchemaAction
{
GENERATED_BODY();
public:
FAssetSchemaAction_ComboActionGraphSchema_NewNode() : NodeTemplate(nullptr){}
FAssetSchemaAction_ComboActionGraphSchema_NewNode(const FText &InNodeCategory, const FText &InMenuDesc, const FText &InToolTip, const int32 InGrouping)
: FEdGraphSchemaAction(InNodeCategory, InMenuDesc, InToolTip, InGrouping), NodeTemplate(nullptr){}
virtual UEdGraphNode *PerformAction(class UEdGraph *ParentGraph, UEdGraphPin *FromPin, const FVector2D Location, bool bSelectNewNode = true) override;
virtual void AddReferencedObjects(FReferenceCollector &Collector) override;
class UEdComboActionGraphNode *NodeTemplate;
};
USTRUCT()
struct FAssetSchemaAction_ComboActionGraphSchema_NewEdge : public FEdGraphSchemaAction
{
GENERATED_BODY();
public:
FAssetSchemaAction_ComboActionGraphSchema_NewEdge() : NodeTemplate(nullptr)
{}
FAssetSchemaAction_ComboActionGraphSchema_NewEdge(const FText &InNodeCategory, const FText &InMenuDesc, const FText &InToolTip, const int32 InGrouping)
: FEdGraphSchemaAction(InNodeCategory, InMenuDesc, InToolTip, InGrouping), NodeTemplate(nullptr)
{}
virtual UEdGraphNode *PerformAction(class UEdGraph *ParentGraph, UEdGraphPin *FromPin, const FVector2D Location, bool bSelectNewNode = true) override;
virtual void AddReferencedObjects(FReferenceCollector &Collector) override;
class UEdComboActionGraphEdge *NodeTemplate;
};
UCLASS(MinimalAPI)
class UComboActionGraphSchema : public UEdGraphSchema
{
GENERATED_BODY()
public:
void GetBreakLinkToSubMenuActions(class UToolMenu* Menu, class UEdGraphPin* InGraphPin);
virtual EGraphType GetGraphType(const UEdGraph* TestEdGraph) const override { return EGraphType::GT_StateMachine; }
virtual void GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const override;
virtual void GetContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const override;
virtual const FPinConnectionResponse CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const override;
virtual bool CreateAutomaticConversionNodeAndConnections(UEdGraphPin* A, UEdGraphPin* B) const override;
virtual class FConnectionDrawingPolicy* CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, class FSlateWindowElementList& InDrawElements, class UEdGraph* InGraphObj) const override;
virtual FLinearColor GetPinTypeColor(const FEdGraphPinType& PinType) const override;
virtual void BreakNodeLinks(UEdGraphNode& TargetNode) const override;
virtual void BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const override;
virtual void BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const override;
virtual UEdGraphPin* DropPinOnNode(UEdGraphNode* InTargetNode, const FName& InSourcePinName, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection) const override;
virtual bool SupportsDropPinOnNode(UEdGraphNode* InTargetNode, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection, FText& OutErrorMessage) const override;
virtual bool IsCacheVisualizationOutOfDate(int32 InVisualizationCacheID) const override;
virtual int32 GetCurrentVisualizationCacheID() const override;
virtual void ForceVisualizationCacheClear() const override;
virtual void CreateDefaultNodesForGraph(UEdGraph& Graph) const override;
private:
static int32 CurrentCacheRefreshID;
};