diff --git a/BepInEx.Common/Utility.cs b/BepInEx.Common/Utility.cs index 0cbc26f..bd860a0 100644 --- a/BepInEx.Common/Utility.cs +++ b/BepInEx.Common/Utility.cs @@ -51,34 +51,24 @@ namespace BepInEx.Common public static IEnumerable TopologicalSort(IEnumerable nodes, Func> dependencySelector) { - List sorted_list = new List(); + List nodeQueue = new List(nodes); + List sorted = new List(); - HashSet visited = new HashSet(); - HashSet sorted = new HashSet(); + while (nodeQueue.Count > 0) + { + List nextBatch = nodeQueue.Where(x => !dependencySelector(x).Except(sorted).Any()).ToList(); - foreach (TNode input in nodes) - Visit(input); + if (!nextBatch.Any()) + throw new Exception("Cyclic Dependency:\r\n" + + nodeQueue.Select(x => x.ToString()).Aggregate((a , b) => $"{a}\r\n{b}")); - return sorted_list; + sorted.AddRange(nextBatch); - void Visit(TNode node) - { - if (visited.Contains(node)) - { - if (!sorted.Contains(node)) - throw new Exception("Cyclic Dependency"); - } - else - { - visited.Add(node); + foreach (TNode item in nextBatch) + nodeQueue.Remove(item); + } - foreach (var dep in dependencySelector(node)) - Visit(dep); - - sorted.Add(node); - sorted_list.Add(node); - } - } + return sorted; } ///