Browse Source

Use new dependency sorting algorithm

Bepis 5 years ago
parent
commit
3eef163425
1 changed files with 13 additions and 23 deletions
  1. 13 23
      BepInEx.Common/Utility.cs

+ 13 - 23
BepInEx.Common/Utility.cs

@@ -51,34 +51,24 @@ namespace BepInEx.Common
 
         public static IEnumerable<TNode> TopologicalSort<TNode>(IEnumerable<TNode> nodes, Func<TNode, IEnumerable<TNode>> dependencySelector)
         {
-            List<TNode> sorted_list = new List<TNode>();
+			List<TNode> nodeQueue = new List<TNode>(nodes);
+			List<TNode> sorted = new List<TNode>();
 
-            HashSet<TNode> visited = new HashSet<TNode>();
-            HashSet<TNode> sorted = new HashSet<TNode>();
+	        while (nodeQueue.Count > 0)
+	        {
+		        List<TNode> 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 (var dep in dependencySelector(node))
-                        Visit(dep);
+		        foreach (TNode item in nextBatch)
+			        nodeQueue.Remove(item);
+	        }
 
-                    sorted.Add(node);
-                    sorted_list.Add(node);
-                }
-            }
+	        return sorted;
         }
 
         /// <summary>