public void Execute(int index)
            {
                var srcChunk = SrcChunks[index].m_Chunk;
                var dstChunk = DstChunks[index].m_Chunk;

                var srcArchetype = srcChunk->Archetype;
                var dstArchetype = dstChunk->Archetype;

                ChunkDataUtility.CloneChangeVersions(srcArchetype, srcChunk->ListIndex, dstArchetype, dstChunk->ListIndex);

                DstEntityComponentStore->AddExistingEntitiesInChunk(dstChunk);
            }
Exemple #2
0
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int entityOffset)
        {
            var archetype        = chunk.Archetype.Archetype;
            var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, TypeIndex);
            var typeOffset       = archetype->Offsets[indexInTypeArray];
            var typeSize         = archetype->SizeOfs[indexInTypeArray];

            var dst      = chunk.m_Chunk->Buffer + typeOffset;
            var src      = ComponentData + (entityOffset * typeSize);
            var copySize = typeSize * chunk.Count;

            UnsafeUtility.MemCpy(dst, src, copySize);
        }
Exemple #3
0
            public unsafe void Execute(int index)
            {
                var chunk     = Chunks[index].m_Chunk;
                var archetype = chunk->Archetype;
                var entities  = (Entity *)(ChunkUtility.GetBuffer(chunk) + archetype->Offsets[0]);
                var componentTypeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(archetype, ComponentTypeIndex);
                var componentBuffer = (TComponentData *)(ChunkUtility.GetBuffer(chunk) + archetype->Offsets[componentTypeIndexInArchetype]);

                for (var i = 0; i < chunk->Count; ++i)
                {
                    ComponentDataToEntity.Add(componentBuffer[i], entities[i]);
                }
            }
Exemple #4
0
        public Chunk *GetCleanChunk(Archetype *archetype, SharedComponentValues sharedComponentValues)
        {
            var newChunk = AllocateChunk();

            ChunkDataUtility.AddEmptyChunk(archetype, newChunk, sharedComponentValues);

            if (archetype->MetaChunkArchetype != null)
            {
                CreateMetaEntityForChunk(newChunk);
            }

            return(newChunk);
        }
Exemple #5
0
        ArchetypeChunkFilter GetArchetypeChunkFilterWithChangedSharedComponent(Chunk *srcChunk, ComponentType componentType, int dstSharedComponentIndex)
        {
            var typeIndex        = componentType.TypeIndex;
            var srcArchetype     = srcChunk->Archetype;
            var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(srcArchetype, typeIndex);

            var srcSharedComponentValueArray = srcChunk->SharedComponentValues;
            var sharedComponentOffset        = indexInTypeArray - srcArchetype->FirstSharedComponent;
            var srcSharedComponentIndex      = srcSharedComponentValueArray[sharedComponentOffset];

            if (dstSharedComponentIndex == srcSharedComponentIndex)
            {
                return(default);
        public bool HasChunkComponent <T>(ArchetypeChunkComponentType <T> chunkComponentType)
            where T : struct, IComponentData
        {
            var metaChunkArchetype = m_Chunk->Archetype->MetaChunkArchetype;

            if (metaChunkArchetype == null)
            {
                return(false);
            }
            var typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype->MetaChunkArchetype, chunkComponentType.m_TypeIndex);

            return(typeIndexInArchetype != -1);
        }
        public void Execute(ArchetypeChunk batchInChunk, int batchIndex, int indexOfFirstEntityInQuery)
        {
            var archetype        = batchInChunk.Archetype.Archetype;
            var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, TypeIndex);
            var typeOffset       = archetype->Offsets[indexInTypeArray];
            var typeSize         = archetype->SizeOfs[indexInTypeArray];

            var dst      = batchInChunk.m_Chunk->Buffer + typeOffset;
            var src      = ComponentData + (indexOfFirstEntityInQuery * typeSize);
            var copySize = typeSize * batchInChunk.Count;

            UnsafeUtility.MemCpy(dst, src, copySize);
        }
Exemple #8
0
        /// <summary>
        /// Returns a version number that increases whenever read-write access to the given
        /// component is requested from this chunk, or 0 if the component doesn't exist in the chunk.
        /// </summary>
        /// <param name="chunkComponentType"></param>
        /// <typeparam name="ArchetypeChunkComponentTypeDynamic"></typeparam>
        /// <returns>Current version number of the given component</returns>
        public uint GetChangeVersion(ArchetypeChunkComponentTypeDynamic chunkComponentType)
        {
            int cache = chunkComponentType.m_TypeLookupCache;

            ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype, chunkComponentType.m_TypeIndex, ref cache);
            chunkComponentType.m_TypeLookupCache = (short)cache;
            int typeIndexInArchetype = cache;

            if (typeIndexInArchetype == -1)
            {
                return(0);
            }
            return(m_Chunk->GetChangeVersion(typeIndexInArchetype));
        }
Exemple #9
0
        public void AssertCanAddChunkComponent(NativeArray <ArchetypeChunk> chunkArray, ComponentType componentType)
        {
            var chunks = (ArchetypeChunk *)chunkArray.GetUnsafeReadOnlyPtr();

            for (int i = 0; i < chunkArray.Length; ++i)
            {
                var chunk = chunks[i].m_Chunk;
                if (ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, componentType.TypeIndex) != -1)
                {
                    throw new ArgumentException(
                              $"A chunk component with type:{componentType} has already been added to the chunk.");
                }
            }
        }
Exemple #10
0
        static void DestroyChunkForDiffing(EntityManager entityManager, Chunk *chunk)
        {
            var count = chunk->Count;

            ChunkDataUtility.DeallocateBuffers(chunk);
            entityManager.EntityComponentStore->DeallocateManagedComponents(chunk, 0, count);

            chunk->Archetype->EntityCount -= chunk->Count;
            entityManager.EntityComponentStore->FreeEntities(chunk);

            entityManager.EntityComponentStore->SetChunkCountKeepMetaChunk(chunk, 0);

            entityManager.ManagedComponentStore.Playback(ref entityManager.EntityComponentStore->ManagedChangesTracker);
        }
Exemple #11
0
        /// <summary>
        /// Reports whether any of IBufferElementData components of the type T, in the chunk containing the
        /// specified <see cref="Entity"/>, could have changed.
        /// </summary>
        /// <remarks>
        /// Note that for efficiency, the change version applies to whole chunks not individual entities. The change
        /// version is incremented even when another job or system that has declared write access to a component does
        /// not actually change the component value.</remarks>
        /// <param name="entity">The entity.</param>
        /// <param name="version">The version to compare. In a system, this parameter should be set to the
        /// current <see cref="Unity.Entities.ComponentSystemBase.LastSystemVersion"/> at the time the job is run or
        /// scheduled.</param>
        /// <returns>True, if the version number stored in the chunk for this component is more recent than the version
        /// passed to the <paramref name="version"/> parameter.</returns>
        public bool DidChange(Entity entity, uint version)
        {
            var chunk = m_EntityComponentStore->GetChunk(entity);

            var typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, m_TypeIndex);

            if (typeIndexInArchetype == -1)
            {
                return(false);
            }
            var chunkVersion = chunk->GetChangeVersion(typeIndexInArchetype);

            return(ChangeVersionUtility.DidChange(chunkVersion, version));
        }
        public void CheckCanAddChunkComponent(NativeArray <ArchetypeChunk> chunkArray, ComponentType componentType, ref bool result)
        {
            var chunks = (ArchetypeChunk *)chunkArray.GetUnsafeReadOnlyPtr();

            for (int i = 0; i < chunkArray.Length; ++i)
            {
                var chunk = chunks[i].m_Chunk;
                if (ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, componentType.TypeIndex) != -1)
                {
                    result = false;
                    return;
                }
            }
        }
        public unsafe uint GetComponentVersion <T>(ArchetypeChunkComponentType <T> chunkComponentType) where T : struct, IComponentData
        {
            uint num2;
            int  indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(this.m_Chunk.Archetype, chunkComponentType.m_TypeIndex);

            if (indexInTypeArray == -1)
            {
                num2 = 0;
            }
            else
            {
                num2 = this.m_Chunk.ChangeVersion[indexInTypeArray];
            }
            return(num2);
        }
Exemple #14
0
        public void CreateEntities(ArchetypeManager archetypeManager, Archetype *archetype, Entity *entities, int count)
        {
            while (count != 0)
            {
                var chunk = archetypeManager.GetChunkWithEmptySlots(archetype, null);
                int allocatedIndex;
                var allocatedCount = archetypeManager.AllocateIntoChunk(chunk, count, out allocatedIndex);
                AllocateEntities(archetype, chunk, allocatedIndex, allocatedCount, entities);
                ChunkDataUtility.ClearComponents(chunk, allocatedIndex, allocatedCount);

                entities += allocatedCount;
                count    -= allocatedCount;
            }

            IncrementComponentTypeOrderVersion(archetype);
        }
        public int GetSharedComponentIndex <T>(ArchetypeChunkSharedComponentType <T> chunkSharedComponentData)
            where T : struct, ISharedComponentData
        {
            var archetype            = m_Chunk->Archetype;
            var typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(archetype, chunkSharedComponentData.m_TypeIndex);

            if (typeIndexInArchetype == -1)
            {
                return(-1);
            }

            var chunkSharedComponentIndex = typeIndexInArchetype - archetype->FirstSharedComponent;
            var sharedComponentIndex      = m_Chunk->GetSharedComponentValue(chunkSharedComponentIndex);

            return(sharedComponentIndex);
        }
Exemple #16
0
            public object GetComponentBoxed(Entity entity, Type type)
            {
                m_Manager.EntityComponentStore->AssertEntitiesExist(&entity, 1);

                var archetype = m_Manager.m_EntityComponentStore->GetArchetype(entity);
                var typeIndex = ChunkDataUtility.GetTypeIndexFromType(archetype, type);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (typeIndex == -1)
                {
                    throw new ArgumentException($"A component with type:{type} has not been added to the entity.");
                }
#endif

                return(GetComponentBoxed(entity, ComponentType.FromTypeIndex(typeIndex)));
            }
        public ArchetypeChunkComponentObjects <T> GetComponentObjects <T>(ArchetypeChunkComponentType <T> componentType, EntityManager manager)
            where T : class
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckReadAndThrow(componentType.m_Safety);
#endif
            var archetype = m_Chunk->Archetype;

            var typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(archetype, componentType.m_TypeIndex);

            int offset, length;
            var array = manager.ArchetypeManager.GetManagedObjectRange(m_Chunk, typeIndexInArchetype, out offset, out length);

            var componentArray = new ArchetypeChunkComponentObjects <T>(offset, length, array);
            return(componentArray);
        }
        public void GetCacheForType(int componentType, out ComponentChunkCache cache, out int typeIndexInArchetype)
        {
            var archetype = m_CurrentMatchingArchetype->Archetype;

            typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(archetype, componentType);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (typeIndexInArchetype == -1)
            {
                throw new System.ArgumentException("componentType does not exist in the iterated archetype");
            }
#endif

            cache.CachedBeginIndex = m_CurrentChunkIndex + m_CurrentArchetypeIndex;
            cache.CachedEndIndex   = cache.CachedBeginIndex + m_CurrentChunk->Count;
            cache.CachedSizeOf     = archetype->SizeOfs[typeIndexInArchetype];
            cache.CachedPtr        = m_CurrentChunk->Buffer + archetype->Offsets[typeIndexInArchetype] - cache.CachedBeginIndex * cache.CachedSizeOf;
        }
Exemple #19
0
        public void AssertCanRemoveComponent(NativeArray <ArchetypeChunk> chunkArray, ComponentType componentType)
        {
            var chunks = (ArchetypeChunk *)chunkArray.GetUnsafeReadOnlyPtr();

            for (int i = 0; i < chunkArray.Length; ++i)
            {
                var chunk = chunks[i].m_Chunk;
                if (ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, componentType.TypeIndex) != -1)
                {
                    if (chunk->Locked)
                    {
                        throw new InvalidOperationException(
                                  "Cannot remove components from locked Chunks. Unlock Chunk first.");
                    }
                }
            }
        }
Exemple #20
0
        // ----------------------------------------------------------------------------------------------------------
        // PUBLIC
        // ----------------------------------------------------------------------------------------------------------

        public void CreateEntities(Archetype *archetype, Entity *entities, int count)
        {
            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = archetype;

            while (count != 0)
            {
                var chunk         = GetChunkWithEmptySlots(ref archetypeChunkFilter);
                var allocateCount = math.min(count, chunk->UnusedCount);

                ChunkDataUtility.Allocate(chunk, entities, allocateCount);

                entities += allocateCount;
                count    -= allocateCount;
            }
        }
        public unsafe int GetSharedComponentIndex <T>(ArchetypeChunkSharedComponentType <T> chunkSharedComponentData) where T : struct, ISharedComponentData
        {
            int num4;

            Unity.Entities.Archetype *archetype = this.m_Chunk.Archetype;
            int indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, chunkSharedComponentData.m_TypeIndex);

            if (indexInTypeArray == -1)
            {
                num4 = -1;
            }
            else
            {
                int index = archetype->SharedComponentOffset[indexInTypeArray];
                num4 = this.m_Chunk.SharedComponentValueArray[index];
            }
            return(num4);
        }
Exemple #22
0
        static void DestroyChunkForDiffing(EntityManager entityManager, Chunk *chunk)
        {
            var access = entityManager.GetCheckedEntityDataAccess();
            var ecs    = access->EntityComponentStore;
            var mcs    = access->ManagedComponentStore;

            var count = chunk->Count;

            ChunkDataUtility.DeallocateBuffers(chunk);
            ecs->DeallocateManagedComponents(chunk, 0, count);

            chunk->Archetype->EntityCount -= chunk->Count;
            ecs->FreeEntities(chunk);

            ChunkDataUtility.SetChunkCountKeepMetaChunk(chunk, 0);

            mcs.Playback(ref ecs->ManagedChangesTracker);
        }
Exemple #23
0
            public void Execute()
            {
                var access = EntityManager.GetCheckedEntityDataAccess();
                var ecs    = access->EntityComponentStore;

                for (var i = 0; i < Chunks.Length; i++)
                {
                    var chunk = Chunks[i].m_Chunk;
                    var count = chunk->Count;
                    ChunkDataUtility.DeallocateBuffers(chunk);
                    ecs->DeallocateManagedComponents(chunk, 0, count);

                    chunk->Archetype->EntityCount -= chunk->Count;
                    ecs->FreeEntities(chunk);

                    ChunkDataUtility.SetChunkCountKeepMetaChunk(chunk, 0);
                }
            }
Exemple #24
0
        public void SetArchetype(ArchetypeManager typeMan, Entity entity, Archetype *archetype,
                                 int *sharedComponentDataIndices)
        {
            var chunk      = typeMan.GetChunkWithEmptySlots(archetype, sharedComponentDataIndices);
            var chunkIndex = typeMan.AllocateIntoChunk(chunk);

            var oldArchetype  = m_Entities[entity.Index].Archetype;
            var oldChunk      = m_Entities[entity.Index].Chunk;
            var oldChunkIndex = m_Entities[entity.Index].IndexInChunk;

            ChunkDataUtility.Convert(oldChunk, oldChunkIndex, chunk, chunkIndex);
            if (chunk->ManagedArrayIndex >= 0 && oldChunk->ManagedArrayIndex >= 0)
            {
                ChunkDataUtility.CopyManagedObjects(typeMan, oldChunk, oldChunkIndex, chunk, chunkIndex, 1);
            }

            m_Entities[entity.Index].Archetype    = archetype;
            m_Entities[entity.Index].Chunk        = chunk;
            m_Entities[entity.Index].IndexInChunk = chunkIndex;

            var lastIndex = oldChunk->Count - 1;

            // No need to replace with ourselves
            if (lastIndex != oldChunkIndex)
            {
                var lastEntity = (Entity *)ChunkDataUtility.GetComponentData(oldChunk, lastIndex, 0);
                m_Entities[lastEntity->Index].IndexInChunk = oldChunkIndex;

                ChunkDataUtility.Copy(oldChunk, lastIndex, oldChunk, oldChunkIndex, 1);
                if (oldChunk->ManagedArrayIndex >= 0)
                {
                    ChunkDataUtility.CopyManagedObjects(typeMan, oldChunk, lastIndex, oldChunk, oldChunkIndex, 1);
                }
            }

            if (oldChunk->ManagedArrayIndex >= 0)
            {
                ChunkDataUtility.ClearManagedObjects(typeMan, oldChunk, lastIndex, 1);
            }

            --oldArchetype->EntityCount;
            typeMan.SetChunkCount(oldChunk, lastIndex);
        }
Exemple #25
0
        internal void DeallocateDataEntitiesInChunk(Chunk *chunk, int indexInChunk, int batchCount)
        {
            DeallocateBuffers(chunk, indexInChunk, batchCount);
            DeallocateManagedComponents(chunk, indexInChunk, batchCount);

            var freeIndex = m_NextFreeEntityIndex;
            var entities  = (Entity *)chunk->Buffer + indexInChunk;

            for (var i = batchCount - 1; i >= 0; --i)
            {
                var entityIndex = entities[i].Index;

                m_EntityInChunkByEntity[entityIndex].Chunk = null;
                m_VersionByEntity[entityIndex]++;
                m_EntityInChunkByEntity[entityIndex].IndexInChunk = freeIndex;
#if UNITY_EDITOR
                m_NameByEntity[entityIndex] = new NumberedWords();
#endif
                freeIndex = entityIndex;
            }

            m_NextFreeEntityIndex = freeIndex;
            m_EntityCreateDestroyVersion++;

            // Compute the number of things that need to moved and patched.
            int patchCount = Math.Min(batchCount, chunk->Count - indexInChunk - batchCount);

            if (0 == patchCount)
            {
                return;
            }

            // updates indexInChunk to point to where the components will be moved to
            //Assert.IsTrue(chunk->archetype->sizeOfs[0] == sizeof(Entity) && chunk->archetype->offsets[0] == 0);
            var movedEntities = (Entity *)chunk->Buffer + (chunk->Count - patchCount);
            for (var i = 0; i != patchCount; i++)
            {
                m_EntityInChunkByEntity[movedEntities[i].Index].IndexInChunk = indexInChunk + i;
            }

            // Move component data from the end to where we deleted components
            ChunkDataUtility.Copy(chunk, chunk->Count - patchCount, chunk, indexInChunk, patchCount);
        }
Exemple #26
0
        public void CreateEntities(ArchetypeManager archetypeManager, Archetype *archetype, Entity *entities, int count)
        {
            int *sharedComponentDataIndices = stackalloc int[archetype->NumSharedComponents];

            UnsafeUtility.MemClear(sharedComponentDataIndices, archetype->NumSharedComponents * sizeof(int));

            while (count != 0)
            {
                var chunk = archetypeManager.GetChunkWithEmptySlots(archetype, sharedComponentDataIndices);
                int allocatedIndex;
                var allocatedCount = archetypeManager.AllocateIntoChunk(chunk, count, out allocatedIndex);
                AllocateEntities(archetype, chunk, allocatedIndex, allocatedCount, entities);
                ChunkDataUtility.InitializeComponents(chunk, allocatedIndex, allocatedCount);

                entities += allocatedCount;
                count    -= allocatedCount;
            }

            IncrementComponentTypeOrderVersion(archetype);
        }
Exemple #27
0
        public void DeallocateEnties(ArchetypeManager typeMan, SharedComponentDataManager sharedComponentDataManager, Entity *entities, int count)
        {
            while (count != 0)
            {
                int    indexInChunk;
                int    batchCount;
                Chunk *chunk;

                //Profiler.BeginSample("DeallocateDataEntitiesInChunk");
                fixed(EntityDataManager *manager = &this)
                {
#if USE_BURST_DESTROY
                    chunk = ms_DeallocateDataEntitiesInChunkDelegate(manager, entities, count, out indexInChunk, out batchCount);
#else
                    chunk = DeallocateDataEntitiesInChunk(manager, entities, count, out indexInChunk, out batchCount);
#endif
                }

                //Profiler.EndSample();

                IncrementComponentOrderVersion(chunk->Archetype, chunk, sharedComponentDataManager);

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

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

                chunk->Archetype->EntityCount -= batchCount;
                typeMan.SetChunkCount(chunk, chunk->Count - batchCount);

                entities += batchCount;
                count    -= batchCount;
            }
        }
Exemple #28
0
        public void MoveEntityToChunk(ArchetypeManager typeMan, Entity entity, Chunk *newChunk, int newChunkIndex)
        {
            var oldChunk = m_Entities[entity.Index].Chunk;

            Assert.IsTrue(oldChunk->Archetype == newChunk->Archetype);

            var oldChunkIndex = m_Entities[entity.Index].IndexInChunk;

            ChunkDataUtility.Copy(oldChunk, oldChunkIndex, newChunk, newChunkIndex, 1);

            if (oldChunk->ManagedArrayIndex >= 0)
            {
                ChunkDataUtility.CopyManagedObjects(typeMan, oldChunk, oldChunkIndex, newChunk, newChunkIndex, 1);
            }

            m_Entities[entity.Index].Chunk        = newChunk;
            m_Entities[entity.Index].IndexInChunk = newChunkIndex;

            var lastIndex = oldChunk->Count - 1;

            // No need to replace with ourselves
            if (lastIndex != oldChunkIndex)
            {
                var lastEntity = (Entity *)ChunkDataUtility.GetComponentData(oldChunk, lastIndex, 0);
                m_Entities[lastEntity->Index].IndexInChunk = oldChunkIndex;

                ChunkDataUtility.Copy(oldChunk, lastIndex, oldChunk, oldChunkIndex, 1);
                if (oldChunk->ManagedArrayIndex >= 0)
                {
                    ChunkDataUtility.CopyManagedObjects(typeMan, oldChunk, lastIndex, oldChunk, oldChunkIndex, 1);
                }
            }

            if (oldChunk->ManagedArrayIndex >= 0)
            {
                ChunkDataUtility.ClearManagedObjects(typeMan, oldChunk, lastIndex, 1);
            }

            newChunk->Archetype->EntityCount--;
            typeMan.SetChunkCount(oldChunk, oldChunk->Count - 1);
        }
Exemple #29
0
        private static void DeallocateDataEntitiesInChunk(EntityDataManager *entityDataManager, Entity *entities,
                                                          Chunk *chunk, int indexInChunk, int batchCount)
        {
            DeallocateBuffers(entityDataManager, entities, chunk, batchCount);

            var freeIndex   = entityDataManager->m_EntitiesFreeIndex;
            var entityDatas = entityDataManager->m_Entities;

            for (var i = batchCount - 1; i >= 0; --i)
            {
                var entityIndex = entities[i].Index;
                var data        = entityDatas + entityIndex;

                data->Chunk = null;
                data->Version++;
                data->IndexInChunk = freeIndex;
                freeIndex          = entityIndex;
            }

            entityDataManager->m_EntitiesFreeIndex = freeIndex;

            // Compute the number of things that need to moved and patched.
            int patchCount = Math.Min(batchCount, chunk->Count - indexInChunk - batchCount);

            if (0 == patchCount)
            {
                return;
            }

            // updates EntitityData->indexInChunk to point to where the components will be moved to
            //Assert.IsTrue(chunk->archetype->sizeOfs[0] == sizeof(Entity) && chunk->archetype->offsets[0] == 0);
            var movedEntities = (Entity *)chunk->Buffer + (chunk->Count - patchCount);

            for (var i = 0; i != patchCount; i++)
            {
                entityDataManager->m_Entities[movedEntities[i].Index].IndexInChunk = indexInChunk + i;
            }

            // Move component data from the end to where we deleted components
            ChunkDataUtility.Copy(chunk, chunk->Count - patchCount, chunk, indexInChunk, patchCount);
        }
        // ----------------------------------------------------------------------------------------------------------
        // PUBLIC
        // ----------------------------------------------------------------------------------------------------------

        public void CreateEntities(Archetype *archetype, Entity *entities, int count)
        {
            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = archetype;

            while (count != 0)
            {
                var chunk = GetChunkWithEmptySlots(ref archetypeChunkFilter);

                int allocatedIndex;
                var allocatedCount = AllocateIntoChunk(chunk, count, out allocatedIndex);
                AllocateEntities(archetype, chunk, allocatedIndex, allocatedCount, entities);
                ChunkDataUtility.InitializeComponents(chunk, allocatedIndex, allocatedCount);
                chunk->SetAllChangeVersions(GlobalSystemVersion);
                entities += allocatedCount;
                count    -= allocatedCount;
            }

            IncrementComponentTypeOrderVersion(archetype);
        }