GenericGraph icon indicating copy to clipboard operation
GenericGraph copied to clipboard

Infinite loop on Sort Nodes

Open cristiangj opened this issue 3 years ago • 1 comments

If you make a cyclical graph (a parent having a reference to a children and this children to their parent) you have a infinite loop on UEdGraph_GenericGraph::SortNodes after call UEdGraph_GenericGraph::RebuildGenericGraph. The issue is that CurrLevelNodes never is empty because the parent finds the children and the children to the parent

cristiangj avatar Jul 19 '21 08:07 cristiangj

Quick fix to be able to work with cyclical references (adding AlreadyVisitedNodes registry to avoid Children access to their parents):

`

void UEdGraph_GenericGraph::SortNodes(UGenericGraphNode* RootNode) {

int Level = 0;
TArray<UGenericGraphNode*> CurrLevelNodes = { RootNode };
TArray<UGenericGraphNode*> NextLevelNodes;
TArray<UGenericGraphNode*> AlreadyVisitedNodes;

while (CurrLevelNodes.Num() != 0)
{
	int32 LevelWidth = 0;
	for (int i = 0; i < CurrLevelNodes.Num(); ++i)
	{
		UGenericGraphNode* Node = CurrLevelNodes[i];

		auto Comp = [&](const UGenericGraphNode& L, const UGenericGraphNode& R)
		{
			UEdNode_GenericGraphNode* EdNode_LNode = NodeMap[&L];
			UEdNode_GenericGraphNode* EdNode_RNode = NodeMap[&R];
			return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX;
		};

		Node->ChildrenNodes.Sort(Comp);
		Node->ParentNodes.Sort(Comp);

		for (int j = 0; j < Node->ChildrenNodes.Num(); ++j)
		{
			if (!AlreadyVisitedNodes.Contains(Node->ChildrenNodes[j]))
			{
				NextLevelNodes.Add(Node->ChildrenNodes[j]);
				AlreadyVisitedNodes.Add(Node->ChildrenNodes[j]);
			}
		}
	}

	CurrLevelNodes = NextLevelNodes;
	NextLevelNodes.Reset();
	++Level;
}

}`

cristiangj avatar Jul 20 '21 11:07 cristiangj