void ConstructChunk(Archetype *archetype, Chunk *chunk, SharedComponentValues sharedComponentValues)
        {
            chunk->Archetype       = archetype;
            chunk->Count           = 0;
            chunk->Capacity        = archetype->ChunkCapacity;
            chunk->SequenceNumber  = AssignSequenceNumber(chunk);
            chunk->metaChunkEntity = Entity.Null;

            var numSharedComponents = archetype->NumSharedComponents;

            if (numSharedComponents > 0)
            {
                for (var i = 0; i < archetype->NumSharedComponents; ++i)
                {
                    var sharedComponentIndex = sharedComponentValues[i];
                    ManagedChangesTracker.AddReference(sharedComponentIndex);
                }
            }

            archetype->AddToChunkList(chunk, sharedComponentValues, GlobalSystemVersion);

            Assert.IsTrue(archetype->Chunks.Count != 0);

            // Chunk can't be locked at at construction time
            archetype->EmptySlotTrackingAddChunk(chunk);

            if (numSharedComponents == 0)
            {
                Assert.IsTrue(archetype->ChunksWithEmptySlots.Length != 0);
            }
            else
            {
                Assert.IsTrue(archetype->FreeChunksBySharedComponents.TryGet(chunk->SharedComponentValues,
                                                                             archetype->NumSharedComponents) != null);
            }

            if (archetype->NumManagedArrays > 0)
            {
                int managedArrayIndex;
                if (!m_ManagedArrayFreeIndex.IsEmpty)
                {
                    managedArrayIndex = m_ManagedArrayFreeIndex.Pop <int>();
                }
                else
                {
                    managedArrayIndex = m_ManagedArrayIndex;
                    m_ManagedArrayIndex++;
                }

                ManagedChangesTracker.AllocateManagedArrayStorage(managedArrayIndex,
                                                                  archetype->NumManagedArrays * chunk->Capacity);
                chunk->ManagedArrayIndex = managedArrayIndex;
            }
            else
            {
                chunk->ManagedArrayIndex = -1;
            }

            chunk->Flags = 0;
        }
        void ReleaseChunk(Chunk *chunk)
        {
            // Remove references to shared components
            if (chunk->Archetype->NumSharedComponents > 0)
            {
                var sharedComponentValueArray = chunk->SharedComponentValues;

                for (var i = 0; i < chunk->Archetype->NumSharedComponents; ++i)
                {
                    ManagedChangesTracker.RemoveReference(sharedComponentValueArray[i]);
                }
            }

            if (chunk->ManagedArrayIndex != -1)
            {
                ManagedChangesTracker.DeallocateManagedArrayStorage(chunk->ManagedArrayIndex);
                m_ManagedArrayFreeIndex.Add(chunk->ManagedArrayIndex);
                chunk->ManagedArrayIndex = -1;
            }

            // this chunk is going away, so it shouldn't be in the empty slot list.
            if (chunk->Count < chunk->Capacity)
            {
                chunk->Archetype->EmptySlotTrackingRemoveChunk(chunk);
            }

            chunk->Archetype->RemoveFromChunkList(chunk);
            chunk->Archetype = null;

            FreeChunk(chunk);
        }
Ejemplo n.º 3
0
        void DeleteChunk(Chunk *chunk)
        {
            var entityCount = chunk->Count;

            DeallocateDataEntitiesInChunk(chunk, 0, chunk->Count);
            ManagedChangesTracker.IncrementComponentOrderVersion(chunk->Archetype, chunk->SharedComponentValues);
            IncrementComponentTypeOrderVersion(chunk->Archetype);
            chunk->Archetype->EntityCount -= entityCount;
            SetChunkCount(chunk, 0);
        }
        void DestroyBatch(Entity *entities, Chunk *chunk, int indexInChunk, int batchCount)
        {
            var archetype = chunk->Archetype;

            if (!archetype->SystemStateCleanupNeeded)
            {
                DeallocateDataEntitiesInChunk(entities, chunk, indexInChunk, batchCount);
                ManagedChangesTracker.IncrementComponentOrderVersion(archetype,
                                                                     chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(archetype);

                if (chunk->ManagedArrayIndex >= 0)
                {
                    // We can just chop-off the end, no need to copy anything
                    if (chunk->Count != indexInChunk + batchCount)
                    {
                        ManagedChangesTracker.CopyManagedObjects(chunk, chunk->Count - batchCount,
                                                                 chunk,
                                                                 indexInChunk, batchCount);
                    }

                    ManagedChangesTracker.ClearManagedObjects(chunk, chunk->Count - batchCount,
                                                              batchCount);
                }

                chunk->Archetype->EntityCount -= batchCount;
                SetChunkCount(chunk, chunk->Count - batchCount);
            }
            else
            {
                var dstArchetypeChunkFilter = new ArchetypeChunkFilter();
                dstArchetypeChunkFilter.Archetype = archetype->SystemStateResidueArchetype;

                if (RequiresBuildingResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype))
                {
                    BuildResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype, chunk->SharedComponentValues, dstArchetypeChunkFilter.SharedComponentValues);
                }

                if (batchCount == chunk->Count)
                {
                    Move(chunk, ref dstArchetypeChunkFilter);
                }
                else
                {
                    Move(new EntityBatchInChunk {
                        Chunk = chunk, StartIndex = indexInChunk, Count = batchCount
                    }, ref dstArchetypeChunkFilter);
                }
            }
        }
Ejemplo n.º 5
0
        void DestroyBatch(Chunk *chunk, int indexInChunk, int batchCount)
        {
            var archetype = chunk->Archetype;

            if (!archetype->SystemStateCleanupNeeded)
            {
                DeallocateDataEntitiesInChunk(chunk, indexInChunk, batchCount);
                ManagedChangesTracker.IncrementComponentOrderVersion(archetype, chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(archetype);
                chunk->Archetype->EntityCount -= batchCount;
                SetChunkCount(chunk, chunk->Count - batchCount);
            }
            else
            {
                var systemStateResidueArchetype = archetype->SystemStateResidueArchetype;
                if (archetype == systemStateResidueArchetype)
                {
                    return;
                }

                var dstArchetypeChunkFilter = new ArchetypeChunkFilter();
                dstArchetypeChunkFilter.Archetype = systemStateResidueArchetype;

                if (RequiresBuildingResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype))
                {
                    BuildResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype, chunk->SharedComponentValues, dstArchetypeChunkFilter.SharedComponentValues);
                }
                else
                {
                    chunk->SharedComponentValues.CopyTo(dstArchetypeChunkFilter.SharedComponentValues, 0, archetype->NumSharedComponents);
                }

                if (batchCount == chunk->Count)
                {
                    Move(chunk, ref dstArchetypeChunkFilter);
                }
                else
                {
                    Move(new EntityBatchInChunk {
                        Chunk = chunk, StartIndex = indexInChunk, Count = batchCount
                    }, ref dstArchetypeChunkFilter);
                }
            }
        }
        // ----------------------------------------------------------------------------------------------------------
        // PUBLIC
        // ----------------------------------------------------------------------------------------------------------

        public void AddExistingChunk(Chunk *chunk, int *sharedComponentIndices)
        {
            var archetype = chunk->Archetype;

            archetype->AddToChunkList(chunk, sharedComponentIndices, GlobalSystemVersion);
            archetype->EntityCount += chunk->Count;

            for (var i = 0; i < archetype->NumSharedComponents; ++i)
            {
                ManagedChangesTracker.AddReference(sharedComponentIndices[i]);
            }

            if (chunk->Count < chunk->Capacity)
            {
                archetype->EmptySlotTrackingAddChunk(chunk);
            }

            AddExistingEntitiesInChunk(chunk);
        }
        public void ReserveManagedObjectArrays(NativeArray <int> indices)
        {
            int available = m_ManagedArrayFreeIndex.Size / UnsafeUtility.SizeOf <int>();

            if (available > indices.Length)
            {
                available = indices.Length;
            }

            m_ManagedArrayFreeIndex.Pop(indices.GetUnsafePtr(), available * UnsafeUtility.SizeOf <int>());

            int remainder = indices.Length - available;

            if (remainder > 0)
            {
                for (int i = available; i < indices.Length; ++i)
                {
                    indices[i] = m_ManagedArrayIndex + i - available;
                }

                m_ManagedArrayIndex += remainder;
                ManagedChangesTracker.ReserveManagedArrayStorage(remainder);
            }
        }
        void InstantiateEntitiesGroup(Entity *srcEntities, int srcEntityCount,
                                      Entity *outputRootEntities, int instanceCount)
        {
            int totalCount = srcEntityCount * instanceCount;

            var tempAllocSize = sizeof(EntityRemapUtility.SparseEntityRemapInfo) * totalCount +
                                sizeof(InstantiateRemapChunk) * totalCount + sizeof(Entity) * instanceCount;
            byte *    allocation;
            const int kMaxStackAllocSize = 16 * 1024;

            if (tempAllocSize > kMaxStackAllocSize)
            {
                allocation = (byte *)UnsafeUtility.Malloc(tempAllocSize, 16, Allocator.Temp);
            }
            else
            {
                var temp = stackalloc byte[tempAllocSize];

                allocation = temp;
            }

            var entityRemap    = (EntityRemapUtility.SparseEntityRemapInfo *)allocation;
            var remapChunks    = (InstantiateRemapChunk *)(entityRemap + totalCount);
            var outputEntities = (Entity *)(remapChunks + totalCount);

            var remapChunksCount = 0;

            for (int i = 0; i != srcEntityCount; i++)
            {
                var srcEntity = srcEntities[i];

                remapChunksCount = InstantiateEntitiesOne(srcEntity,
                                                          outputEntities, instanceCount, remapChunks, remapChunksCount);

                for (int r = 0; r != instanceCount; r++)
                {
                    var ptr = entityRemap + (r * srcEntityCount + i);
                    ptr->Src    = srcEntity;
                    ptr->Target = outputEntities[r];
                }

                if (i == 0)
                {
                    for (int r = 0; r != instanceCount; r++)
                    {
                        outputRootEntities[r] = outputEntities[r];
                    }
                }
            }


            for (int i = 0; i != remapChunksCount; i++)
            {
                var chunk              = remapChunks[i].Chunk;
                var dstArchetype       = chunk->Archetype;
                var allocatedCount     = remapChunks[i].AllocatedCount;
                var indexInChunk       = remapChunks[i].IndexInChunk;
                var instanceBeginIndex = remapChunks[i].InstanceBeginIndex;

                var localRemap = entityRemap + instanceBeginIndex * srcEntityCount;

                EntityRemapUtility.PatchEntitiesForPrefab(dstArchetype->ScalarEntityPatches + 1, dstArchetype->ScalarEntityPatchCount - 1,
                                                          dstArchetype->BufferEntityPatches, dstArchetype->BufferEntityPatchCount,
                                                          chunk->Buffer, indexInChunk, allocatedCount, localRemap, srcEntityCount);

                ManagedChangesTracker.PatchEntitiesForPrefab(dstArchetype, chunk, indexInChunk, allocatedCount, localRemap, srcEntityCount, Allocator.Temp);
            }

            if (tempAllocSize > kMaxStackAllocSize)
            {
                UnsafeUtility.Free(allocation, Allocator.Temp);
            }
        }
        int InstantiateEntitiesOne(Entity srcEntity, Entity *outputEntities, int instanceCount, InstantiateRemapChunk *remapChunks, int remapChunksCount)
        {
            var src          = GetEntityInChunk(srcEntity);
            var srcArchetype = src.Chunk->Archetype;
            var dstArchetype = srcArchetype->InstantiableArchetype;

            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = dstArchetype;

            if (RequiresBuildingResidueSharedComponentIndices(srcArchetype, dstArchetype))
            {
                BuildResidueSharedComponentIndices(srcArchetype, dstArchetype, src.Chunk->SharedComponentValues, archetypeChunkFilter.SharedComponentValues);
            }
            else
            {
                // Always copy shared component indices since GetChunkWithEmptySlots might reallocate the storage of SharedComponentValues
                src.Chunk->SharedComponentValues.CopyTo(archetypeChunkFilter.SharedComponentValues, 0, dstArchetype->NumSharedComponents);
            }

            Chunk *chunk = null;

            int instanceBeginIndex = 0;

            while (instanceBeginIndex != instanceCount)
            {
                chunk = GetChunkWithEmptySlots(ref archetypeChunkFilter);

                int indexInChunk;
                var allocatedCount = AllocateIntoChunk(chunk, instanceCount - instanceBeginIndex, out indexInChunk);

                ChunkDataUtility.ReplicateComponents(src.Chunk, src.IndexInChunk, chunk, indexInChunk, allocatedCount);
                AllocateEntities(dstArchetype, chunk, indexInChunk, allocatedCount,
                                 outputEntities + instanceBeginIndex);

                if (srcArchetype->NumManagedArrays > 0)
                {
                    ManagedChangesTracker.ReplicateManagedObjects(src.Chunk, src.IndexInChunk, chunk, indexInChunk, allocatedCount, srcEntity, outputEntities + instanceBeginIndex);
                }

                chunk->SetAllChangeVersions(GlobalSystemVersion);

#if UNITY_EDITOR
                for (var i = 0; i < allocatedCount; ++i)
                {
                    CopyName(outputEntities[i + instanceBeginIndex], srcEntity);
                }
#endif

                if (remapChunks != null)
                {
                    remapChunks[remapChunksCount].Chunk              = chunk;
                    remapChunks[remapChunksCount].IndexInChunk       = indexInChunk;
                    remapChunks[remapChunksCount].AllocatedCount     = allocatedCount;
                    remapChunks[remapChunksCount].InstanceBeginIndex = instanceBeginIndex;
                    remapChunksCount++;
                }


                instanceBeginIndex += allocatedCount;
            }

            if (chunk != null)
            {
                ManagedChangesTracker.IncrementComponentOrderVersion(dstArchetype,
                                                                     chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(dstArchetype);
            }

            return(remapChunksCount);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Fix-up the chunk to refer to a different (but layout compatible) archetype.
        /// - Should only be called by Move(chunk)
        /// </summary>
        void ChangeArchetypeInPlace(Chunk *srcChunk, ref ArchetypeChunkFilter dstArchetypeChunkFilter)
        {
            var dstArchetype = dstArchetypeChunkFilter.Archetype;

            fixed(int *sharedComponentValues = dstArchetypeChunkFilter.SharedComponentValues)
            {
                var srcArchetype = srcChunk->Archetype;

                ChunkDataUtility.AssertAreLayoutCompatible(srcArchetype, dstArchetype);

                var fixupSharedComponentReferences = (srcArchetype->NumSharedComponents > 0) || (dstArchetype->NumSharedComponents > 0);

                if (fixupSharedComponentReferences)
                {
                    int srcFirstShared = srcArchetype->FirstSharedComponent;
                    int dstFirstShared = dstArchetype->FirstSharedComponent;
                    int srcCount       = srcArchetype->NumSharedComponents;
                    int dstCount       = dstArchetype->NumSharedComponents;

                    int o = 0;
                    int n = 0;

                    for (; n < dstCount && o < srcCount;)
                    {
                        int srcType = srcArchetype->Types[o + srcFirstShared].TypeIndex;
                        int dstType = dstArchetype->Types[n + dstFirstShared].TypeIndex;
                        if (srcType == dstType)
                        {
                            var srcSharedComponentDataIndex = srcChunk->SharedComponentValues[o];
                            var dstSharedComponentDataIndex = sharedComponentValues[n];
                            if (srcSharedComponentDataIndex != dstSharedComponentDataIndex)
                            {
                                ManagedChangesTracker.RemoveReference(srcSharedComponentDataIndex);
                                ManagedChangesTracker.AddReference(dstSharedComponentDataIndex);
                            }

                            n++;
                            o++;
                        }
                        else if (dstType > srcType) // removed from dstArchetype
                        {
                            var sharedComponentDataIndex = srcChunk->SharedComponentValues[o];
                            ManagedChangesTracker.RemoveReference(sharedComponentDataIndex);
                            o++;
                        }
                        else // added to dstArchetype
                        {
                            var sharedComponentDataIndex = sharedComponentValues[n];
                            ManagedChangesTracker.AddReference(sharedComponentDataIndex);
                            n++;
                        }
                    }

                    for (; n < dstCount; n++) // added to dstArchetype
                    {
                        var sharedComponentDataIndex = sharedComponentValues[n];
                        ManagedChangesTracker.AddReference(sharedComponentDataIndex);
                    }

                    for (; o < srcCount; o++) // removed from dstArchetype
                    {
                        var sharedComponentDataIndex = srcChunk->SharedComponentValues[o];
                        ManagedChangesTracker.RemoveReference(sharedComponentDataIndex);
                    }
                }

                var fixupManagedComponents = (srcArchetype->NumManagedArrays > 0) || (dstArchetype->NumManagedArrays > 0);

                if (fixupManagedComponents)
                {
                    if (dstArchetype->NumManagedArrays == 0) // removed all
                    {
                        ManagedChangesTracker.DeallocateManagedArrayStorage(srcChunk->ManagedArrayIndex);
                        m_ManagedArrayFreeIndex.Add(srcChunk->ManagedArrayIndex);
                        srcChunk->ManagedArrayIndex = -1;
                    }
                    else
                    {
                        // We have changed the managed array order + size so allocate a new managed array
                        // copy the unchanged values into it
                        int dstManagedArrayIndex;
                        if (!m_ManagedArrayFreeIndex.IsEmpty)
                        {
                            dstManagedArrayIndex = m_ManagedArrayFreeIndex.Pop <int>();
                        }
                        else
                        {
                            dstManagedArrayIndex = m_ManagedArrayIndex;
                            m_ManagedArrayIndex++;
                        }

                        ManagedChangesTracker.AllocateManagedArrayStorage(dstManagedArrayIndex, dstArchetype->NumManagedArrays * srcChunk->Capacity);

                        int srcManagedArrayIndex = srcChunk->ManagedArrayIndex;
                        srcChunk->ManagedArrayIndex = dstManagedArrayIndex;

                        if (srcManagedArrayIndex != -1)
                        {
                            ManagedChangesTracker.MoveChunksManagedObjects(srcArchetype, srcManagedArrayIndex, dstArchetype, dstManagedArrayIndex, srcChunk->Capacity, srcChunk->Count);

                            ManagedChangesTracker.DeallocateManagedArrayStorage(srcManagedArrayIndex);
                            m_ManagedArrayFreeIndex.Add(srcManagedArrayIndex);
                        }
                    }
                }

                var  count         = srcChunk->Count;
                bool hasEmptySlots = count < srcChunk->Capacity;

                if (hasEmptySlots)
                {
                    srcArchetype->EmptySlotTrackingRemoveChunk(srcChunk);
                }

                int chunkIndexInSrcArchetype = srcChunk->ListIndex;

                var dstTypes = dstArchetype->Types;
                var srcTypes = srcArchetype->Types;

                //Change version is overriden below
                dstArchetype->AddToChunkList(srcChunk, sharedComponentValues, 0);
                int chunkIndexInDstArchetype = srcChunk->ListIndex;

                //Copy change versions from src to dst archetype
                for (int isrcType = srcArchetype->TypesCount - 1, idstType = dstArchetype->TypesCount - 1;
                     idstType >= 0;
                     --idstType)
                {
                    var dstType = dstTypes[idstType];
                    while (srcTypes[isrcType] > dstType)
                    {
                        --isrcType;
                    }
                    var version = srcTypes[isrcType] == dstType
                        ? srcArchetype->Chunks.GetChangeVersion(isrcType, chunkIndexInSrcArchetype)
                        : GlobalSystemVersion;

                    dstArchetype->Chunks.SetChangeVersion(idstType, chunkIndexInDstArchetype, version);
                }

                srcChunk->ListIndex = chunkIndexInSrcArchetype;
                srcArchetype->RemoveFromChunkList(srcChunk);
                srcChunk->ListIndex = chunkIndexInDstArchetype;

                if (hasEmptySlots)
                {
                    dstArchetype->EmptySlotTrackingAddChunk(srcChunk);
                }

                SetArchetype(srcChunk, dstArchetype);

                srcArchetype->EntityCount -= count;
                dstArchetype->EntityCount += count;

                if (srcArchetype->MetaChunkArchetype != dstArchetype->MetaChunkArchetype)
                {
                    if (srcArchetype->MetaChunkArchetype == null)
                    {
                        CreateMetaEntityForChunk(srcChunk);
                    }
                    else if (dstArchetype->MetaChunkArchetype == null)
                    {
                        DestroyMetaChunkEntity(srcChunk->metaChunkEntity);
                        srcChunk->metaChunkEntity = Entity.Null;
                    }
                    else
                    {
                        var metaChunk            = GetChunk(srcChunk->metaChunkEntity);
                        var archetypeChunkFilter = new ArchetypeChunkFilter(dstArchetype->MetaChunkArchetype, metaChunk->SharedComponentValues);
                        Move(srcChunk->metaChunkEntity, ref archetypeChunkFilter);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        // ----------------------------------------------------------------------------------------------------------
        // Core, self-contained functions to change chunks. No other functions should actually move data from
        // one Chunk to another, or otherwise change the structure of a Chunk after creation.
        // ----------------------------------------------------------------------------------------------------------

        /// <summary>
        /// Move subset of chunk data into another chunk.
        /// - Chunks can be of same archetype (but differ by shared component values)
        /// - Returns number moved. Caller handles if less than indicated in srcBatch.
        /// </summary>
        /// <returns></returns>
        int Move(EntityBatchInChunk srcBatch, Chunk *dstChunk)
        {
            var srcChunk      = srcBatch.Chunk;
            var srcChunkIndex = srcBatch.StartIndex;
            var srcCount      = srcBatch.Count;
            var srcArchetype  = srcChunk->Archetype;
            var dstArchetype  = dstChunk->Archetype;

            // Note (srcArchetype == dstArchetype) is valid
            // Archetypes can the the same, but chunks still differ because filter is different (e.g. shared component)

            int dstChunkIndex;
            var dstCount = AllocateIntoChunk(dstChunk, srcCount, out dstChunkIndex);

            // If can only move partial batch, move from the end so that remainder of batch isn't affected.
            srcChunkIndex = srcChunkIndex + srcCount - dstCount;

            ChunkDataUtility.Convert(srcChunk, srcChunkIndex, dstChunk, dstChunkIndex, dstCount);

            if (dstChunk->ManagedArrayIndex >= 0 && srcChunk->ManagedArrayIndex >= 0)
            {
                ManagedChangesTracker.CopyManagedObjects(srcChunk, srcChunkIndex, dstChunk, dstChunkIndex, dstCount);
            }

            var dstEntities = (Entity *)ChunkDataUtility.GetComponentDataRO(dstChunk, dstChunkIndex, 0);

            for (int i = 0; i < dstCount; i++)
            {
                var entity = dstEntities[i];

                SetArchetype(entity, dstArchetype);
                SetEntityInChunk(entity, new EntityInChunk {
                    Chunk = dstChunk, IndexInChunk = dstChunkIndex + i
                });
            }

            // Fill in moved component data from the end.
            var srcTailIndex = srcChunkIndex + dstCount;
            var srcTailCount = srcChunk->Count - srcTailIndex;
            var fillCount    = math.min(dstCount, srcTailCount);

            if (fillCount > 0)
            {
                var fillStartIndex = srcChunk->Count - fillCount;

                ChunkDataUtility.Copy(srcChunk, fillStartIndex, srcChunk, srcChunkIndex, fillCount);

                var fillEntities = (Entity *)ChunkDataUtility.GetComponentDataRO(srcChunk, srcChunkIndex, 0);
                for (int i = 0; i < fillCount; i++)
                {
                    var entity = fillEntities[i];
                    SetEntityInChunk(entity, new EntityInChunk {
                        Chunk = srcChunk, IndexInChunk = srcChunkIndex + i
                    });
                }

                if (srcChunk->ManagedArrayIndex >= 0)
                {
                    ManagedChangesTracker.CopyManagedObjects(srcChunk, fillStartIndex, srcChunk, srcChunkIndex, fillCount);
                }
            }

            if (srcChunk->ManagedArrayIndex >= 0)
            {
                ManagedChangesTracker.ClearManagedObjects(srcChunk, srcChunk->Count - dstCount, dstCount);
            }

            srcArchetype->EntityCount -= dstCount;

            dstChunk->SetAllChangeVersions(GlobalSystemVersion);
            srcChunk->SetAllChangeVersions(GlobalSystemVersion);

            ManagedChangesTracker.IncrementComponentOrderVersion(srcArchetype, srcChunk->SharedComponentValues);
            IncrementComponentTypeOrderVersion(srcArchetype);

            ManagedChangesTracker.IncrementComponentOrderVersion(dstArchetype, dstChunk->SharedComponentValues);
            IncrementComponentTypeOrderVersion(dstArchetype);

            SetChunkCount(srcChunk, srcChunk->Count - dstCount);

            // Cannot DestroyEntities unless SystemStateCleanupComplete on the entity chunk.
            if (dstChunk->Archetype->SystemStateCleanupComplete)
            {
                DestroyEntities(dstEntities, dstCount);
            }

            return(dstCount);
        }
Ejemplo n.º 12
0
        void DestroyBatch(Entity *entities, Chunk *chunk, int indexInChunk, int batchCount)
        {
            var archetype = chunk->Archetype;

            if (!archetype->SystemStateCleanupNeeded)
            {
                DeallocateDataEntitiesInChunk(entities, chunk, indexInChunk, batchCount);
                ManagedChangesTracker.IncrementComponentOrderVersion(archetype,
                                                                     chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(archetype);

                if (chunk->ManagedArrayIndex >= 0)
                {
                    // We can just chop-off the end, no need to copy anything
                    if (chunk->Count != indexInChunk + batchCount)
                    {
                        ManagedChangesTracker.CopyManagedObjects(chunk, chunk->Count - batchCount,
                                                                 chunk,
                                                                 indexInChunk, batchCount);
                    }

                    ManagedChangesTracker.ClearManagedObjects(chunk, chunk->Count - batchCount,
                                                              batchCount);
                }

                chunk->Archetype->EntityCount -= batchCount;
                SetChunkCount(chunk, chunk->Count - batchCount);
            }
            else
            {
                var newType = archetype->SystemStateResidueArchetype;

                var sharedComponentValues = chunk->SharedComponentValues;

                if (RequiresBuildingResidueSharedComponentIndices(archetype, newType))
                {
                    var tempAlloc = stackalloc int[newType->NumSharedComponents];
                    BuildResidueSharedComponentIndices(archetype, newType, sharedComponentValues, tempAlloc);
                    sharedComponentValues = tempAlloc;
                }

                // See: https://github.com/Unity-Technologies/dots/issues/1387
                // For Locked Order Chunks specfically, need to make sure that structural changes are always done per-chunk.
                // If trying to muutate structure in a way that is not per chunk, will hit an exception in the else clause anyway.
                // This ultimately needs to be replaced by entity batch interface.

                if (batchCount == chunk->Count)
                {
                    ManagedChangesTracker.IncrementComponentOrderVersion(archetype,
                                                                         chunk->SharedComponentValues);
                    IncrementComponentTypeOrderVersion(archetype);

                    SetArchetype(chunk, newType, sharedComponentValues);
                }
                else
                {
                    for (var i = 0; i < batchCount; i++)
                    {
                        var entity = entities[i];
                        ManagedChangesTracker.IncrementComponentOrderVersion(archetype, GetChunk(entity)->SharedComponentValues);
                        IncrementComponentTypeOrderVersion(archetype);
                        SetArchetype(entity, newType, sharedComponentValues);
                    }
                }
            }
        }