static List <InsertionBucket> CreateSystemDependencyList(IEnumerable <ScriptBehaviourManager> activeManagers, PlayerLoopSystem defaultPlayerLoop) { var dependencyGraph = BuildSystemGraph(activeManagers, defaultPlayerLoop); MarkSchedulingAndWaitingJobs(dependencyGraph); // Figure out which systems should be inserted early or late var earlyUpdates = new HashSet <DependantBehavior>(); var normalUpdates = new HashSet <DependantBehavior>(); var lateUpdates = new HashSet <DependantBehavior>(); foreach (var dependency in dependencyGraph) { var system = dependency.Value; if (system.spawnsJobs) { earlyUpdates.Add(system); } else if (system.WaitsForJobs) { lateUpdates.Add(system); } else { normalUpdates.Add(system); } } var depsToAdd = new List <DependantBehavior>(); while (true) { foreach (var sys in earlyUpdates) { foreach (var depType in sys.UpdateAfter) { var depSys = dependencyGraph[depType]; if (normalUpdates.Remove(depSys) || lateUpdates.Remove(depSys)) { depsToAdd.Add(depSys); } } } if (depsToAdd.Count == 0) { break; } foreach (var dep in depsToAdd) { earlyUpdates.Add(dep); } depsToAdd.Clear(); } while (true) { foreach (var sys in lateUpdates) { foreach (var depType in sys.UpdateBefore) { var depSys = dependencyGraph[depType]; if (normalUpdates.Remove(depSys)) { depsToAdd.Add(depSys); } } } if (depsToAdd.Count == 0) { break; } foreach (var dep in depsToAdd) { lateUpdates.Add(dep); } depsToAdd.Clear(); } var defaultPos = 0; foreach (var sys in defaultPlayerLoop.subSystemList) { defaultPos += 1 + sys.subSystemList.Length; if (sys.type == typeof(UnityEngine.Experimental.PlayerLoop.Update)) { break; } } var insertionBucketDict = new Dictionary <int, InsertionBucket>(); // increase the number of dependencies allowed by 1, starting from 0 and add all systems with that many at the first or last possible pos // bucket idx is insertion point << 2 | 0,1,2 // When adding propagate min or max through the chain var processedChainLength = 0; while (earlyUpdates.Count > 0 || lateUpdates.Count > 0) { foreach (var sys in earlyUpdates) { if (sys.LongestSystemsUpdatingBeforeChain != processedChainLength) { continue; } if (sys.MinInsertPos == 0) { sys.MinInsertPos = defaultPos; } sys.MaxInsertPos = sys.MinInsertPos; depsToAdd.Add(sys); foreach (var nextSys in sys.UpdateBefore) { if (dependencyGraph[nextSys].MinInsertPos < sys.MinInsertPos) { dependencyGraph[nextSys].MinInsertPos = sys.MinInsertPos; } } } foreach (var sys in lateUpdates) { if (sys.LongestSystemsUpdatingAfterChain != processedChainLength) { continue; } if (sys.MaxInsertPos == 0) { sys.MaxInsertPos = defaultPos; } sys.MinInsertPos = sys.MaxInsertPos; depsToAdd.Add(sys); foreach (var prevSys in sys.UpdateAfter) { if (dependencyGraph[prevSys].MaxInsertPos == 0 || dependencyGraph[prevSys].MaxInsertPos > sys.MaxInsertPos) { dependencyGraph[prevSys].MaxInsertPos = sys.MaxInsertPos; } } } foreach (var sys in depsToAdd) { earlyUpdates.Remove(sys); var isLate = lateUpdates.Remove(sys); var subIndex = isLate ? 2 : 0; // Bucket to insert in is minPos == maxPos var bucketIndex = (sys.MinInsertPos << 2) | subIndex; InsertionBucket bucket; if (!insertionBucketDict.TryGetValue(bucketIndex, out bucket)) { bucket = new InsertionBucket { InsertPos = sys.MinInsertPos, InsertSubPos = subIndex }; insertionBucketDict.Add(bucketIndex, bucket); } bucket.Systems.Add(sys); } depsToAdd.Clear(); ++processedChainLength; } processedChainLength = 0; while (normalUpdates.Count > 0) { foreach (var sys in normalUpdates) { if (sys.LongestSystemsUpdatingBeforeChain != processedChainLength) { continue; } if (sys.MinInsertPos == 0) { sys.MinInsertPos = defaultPos; } sys.MaxInsertPos = sys.MinInsertPos; depsToAdd.Add(sys); foreach (var nextSys in sys.UpdateBefore) { if (dependencyGraph[nextSys].MinInsertPos < sys.MinInsertPos) { dependencyGraph[nextSys].MinInsertPos = sys.MinInsertPos; } } } foreach (var sys in depsToAdd) { const int subIndex = 1; normalUpdates.Remove(sys); // Bucket to insert in is minPos == maxPos var bucketIndex = (sys.MinInsertPos << 2) | subIndex; InsertionBucket bucket; if (!insertionBucketDict.TryGetValue(bucketIndex, out bucket)) { bucket = new InsertionBucket(); bucket.InsertPos = sys.MinInsertPos; bucket.InsertSubPos = subIndex; insertionBucketDict.Add(bucketIndex, bucket); } bucket.Systems.Add(sys); } depsToAdd.Clear(); ++processedChainLength; } return(new List <InsertionBucket>(insertionBucketDict.Values)); }
private static List <InsertionBucket> CreateSystemDependencyList(IEnumerable <ScriptBehaviourManager> activeManagers, PlayerLoopSystem defaultPlayerLoop) { Dictionary <Type, DependantBehavior> dependencyGraph = BuildSystemGraph(activeManagers, defaultPlayerLoop); MarkSchedulingAndWaitingJobs(dependencyGraph); HashSet <DependantBehavior> set = new HashSet <DependantBehavior>(); HashSet <DependantBehavior> set2 = new HashSet <DependantBehavior>(); HashSet <DependantBehavior> set3 = new HashSet <DependantBehavior>(); foreach (KeyValuePair <Type, DependantBehavior> pair in dependencyGraph) { DependantBehavior item = pair.Value; if (item.spawnsJobs) { set.Add(item); continue; } if (item.WaitsForJobs) { set3.Add(item); continue; } set2.Add(item); } List <DependantBehavior> list = new List <DependantBehavior>(); while (true) { foreach (DependantBehavior behavior2 in set) { foreach (Type type in behavior2.UpdateAfter) { DependantBehavior item = dependencyGraph[type]; if (set2.Remove(item) || set3.Remove(item)) { list.Add(item); } } } if (list.Count == 0) { while (true) { foreach (DependantBehavior behavior5 in set3) { foreach (Type type2 in behavior5.UpdateBefore) { DependantBehavior item = dependencyGraph[type2]; if (set2.Remove(item)) { list.Add(item); } } } if (list.Count == 0) { int num = 0; PlayerLoopSystem[] subSystemList = defaultPlayerLoop.subSystemList; int index = 0; while (true) { if (index < subSystemList.Length) { PlayerLoopSystem system = subSystemList[index]; num += 1 + system.subSystemList.Length; if (!(system.type == typeof(Update))) { index++; continue; } } Dictionary <int, InsertionBucket> dictionary2 = new Dictionary <int, InsertionBucket>(); int num2 = 0; while (true) { if ((set.Count <= 0) && (set3.Count <= 0)) { num2 = 0; while (set2.Count > 0) { foreach (DependantBehavior behavior11 in set2) { if (behavior11.LongestSystemsUpdatingBeforeChain == num2) { if (behavior11.MinInsertPos == 0) { behavior11.MinInsertPos = num; } behavior11.MaxInsertPos = behavior11.MinInsertPos; list.Add(behavior11); foreach (Type type5 in behavior11.UpdateBefore) { if (dependencyGraph[type5].MinInsertPos < behavior11.MinInsertPos) { dependencyGraph[type5].MinInsertPos = behavior11.MinInsertPos; } } } } foreach (DependantBehavior behavior12 in list) { InsertionBucket bucket2; set2.Remove(behavior12); int key = (behavior12.MinInsertPos << 2) | 1; if (!dictionary2.TryGetValue(key, out bucket2)) { bucket2 = new InsertionBucket { InsertPos = behavior12.MinInsertPos, InsertSubPos = 1 }; dictionary2.Add(key, bucket2); } bucket2.Systems.Add(behavior12); } list.Clear(); num2++; } return(new List <InsertionBucket>(dictionary2.Values)); } foreach (DependantBehavior behavior8 in set) { if (behavior8.LongestSystemsUpdatingBeforeChain == num2) { if (behavior8.MinInsertPos == 0) { behavior8.MinInsertPos = num; } behavior8.MaxInsertPos = behavior8.MinInsertPos; list.Add(behavior8); foreach (Type type3 in behavior8.UpdateBefore) { if (dependencyGraph[type3].MinInsertPos < behavior8.MinInsertPos) { dependencyGraph[type3].MinInsertPos = behavior8.MinInsertPos; } } } } foreach (DependantBehavior behavior9 in set3) { if (behavior9.LongestSystemsUpdatingAfterChain == num2) { if (behavior9.MaxInsertPos == 0) { behavior9.MaxInsertPos = num; } behavior9.MinInsertPos = behavior9.MaxInsertPos; list.Add(behavior9); foreach (Type type4 in behavior9.UpdateAfter) { if ((dependencyGraph[type4].MaxInsertPos == 0) || (dependencyGraph[type4].MaxInsertPos > behavior9.MaxInsertPos)) { dependencyGraph[type4].MaxInsertPos = behavior9.MaxInsertPos; } } } } foreach (DependantBehavior behavior10 in list) { InsertionBucket bucket; set.Remove(behavior10); bool flag16 = set3.Remove(behavior10); int num4 = flag16 ? 2 : 0; int key = (behavior10.MinInsertPos << 2) | num4; if (!dictionary2.TryGetValue(key, out bucket)) { InsertionBucket bucket1 = new InsertionBucket(); bucket1.InsertPos = behavior10.MinInsertPos; bucket1.InsertSubPos = num4; bucket = bucket1; dictionary2.Add(key, bucket); } bucket.Systems.Add(behavior10); } list.Clear(); num2++; } } } foreach (DependantBehavior behavior7 in list) { set3.Add(behavior7); } list.Clear(); } } foreach (DependantBehavior behavior4 in list) { set.Add(behavior4); } list.Clear(); } }