public virtual void SortSystemUpdateList()
        {
            CheckCreated();

            if (!UseLegacySortOrder)
            {
                throw new InvalidOperationException("UseLegacySortOrder must be true to use the SortSystemUpdateList() legacy API");
            }

            if (!m_systemSortDirty)
            {
                return;
            }

            m_systemSortDirty = false;

            RemovePending();

            foreach (var sys in m_systemsToUpdate)
            {
                if (TypeManager.IsSystemAGroup(sys.GetType()))
                {
                    RecurseUpdate((ComponentSystemGroup)sys);
                }
            }

            var elems = new ComponentSystemSorter.SystemElement[m_systemsToUpdate.Count];

            for (int i = 0; i < m_systemsToUpdate.Count; ++i)
            {
                elems[i] = new ComponentSystemSorter.SystemElement
                {
                    Type           = m_systemsToUpdate[i].GetType(),
                    Index          = new UpdateIndex(i, true),
                    OrderingBucket = 1,
                    updateBefore   = new List <Type>(),
                    nAfter         = 0,
                };
            }

            ComponentSystemSorter.FindConstraints(GetType(), elems);

            ComponentSystemSorter.Sort(elems);

            var oldSystems = m_systemsToUpdate;

            m_systemsToUpdate = new List <ComponentSystemBase>(oldSystems.Count);
            m_MasterUpdateList.Clear();
            for (int i = 0; i < elems.Length; ++i)
            {
                var index = elems[i].Index;
                m_systemsToUpdate.Add(oldSystems[index.Index]);
                m_MasterUpdateList.Add(new UpdateIndex(i, true));
            }
        }
예제 #2
0
        private void RecurseUpdate(ComponentSystemGroup group)
        {
            if (!m_systemSortDirty)
            {
                return;
            }

            RemovePending();

            var groupType        = GetType();
            var allElems         = new ComponentSystemSorter.SystemElement[m_systemsToUpdate.Count + m_UnmanagedSystemsToUpdate.Length];
            var systemsPerBucket = new int[3];

            for (int i = 0; i < m_systemsToUpdate.Count; ++i)
            {
                var system         = m_systemsToUpdate[i];
                var sysType        = system.GetType();
                int orderingBucket = ComputeSystemOrdering(sysType, groupType);
                allElems[i] = new ComponentSystemSorter.SystemElement
                {
                    Type           = sysType,
                    Index          = new UpdateIndex(i, true),
                    OrderingBucket = orderingBucket,
                    updateBefore   = new List <Type>(),
                    nAfter         = 0,
                };
                systemsPerBucket[orderingBucket]++;
            }
            for (int i = 0; i < m_UnmanagedSystemsToUpdate.Length; ++i)
            {
                var sysType        = World.GetTypeOfUnmanagedSystem(m_UnmanagedSystemsToUpdate[i]);
                int orderingBucket = ComputeSystemOrdering(sysType, groupType);
                allElems[m_systemsToUpdate.Count + i] = new ComponentSystemSorter.SystemElement
                {
                    Type           = sysType,
                    Index          = new UpdateIndex(i, false),
                    OrderingBucket = orderingBucket,
                    updateBefore   = new List <Type>(),
                    nAfter         = 0,
                };
                systemsPerBucket[orderingBucket]++;
            }

            // Find & validate constraints between systems in the group
            ComponentSystemSorter.FindConstraints(groupType, allElems);

            // Build three lists of systems
            var elemBuckets = new []
            {
                new ComponentSystemSorter.SystemElement[systemsPerBucket[0]],
                new ComponentSystemSorter.SystemElement[systemsPerBucket[1]],
                new ComponentSystemSorter.SystemElement[systemsPerBucket[2]],
            };
            var nextBucketIndex = new int[3];

            for (int i = 0; i < allElems.Length; ++i)
            {
                int bucket = allElems[i].OrderingBucket;
                int index  = nextBucketIndex[bucket]++;
                elemBuckets[bucket][index] = allElems[i];
            }
            // Perform the sort for each bucket.
            for (int i = 0; i < 3; ++i)
            {
                if (elemBuckets[i].Length > 0)
                {
                    ComponentSystemSorter.Sort(elemBuckets[i]);
                }
            }

            // Because people can freely look at the list of managed systems, we need to put that part of list in order.
            var oldSystems = m_systemsToUpdate;

            m_systemsToUpdate = new List <ComponentSystemBase>(oldSystems.Count);
            for (int i = 0; i < 3; ++i)
            {
                foreach (var e in elemBuckets[i])
                {
                    var index = e.Index;
                    if (index.IsManaged)
                    {
                        m_systemsToUpdate.Add(oldSystems[index.Index]);
                    }
                }
            }

            // Commit results to master update list
            m_MasterUpdateList.Clear();
            m_MasterUpdateList.SetCapacity(allElems.Length);

            // Append buckets in order, but replace managed indices with incrementing indices
            // into the newly sorted m_systemsToUpdate list
            int managedIndex = 0;

            for (int i = 0; i < 3; ++i)
            {
                foreach (var e in elemBuckets[i])
                {
                    if (e.Index.IsManaged)
                    {
                        m_MasterUpdateList.Add(new UpdateIndex(managedIndex++, true));
                    }
                    else
                    {
                        m_MasterUpdateList.Add(e.Index);
                    }
                }
            }

            m_systemSortDirty = false;

            foreach (var sys in m_systemsToUpdate)
            {
                if (TypeManager.IsSystemAGroup(sys.GetType()))
                {
                    RecurseUpdate((ComponentSystemGroup)sys);
                }
            }
        }