private static void CollectGroups(IEnumerable <ScriptBehaviourManager> activeManagers, out Dictionary <Type, ScriptBehaviourGroup> allGroups, out Dictionary <Type, DependantBehavior> dependencies) { allGroups = new Dictionary <Type, ScriptBehaviourGroup>(); dependencies = new Dictionary <Type, DependantBehavior>(); foreach (ScriptBehaviourManager manager in activeManagers) { object[] objArray2 = manager.GetType().GetCustomAttributes(typeof(UpdateInGroupAttribute), true); int index = 0; while (true) { ScriptBehaviourGroup group; if (index >= objArray2.Length) { DependantBehavior behavior = new DependantBehavior(manager); dependencies.Add(manager.GetType(), behavior); break; } object obj2 = objArray2[index]; UpdateInGroupAttribute attribute = obj2 as UpdateInGroupAttribute; if (!allGroups.TryGetValue(attribute.GroupType, out group)) { group = new ScriptBehaviourGroup(attribute.GroupType, allGroups, null); } group.Managers.Add(manager.GetType()); index++; } } }
public void AddUpdateAfterToAllChildBehaviours(DependantBehavior target, IReadOnlyDictionary <Type, DependantBehavior> dependencies) { var dep = target.Manager.GetType(); foreach (var manager in Managers) { DependantBehavior managerDep; if (!dependencies.TryGetValue(manager, out managerDep)) { continue; } target.UpdateBefore.Add(manager); managerDep.UpdateAfter.Add(dep); } foreach (var group in m_Groups) { group.AddUpdateAfterToAllChildBehaviours(target, dependencies); } }
static void ValidateAndFixSingleChainMaxPos(DependantBehavior system, Dictionary <Type, DependantBehavior> dependencyGraph, int maxInsertPos) { foreach (var prevInChain in system.UpdateAfter) { var prevSys = dependencyGraph[prevInChain]; if (system.LongestSystemsUpdatingAfterChain >= prevSys.LongestSystemsUpdatingAfterChain) { prevSys.LongestSystemsUpdatingAfterChain = system.LongestSystemsUpdatingAfterChain + 1; } if (prevSys.MaxInsertPos == 0 || prevSys.MaxInsertPos > maxInsertPos) { prevSys.MaxInsertPos = maxInsertPos; } if (prevSys.MaxInsertPos > 0 && prevSys.MaxInsertPos < prevSys.MinInsertPos) { Debug.LogError($"{prevInChain} is over constrained with engine and system containts - ignoring dependencies"); prevSys.MinInsertPos = prevSys.MaxInsertPos; } ValidateAndFixSingleChainMaxPos(prevSys, dependencyGraph, prevSys.MaxInsertPos); } }
static void ValidateAndFixSingleChainMinPos(DependantBehavior system, IReadOnlyDictionary <Type, DependantBehavior> dependencyGraph, int minInsertPos) { foreach (var nextInChain in system.UpdateBefore) { var nextSys = dependencyGraph[nextInChain]; if (system.LongestSystemsUpdatingBeforeChain >= nextSys.LongestSystemsUpdatingBeforeChain) { nextSys.LongestSystemsUpdatingBeforeChain = system.LongestSystemsUpdatingBeforeChain + 1; } if (nextSys.MinInsertPos < minInsertPos) { nextSys.MinInsertPos = minInsertPos; } if (nextSys.MaxInsertPos > 0 && nextSys.MaxInsertPos < nextSys.MinInsertPos) { Debug.LogError($"{nextInChain} is over constrained with engine and system containts - ignoring dependencies"); nextSys.MaxInsertPos = nextSys.MinInsertPos; } ValidateAndFixSingleChainMinPos(nextSys, dependencyGraph, nextSys.MinInsertPos); } }
private static void ValidateAndFixSingleChainMinPos(DependantBehavior system, IReadOnlyDictionary <Type, DependantBehavior> dependencyGraph, int minInsertPos) { foreach (Type type in system.UpdateBefore) { DependantBehavior behavior = dependencyGraph[type]; if (system.LongestSystemsUpdatingBeforeChain >= behavior.LongestSystemsUpdatingBeforeChain) { behavior.LongestSystemsUpdatingBeforeChain = system.LongestSystemsUpdatingBeforeChain + 1; } if (behavior.MinInsertPos < minInsertPos) { behavior.MinInsertPos = minInsertPos; } if ((behavior.MaxInsertPos > 0) && (behavior.MaxInsertPos < behavior.MinInsertPos)) { Debug.LogError($"{type} is over constrained with engine and system containts - ignoring dependencies"); behavior.MaxInsertPos = behavior.MinInsertPos; } ValidateAndFixSingleChainMinPos(behavior, dependencyGraph, behavior.MinInsertPos); } }
public static void CollectGroups(IEnumerable <ScriptBehaviourManager> activeManagers, out Dictionary <Type, ScriptBehaviourGroup> allGroups, out Dictionary <Type, DependantBehavior> dependencies) { allGroups = new Dictionary <Type, ScriptBehaviourGroup>(); dependencies = new Dictionary <Type, DependantBehavior>(); foreach (var manager in activeManagers) { var attribs = manager.GetType().GetCustomAttributes(typeof(UpdateInGroupAttribute), true); foreach (var attr in attribs) { var grp = attr as UpdateInGroupAttribute; ScriptBehaviourGroup groupData; if (!allGroups.TryGetValue(grp.GroupType, out groupData)) { groupData = new ScriptBehaviourGroup(grp.GroupType, allGroups); } groupData.Managers.Add(manager.GetType()); } var dep = new DependantBehavior(manager); dependencies.Add(manager.GetType(), dep); } }
static Dictionary <Type, DependantBehavior> BuildSystemGraph(IEnumerable <ScriptBehaviourManager> activeManagers, PlayerLoopSystem defaultPlayerLoop) { // Collect all groups and create empty dependency data var allGroups = new Dictionary <Type, ScriptBehaviourGroup>(); var dependencies = new Dictionary <Type, DependantBehavior>(); foreach (var manager in activeManagers) { var attribs = manager.GetType().GetCustomAttributes(typeof(UpdateInGroupAttribute), true); foreach (var attr in attribs) { var grp = attr as UpdateInGroupAttribute; ScriptBehaviourGroup groupData; if (!allGroups.TryGetValue(grp.GroupType, out groupData)) { groupData = new ScriptBehaviourGroup(grp.GroupType, allGroups); } groupData.Managers.Add(manager.GetType()); } var dep = new DependantBehavior(manager); dependencies.Add(manager.GetType(), dep); } // @TODO: apply additional sideloaded constraints here // Apply the update before / after dependencies foreach (var manager in dependencies) { // @TODO: need to deal with extracting dependencies for GenericProcessComponentSystem AddDependencies(manager.Value, dependencies, allGroups, defaultPlayerLoop); } ValidateAndFixSystemGraph(dependencies); return(dependencies); }
static void AddDependencies(DependantBehavior targetSystem, IReadOnlyDictionary <Type, DependantBehavior> dependencies, IReadOnlyDictionary <Type, ScriptBehaviourGroup> allGroups, PlayerLoopSystem defaultPlayerLoop) { var target = targetSystem.Manager.GetType(); var attribs = target.GetCustomAttributes(typeof(UpdateAfterAttribute), true); foreach (var attr in attribs) { var attribDep = attr as UpdateAfterAttribute; DependantBehavior otherSystem; ScriptBehaviourGroup otherGroup; if (dependencies.TryGetValue(attribDep.SystemType, out otherSystem)) { targetSystem.UpdateAfter.Add(attribDep.SystemType); otherSystem.UpdateBefore.Add(target); } else if (allGroups.TryGetValue(attribDep.SystemType, out otherGroup)) { otherGroup.AddUpdateBeforeToAllChildBehaviours(targetSystem, dependencies); } else { UpdateInsertionPos(targetSystem, attribDep.SystemType, defaultPlayerLoop, true); } } attribs = target.GetCustomAttributes(typeof(UpdateBeforeAttribute), true); foreach (var attr in attribs) { var attribDep = attr as UpdateBeforeAttribute; DependantBehavior otherSystem; ScriptBehaviourGroup otherGroup; if (dependencies.TryGetValue(attribDep.SystemType, out otherSystem)) { targetSystem.UpdateBefore.Add(attribDep.SystemType); otherSystem.UpdateAfter.Add(target); } else if (allGroups.TryGetValue(attribDep.SystemType, out otherGroup)) { otherGroup.AddUpdateAfterToAllChildBehaviours(targetSystem, dependencies); } else { UpdateInsertionPos(targetSystem, attribDep.SystemType, defaultPlayerLoop, false); } } attribs = target.GetCustomAttributes(typeof(UpdateInGroupAttribute), true); foreach (var attr in attribs) { var attribDep = attr as UpdateInGroupAttribute; ScriptBehaviourGroup group; if (!allGroups.TryGetValue(attribDep.GroupType, out group)) { continue; } DependantBehavior otherSystem; ScriptBehaviourGroup otherGroup; foreach (var dep in group.UpdateAfter) { if (dependencies.TryGetValue(dep, out otherSystem)) { targetSystem.UpdateAfter.Add(dep); otherSystem.UpdateBefore.Add(target); } else if (allGroups.TryGetValue(dep, out otherGroup)) { otherGroup.AddUpdateBeforeToAllChildBehaviours(targetSystem, dependencies); } else { UpdateInsertionPos(targetSystem, dep, defaultPlayerLoop, true); } } foreach (var dep in group.UpdateBefore) { if (dependencies.TryGetValue(dep, out otherSystem)) { targetSystem.UpdateBefore.Add(dep); otherSystem.UpdateAfter.Add(target); } else if (allGroups.TryGetValue(dep, out otherGroup)) { otherGroup.AddUpdateAfterToAllChildBehaviours(targetSystem, dependencies); } else { UpdateInsertionPos(targetSystem, dep, defaultPlayerLoop, false); } } } }
// Try to find a system of the specified type in the default playerloop and update the min / max insertion position static void UpdateInsertionPos(DependantBehavior target, Type dep, PlayerLoopSystem defaultPlayerLoop, bool after) { var pos = 0; foreach (var sys in defaultPlayerLoop.subSystemList) { ++pos; if (sys.type == dep) { if (after) { pos += sys.subSystemList.Length; if (target.MinInsertPos < pos) { target.MinInsertPos = pos; } if (target.MaxInsertPos == 0 || target.MaxInsertPos > pos) { target.MaxInsertPos = pos; } } else { if (target.MinInsertPos < pos) { target.MinInsertPos = pos; } if (target.MaxInsertPos == 0 || target.MaxInsertPos > pos) { target.MaxInsertPos = pos; } } return; } var beginPos = pos; var endPos = pos + sys.subSystemList.Length; foreach (var subsys in sys.subSystemList) { if (subsys.type == dep) { if (after) { ++pos; if (target.MinInsertPos < pos) { target.MinInsertPos = pos; } if (target.MaxInsertPos == 0 || target.MaxInsertPos > endPos) { target.MaxInsertPos = endPos; } } else { if (target.MinInsertPos < beginPos) { target.MinInsertPos = beginPos; } if (target.MaxInsertPos == 0 || target.MaxInsertPos > pos) { target.MaxInsertPos = pos; } } return; } ++pos; } } // System was not found }
private static void ValidateAndFixSystemGraph(Dictionary <Type, DependantBehavior> dependencyGraph) { foreach (KeyValuePair <Type, DependantBehavior> pair in dependencyGraph) { DependantBehavior behavior = pair.Value; if (behavior.MinInsertPos > behavior.MaxInsertPos) { Debug.LogError($"{behavior.Manager.GetType()} is over constrained with engine containts - ignoring dependencies"); behavior.MinInsertPos = behavior.MaxInsertPos = 0; } behavior.UnvalidatedSystemsUpdatingBefore = behavior.UpdateAfter.Count; behavior.LongestSystemsUpdatingBeforeChain = 0; behavior.LongestSystemsUpdatingAfterChain = 0; } bool flag = true; while (true) { if (!flag) { foreach (KeyValuePair <Type, DependantBehavior> pair3 in dependencyGraph) { DependantBehavior behavior3 = pair3.Value; if (behavior3.UnvalidatedSystemsUpdatingBefore > 0) { Debug.LogError($"{behavior3.Manager.GetType()} is in a chain of circular dependencies - ignoring dependencies"); foreach (Type type2 in behavior3.UpdateAfter) { dependencyGraph[type2].UpdateBefore.Remove(behavior3.Manager.GetType()); } behavior3.UpdateAfter.Clear(); } } foreach (KeyValuePair <Type, DependantBehavior> pair4 in dependencyGraph) { DependantBehavior system = pair4.Value; if (system.UpdateBefore.Count == 0) { ValidateAndFixSingleChainMaxPos(system, dependencyGraph, system.MaxInsertPos); } if (system.UpdateAfter.Count == 0) { ValidateAndFixSingleChainMinPos(system, dependencyGraph, system.MinInsertPos); } } return; } flag = false; foreach (KeyValuePair <Type, DependantBehavior> pair2 in dependencyGraph) { DependantBehavior behavior2 = pair2.Value; if (behavior2.UnvalidatedSystemsUpdatingBefore == 0) { behavior2.UnvalidatedSystemsUpdatingBefore = -1; foreach (Type type in behavior2.UpdateBefore) { DependantBehavior local1 = dependencyGraph[type]; local1.UnvalidatedSystemsUpdatingBefore--; flag = true; } } } } }
private static void UpdateInsertionPos(DependantBehavior target, Type dep, PlayerLoopSystem defaultPlayerLoop, bool after) { int num = 0; PlayerLoopSystem[] subSystemList = defaultPlayerLoop.subSystemList; int index = 0; while (true) { while (true) { if (index < subSystemList.Length) { PlayerLoopSystem system = subSystemList[index]; num++; if (!(system.type == dep)) { int num3 = num; int num4 = num + system.subSystemList.Length; PlayerLoopSystem[] systemArray2 = system.subSystemList; int num5 = 0; while (true) { if (num5 < systemArray2.Length) { PlayerLoopSystem system2 = systemArray2[num5]; if (!(system2.type == dep)) { num++; num5++; continue; } if (!after) { if (target.MinInsertPos < num3) { target.MinInsertPos = num3; } if ((target.MaxInsertPos == 0) || (target.MaxInsertPos > num)) { target.MaxInsertPos = num; } } else { num++; if (target.MinInsertPos < num) { target.MinInsertPos = num; } if ((target.MaxInsertPos == 0) || (target.MaxInsertPos > num4)) { target.MaxInsertPos = num4; } } } else { index++; continue; } break; } } else if (!after) { if (target.MinInsertPos < num) { target.MinInsertPos = num; } if ((target.MaxInsertPos == 0) || (target.MaxInsertPos > num)) { target.MaxInsertPos = num; } } else { num += system.subSystemList.Length; if (target.MinInsertPos < num) { target.MinInsertPos = num; } if ((target.MaxInsertPos == 0) || (target.MaxInsertPos > num)) { target.MaxInsertPos = num; } } return; } else { return; } } } }
private static void MarkSchedulingAndWaitingJobs(Dictionary <Type, DependantBehavior> dependencyGraph) { HashSet <DependantBehavior> set = new HashSet <DependantBehavior>(); foreach (KeyValuePair <Type, DependantBehavior> pair in dependencyGraph) { DependantBehavior item = pair.Value; if (item.Manager is JobComponentSystem) { item.spawnsJobs = true; set.Add(item); } } foreach (KeyValuePair <Type, DependantBehavior> pair2 in dependencyGraph) { ComponentGroup[] componentGroups; DependantBehavior behavior2 = pair2.Value; ComponentSystem manager = behavior2.Manager as ComponentSystem; if (manager != null) { componentGroups = manager.ComponentGroups; } else { object obj1 = manager; componentGroups = null; } if (componentGroups != null) { HashSet <int> set2 = new HashSet <int>(); ComponentGroup[] componentGroups = ((ComponentSystem)behavior2.Manager).ComponentGroups; int index = 0; while (true) { if (index >= componentGroups.Length) { using (HashSet <DependantBehavior> .Enumerator enumerator3 = set.GetEnumerator()) { while (true) { if (enumerator3.MoveNext()) { DependantBehavior current = enumerator3.Current; if (!(current.Manager is ComponentSystem)) { continue; } HashSet <int> set3 = new HashSet <int>(); ComponentGroup[] groupArray2 = ((ComponentSystem)current.Manager).ComponentGroups; int num3 = 0; while (true) { if (num3 < groupArray2.Length) { ComponentGroup group2 = groupArray2[num3]; ComponentType[] typeArray2 = group2.Types; int num4 = 0; while (true) { if (num4 >= typeArray2.Length) { num3++; break; } ComponentType type2 = typeArray2[num4]; if (type2.RequiresJobDependency) { set3.Add(type2.TypeIndex); } num4++; } continue; } bool flag4 = false; foreach (int num5 in set2) { if (set3.Contains(num5)) { flag4 = true; break; } } if (flag4) { behavior2.WaitsForJobs = true; } else { continue; } break; } } break; } } break; } ComponentGroup group = componentGroups[index]; ComponentType[] types = group.Types; int num2 = 0; while (true) { if (num2 >= types.Length) { index++; break; } ComponentType type = types[num2]; if (type.RequiresJobDependency) { set2.Add(type.TypeIndex); } num2++; } } } } }
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(); } }
private static void AddDependencies(DependantBehavior targetSystem, IReadOnlyDictionary <Type, DependantBehavior> dependencies, IReadOnlyDictionary <Type, ScriptBehaviourGroup> allGroups, PlayerLoopSystem defaultPlayerLoop) { Type item = targetSystem.Manager.GetType(); foreach (object obj2 in item.GetCustomAttributes(typeof(UpdateAfterAttribute), true)) { DependantBehavior behavior; UpdateAfterAttribute attribute = obj2 as UpdateAfterAttribute; if (dependencies.TryGetValue(attribute.SystemType, out behavior)) { targetSystem.UpdateAfter.Add(attribute.SystemType); behavior.UpdateBefore.Add(item); } else { ScriptBehaviourGroup group; if (allGroups.TryGetValue(attribute.SystemType, out group)) { group.AddUpdateBeforeToAllChildBehaviours(targetSystem, dependencies); } else { UpdateInsertionPos(targetSystem, attribute.SystemType, defaultPlayerLoop, true); } } } foreach (object obj3 in item.GetCustomAttributes(typeof(UpdateBeforeAttribute), true)) { DependantBehavior behavior2; UpdateBeforeAttribute attribute2 = obj3 as UpdateBeforeAttribute; if (dependencies.TryGetValue(attribute2.SystemType, out behavior2)) { targetSystem.UpdateBefore.Add(attribute2.SystemType); behavior2.UpdateAfter.Add(item); } else { ScriptBehaviourGroup group2; if (allGroups.TryGetValue(attribute2.SystemType, out group2)) { group2.AddUpdateAfterToAllChildBehaviours(targetSystem, dependencies); } else { UpdateInsertionPos(targetSystem, attribute2.SystemType, defaultPlayerLoop, false); } } } foreach (object obj4 in item.GetCustomAttributes(typeof(UpdateInGroupAttribute), true)) { ScriptBehaviourGroup group3; UpdateInGroupAttribute attribute3 = obj4 as UpdateInGroupAttribute; if (allGroups.TryGetValue(attribute3.GroupType, out group3)) { DependantBehavior behavior3; ScriptBehaviourGroup group4; foreach (Type type2 in group3.UpdateAfter) { if (dependencies.TryGetValue(type2, out behavior3)) { targetSystem.UpdateAfter.Add(type2); behavior3.UpdateBefore.Add(item); continue; } if (allGroups.TryGetValue(type2, out group4)) { group4.AddUpdateBeforeToAllChildBehaviours(targetSystem, dependencies); continue; } UpdateInsertionPos(targetSystem, type2, defaultPlayerLoop, true); } foreach (Type type3 in group3.UpdateBefore) { if (dependencies.TryGetValue(type3, out behavior3)) { targetSystem.UpdateBefore.Add(type3); behavior3.UpdateAfter.Add(item); continue; } if (allGroups.TryGetValue(type3, out group4)) { group4.AddUpdateAfterToAllChildBehaviours(targetSystem, dependencies); continue; } UpdateInsertionPos(targetSystem, type3, defaultPlayerLoop, false); } } } }