using System; using UnityEngine; using UnityEditor.Graphing; using UnityEngine.Pool; namespace UnityEditor.ShaderGraph { sealed partial class GraphData : ISerializationCallbackReceiver { public static class GraphDataUtils { public static void ApplyActionLeafFirst(GraphData graph, Action action) { var temporaryMarks = PooledHashSet.Get(); var permanentMarks = PooledHashSet.Get(); var slots = ListPool.Get(); // Make sure we process a node's children before the node itself. var stack = StackPool.Get(); foreach (var node in graph.GetNodes()) { stack.Push(node); } while (stack.Count > 0) { var node = stack.Pop(); if (permanentMarks.Contains(node.objectId)) { continue; } if (temporaryMarks.Contains(node.objectId)) { action.Invoke(node); permanentMarks.Add(node.objectId); } else { temporaryMarks.Add(node.objectId); stack.Push(node); node.GetInputSlots(slots); foreach (var inputSlot in slots) { var nodeEdges = graph.GetEdges(inputSlot.slotReference); foreach (var edge in nodeEdges) { var fromSocketRef = edge.outputSlot; var childNode = fromSocketRef.node; if (childNode != null) { stack.Push(childNode); } } } slots.Clear(); } } StackPool.Release(stack); ListPool.Release(slots); temporaryMarks.Dispose(); permanentMarks.Dispose(); } } } }