Пример #1
0
    public unsafe void UnsafeList_Resize_ClearMemory()
    {
        var sizeOf  = UnsafeUtility.SizeOf <int>();
        var alignOf = UnsafeUtility.AlignOf <int>();

        UnsafeList list = new UnsafeList(sizeOf, alignOf, 5, Allocator.Persistent, NativeArrayOptions.ClearMemory);

        list.SetCapacity <int>(32);
        var capacity = list.Capacity;

        list.Resize(sizeOf, alignOf, 5, NativeArrayOptions.UninitializedMemory);
        Assert.AreEqual(capacity, list.Capacity); // list capacity should not change on resize

        for (var i = 0; i < 5; ++i)
        {
            UnsafeUtility.WriteArrayElement(list.Ptr, i, i);
        }

        list.Resize(sizeOf, alignOf, 10, NativeArrayOptions.ClearMemory);
        Assert.AreEqual(capacity, list.Capacity); // list capacity should not change on resize

        for (var i = 0; i < 5; ++i)
        {
            Assert.AreEqual(i, UnsafeUtility.ReadArrayElement <int>(list.Ptr, i));
        }

        for (var i = 5; i < list.Length; ++i)
        {
            Assert.AreEqual(0, UnsafeUtility.ReadArrayElement <int>(list.Ptr, i));
        }

        list.Dispose();
    }
Пример #2
0
        void AddToDestroyList(Chunk *chunk, int indexInChunk, int batchCount, int inputDestroyCount,
                              ref UnsafeList entitiesList, ref int minBufferLength, ref int maxBufferLength)
        {
            int indexInArchetype = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, m_LinkedGroupType);

            if (indexInArchetype != -1)
            {
                var baseHeader = ChunkDataUtility.GetComponentDataWithTypeRO(chunk, indexInChunk, m_LinkedGroupType);
                var stride     = chunk->Archetype->SizeOfs[indexInArchetype];
                for (int i = 0; i != batchCount; i++)
                {
                    var header = (BufferHeader *)(baseHeader + stride * i);

                    var entityGroupCount = header->Length - 1;
                    if (entityGroupCount <= 0)
                    {
                        continue;
                    }

                    var entityGroupArray = (Entity *)BufferHeader.GetElementPointer(header) + 1;

                    if (entitiesList.Capacity == 0)
                    {
                        entitiesList.SetCapacity <Entity>(inputDestroyCount * entityGroupCount /*, Allocator.TempJob*/);
                    }
                    entitiesList.AddRange <Entity>(entityGroupArray, entityGroupCount /*, Allocator.TempJob*/);

                    minBufferLength = math.min(minBufferLength, entityGroupCount);
                    maxBufferLength = math.max(maxBufferLength, entityGroupCount);
                }
            }
        }
Пример #3
0
        public void FreeIndexRange(int startIndex, int range)
        {
            var lastIndex = startIndex + range;

            if (startIndex < 0 || lastIndex > indexToID.Length)
            {
                throw new ArgumentOutOfRangeException($"StartIndex {startIndex} with range {range}, must be between 0 and {indexToID.Length}");
            }

            if (range == 0)
            {
                return; // nothing to do
            }
            if (freeIDs.Capacity < freeIDs.Length + (lastIndex - startIndex + 1))
            {
                freeIDs.SetCapacity((int)((freeIDs.Length + (lastIndex - startIndex + 1)) * 1.5f));
            }
            for (int index = startIndex; index < lastIndex; index++)
            {
                var idInternal = indexToID[index] - 1;
                indexToID[index] = 0;

                //Debug.Assert(!freeIDs.Contains(idInternal)); // slow
                freeIDs.AddNoResize(idInternal);

                var idLookup = idToIndex[idInternal];
                idLookup.index        = -1;
                idToIndex[idInternal] = idLookup;
            }

            sectionManager.FreeRange(startIndex, range);
        }
Пример #4
0
    public void UnsafeList_Performance_Add()
    {
        const int numElements = 16 << 10;

        var sizeOf  = UnsafeUtility.SizeOf <int>();
        var alignOf = UnsafeUtility.AlignOf <int>();
        var list    = new UnsafeList(sizeOf, alignOf, 1, Allocator.Persistent, NativeArrayOptions.ClearMemory);

        Measure.Method(() =>
        {
            list.SetCapacity <int>(1);
            for (int i = 0; i < numElements; ++i)
            {
                list.Add(i);
            }
        })
        .WarmupCount(100)
        .MeasurementCount(1000)
        .Run();

        list.Dispose();
    }
Пример #5
0
        private void SortSystemUpdateList2()
        {
            if (!m_systemSortDirty)
            {
                return;
            }

            if (UseLegacySortOrder)
            {
                throw new InvalidOperationException("UseLegacySortOrder must be false to use the updated sorting API");
            }

            RemovePending();


            // Build three lists of systems
            var elems = new List <ComponentSystemSorter.SystemElement>[3]
            {
                new List <ComponentSystemSorter.SystemElement>(4),
                new List <ComponentSystemSorter.SystemElement>(m_systemsToUpdate.Count + m_UnmanagedSystemsToUpdate.Length),
                new List <ComponentSystemSorter.SystemElement>(4),
            };

            var ourType = GetType();

            for (int i = 0; i < m_systemsToUpdate.Count; ++i)
            {
                var system  = m_systemsToUpdate[i];
                var sysType = system.GetType();

                // Take order first/last ordering into account
                int ordering = ComputeSystemOrdering(sysType, ourType);
                elems[ordering].Add(new ComponentSystemSorter.SystemElement {
                    Index = new UpdateIndex(i, true), Type = sysType
                });
            }

            for (int i = 0; i < m_UnmanagedSystemsToUpdate.Length; ++i)
            {
                var sysType  = World.GetTypeOfUnmanagedSystem(m_UnmanagedSystemsToUpdate[i]);
                int ordering = ComputeSystemOrdering(sysType, ourType);
                elems[ordering].Add(new ComponentSystemSorter.SystemElement {
                    Index = new UpdateIndex(i, false), Type = sysType
                });
            }

            // Perform the sort for each bucket.
            for (int i = 0; i < 3; ++i)
            {
                if (elems[i].Count > 0)
                {
                    ComponentSystemSorter.Sort(elems[i], ourType);
                }
            }

            // 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 elems[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(elems[0].Count + elems[1].Count + elems[2].Count);

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

            for (int i = 0; i < 3; ++i)
            {
                foreach (var e in elems[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);
                }
            }
        }
Пример #6
0
        public int SetCapacity(int capacity)
        {
            UnsafeList.SetCapacity(m_inner, capacity);

            return(Capacity);
        }
Пример #7
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);
                }
            }
        }