Esempio n. 1
0
        public static void MoveChunks(ArchetypeManager srcArchetypeManager, EntityDataManager *srcEntityDataManager, SharedComponentDataManager srcSharedComponents, ArchetypeManager dstArchetypeManager, EntityGroupManager dstGroupManager, SharedComponentDataManager dstSharedComponentDataManager, EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents)
        {
            var entitiesArray = new NativeArray <Entity>(Chunk.kMaximumEntitiesPerChunk, Allocator.Temp);
            var entitiesPtr   = (Entity *)entitiesArray.GetUnsafePtr();

            var srcArchetype = srcArchetypeManager.m_LastArchetype;

            while (srcArchetype != null)
            {
                if (srcArchetype->EntityCount != 0)
                {
                    if (srcArchetype->NumManagedArrays != 0)
                    {
                        throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays");
                    }
                    var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(srcArchetype->Types, srcArchetype->TypesCount, dstGroupManager);

                    for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next)
                    {
                        Chunk *chunk = (Chunk *)c;

                        EntityDataManager.FreeDataEntitiesInChunk(srcEntityDataManager, chunk, chunk->Count);
                        dstEntityDataManager->AllocateEntities(dstArchetype, chunk, 0, chunk->Count, entitiesPtr);

                        chunk->Archetype = dstArchetype;

                        if (dstArchetype->NumSharedComponents > 0)
                        {
                            dstSharedComponents.MoveSharedComponents(srcSharedComponents, chunk->SharedComponentValueArray, dstArchetype->NumSharedComponents);
                        }
                    }

                    //@TODO: Patch Entity references in IComponentData...

                    UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkList.End, &srcArchetype->ChunkList);
                    UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkListWithEmptySlots.End, &srcArchetype->ChunkListWithEmptySlots);

                    dstArchetype->EntityCount += srcArchetype->EntityCount;
                    srcArchetype->EntityCount  = 0;
                }

                srcArchetype = srcArchetype->PrevArchetype;
            }
            entitiesArray.Dispose();
        }
Esempio n. 2
0
        public void AddComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager,
                                 SharedComponentDataManager sharedComponentDataManager,
                                 EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);
            var archetype     = GetArchetype(entity);

            var t = 0;

            while (t < archetype->TypesCount && archetype->Types[t] < componentType)
            {
                componentTypeInArchetypeArray[t] = archetype->Types[t];
                ++t;
            }

            var indexInTypeArray = t;

            componentTypeInArchetypeArray[t] = componentType;
            while (t < archetype->TypesCount)
            {
                componentTypeInArchetypeArray[t + 1] = archetype->Types[t];
                ++t;
            }

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount + 1, groupManager);

            int *sharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;

            if ((newType->NumSharedComponents > 0) && (newType->NumSharedComponents != archetype->NumSharedComponents))
            {
                var  oldSharedComponentDataIndices = sharedComponentDataIndices;
                int *stackAlloced = stackalloc int[newType->NumSharedComponents];
                sharedComponentDataIndices = stackAlloced;

                int indexOfNewSharedComponent = newType->SharedComponentOffset[indexInTypeArray];
                UnsafeUtility.MemCpy(sharedComponentDataIndices, oldSharedComponentDataIndices, indexOfNewSharedComponent * sizeof(int));
                sharedComponentDataIndices[indexOfNewSharedComponent] = 0;
                UnsafeUtility.MemCpy(sharedComponentDataIndices + indexOfNewSharedComponent + 1, oldSharedComponentDataIndices + indexOfNewSharedComponent,
                                     (archetype->NumSharedComponents - indexOfNewSharedComponent) * sizeof(int));
            }

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
            IncrementComponentOrderVersion(newType, GetComponentChunk(entity), sharedComponentDataManager);
        }
Esempio n. 3
0
        public void RemoveComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager,
                                    SharedComponentDataManager sharedComponentDataManager,
                                    EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);

            var archetype = GetArchetype(entity);

            var removedTypes        = 0;
            int indexInOldTypeArray = -1;

            for (var t = 0; t < archetype->TypesCount; ++t)
            {
                if (archetype->Types[t].TypeIndex == componentType.TypeIndex)
                {
                    indexInOldTypeArray = t;
                    ++removedTypes;
                }
                else
                {
                    componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t];
                }
            }

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount - removedTypes, groupManager);

            int *sharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;

            if ((newType->NumSharedComponents > 0) && (newType->NumSharedComponents != archetype->NumSharedComponents))
            {
                var  oldSharedComponentDataIndices = sharedComponentDataIndices;
                int *tempAlloc = stackalloc int[newType->NumSharedComponents];
                sharedComponentDataIndices = tempAlloc;

                int indexOfRemovedSharedComponent = archetype->SharedComponentOffset[indexInOldTypeArray];
                UnsafeUtility.MemCpy(sharedComponentDataIndices, oldSharedComponentDataIndices, indexOfRemovedSharedComponent * sizeof(int));
                UnsafeUtility.MemCpy(sharedComponentDataIndices + indexOfRemovedSharedComponent, oldSharedComponentDataIndices + indexOfRemovedSharedComponent + 1, (newType->NumSharedComponents - indexOfRemovedSharedComponent) * sizeof(int));
            }

            IncrementComponentOrderVersion(archetype, GetComponentChunk(entity), sharedComponentDataManager);

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
        }
Esempio n. 4
0
        internal EntityArchetype CreateArchetype(ComponentType *types, int count)
        {
            var cachedComponentCount = PopulatedCachedTypeInArchetypeArray(types, count);

            // Lookup existing archetype (cheap)
            EntityArchetype entityArchetype;

            entityArchetype.Archetype = m_ArchetypeManager.GetExistingArchetype(m_CachedComponentTypeInArchetypeArray, cachedComponentCount);
            if (entityArchetype.Archetype != null)
            {
                return(entityArchetype);
            }

            // Creating an archetype invalidates all iterators / jobs etc
            // because it affects the live iteration linked lists...
            BeforeStructuralChange();

            entityArchetype.Archetype = m_ArchetypeManager.GetOrCreateArchetype(m_CachedComponentTypeInArchetypeArray, cachedComponentCount, m_GroupManager);
            return(entityArchetype);
        }
Esempio n. 5
0
        public void RemoveComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager,
                                    EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);

            var archetype = GetArchetype(entity);

            var removedTypes = 0;

            for (var t = 0; t < archetype->TypesCount; ++t)
            {
                if (archetype->Types[t].TypeIndex == componentType.TypeIndex)
                {
                    ++removedTypes;
                }
                else
                {
                    componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t];
                }
            }

            Assert.AreNotEqual(-1, removedTypes);

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount - removedTypes, groupManager);

            int *sharedComponentDataIndices = null;

            if (newType->NumSharedComponents > 0)
            {
                var oldSharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;
                var removedComponentIsShared      = TypeManager.TypeCategory.ISharedComponentData ==
                                                    TypeManager.GetComponentType(type.TypeIndex).Category;
                removedTypes = 0;
                if (removedComponentIsShared)
                {
                    int *tempAlloc = stackalloc int[newType->NumSharedComponents];
                    sharedComponentDataIndices = tempAlloc;

                    int srcIndex = 0;
                    int dstIndex = 0;
                    for (var t = 0; t < archetype->TypesCount; ++t)
                    {
                        if (archetype->SharedComponentOffset[t] != -1)
                        {
                            if (archetype->Types[t].TypeIndex == componentType.TypeIndex)
                            {
                                srcIndex++;
                            }
                            else
                            {
                                sharedComponentDataIndices[dstIndex] = oldSharedComponentDataIndices[srcIndex];
                                srcIndex++;
                                dstIndex++;
                            }
                        }
                    }
                }
                else
                {
                    // reuse old sharedComponentDataIndices
                    sharedComponentDataIndices = oldSharedComponentDataIndices;
                }
            }

            IncrementComponentOrderVersion(archetype, GetComponentChunk(entity), sharedComponentDataManager);

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
        }
Esempio n. 6
0
        public void AddComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager,
                                 EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);
            var archetype     = GetArchetype(entity);

            var t = 0;

            while (t < archetype->TypesCount && archetype->Types[t] < componentType)
            {
                componentTypeInArchetypeArray[t] = archetype->Types[t];
                ++t;
            }

            componentTypeInArchetypeArray[t] = componentType;
            while (t < archetype->TypesCount)
            {
                componentTypeInArchetypeArray[t + 1] = archetype->Types[t];
                ++t;
            }

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount + 1, groupManager);

            int *sharedComponentDataIndices = null;

            if (newType->NumSharedComponents > 0)
            {
                var oldSharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;
                var newComponentIsShared          = (TypeManager.TypeCategory.ISharedComponentData ==
                                                     TypeManager.GetComponentType(type.TypeIndex).Category);
                if (newComponentIsShared)
                {
                    int *stackAlloced = stackalloc int[newType->NumSharedComponents];
                    sharedComponentDataIndices = stackAlloced;

                    if (archetype->SharedComponentOffset == null)
                    {
                        sharedComponentDataIndices[0] = 0;
                    }
                    else
                    {
                        t = 0;
                        var sharedIndex = 0;
                        while (t < archetype->TypesCount && archetype->Types[t] < componentType)
                        {
                            if (archetype->SharedComponentOffset[t] != -1)
                            {
                                sharedComponentDataIndices[sharedIndex] = oldSharedComponentDataIndices[sharedIndex];
                                ++sharedIndex;
                            }

                            ++t;
                        }

                        sharedComponentDataIndices[sharedIndex] = 0;
                        while (t < archetype->TypesCount)
                        {
                            if (archetype->SharedComponentOffset[t] != -1)
                            {
                                sharedComponentDataIndices[sharedIndex + 1] =
                                    oldSharedComponentDataIndices[sharedIndex];
                                ++sharedIndex;
                            }

                            ++t;
                        }
                    }
                }
                else
                {
                    // reuse old sharedComponentDataIndices
                    sharedComponentDataIndices = oldSharedComponentDataIndices;
                }
            }

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);

            IncrementComponentOrderVersion(newType, GetComponentChunk(entity), sharedComponentDataManager);
        }
        public static void MoveChunks(EntityManager srcEntities, ArchetypeManager dstArchetypeManager,
                                      EntityGroupManager dstGroupManager, EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents)
        {
            var srcArchetypeManager  = srcEntities.ArchetypeManager;
            var srcEntityDataManager = srcEntities.Entities;
            var srcSharedComponents  = srcEntities.m_SharedComponentManager;

            var entityRemapping = new NativeArray <EntityRemapUtility.EntityRemapInfo>(srcEntityDataManager->Capacity, Allocator.Temp);

            dstEntityDataManager->AllocateEntitiesForRemapping(srcEntityDataManager, ref entityRemapping);
            srcEntityDataManager->FreeAllEntities();

            var samplerShared = CustomSampler.Create("MoveAllSharedComponents");

            samplerShared.Begin();
            var remapShared = dstSharedComponents.MoveAllSharedComponents(srcSharedComponents, Allocator.Temp);

            samplerShared.End();

            Archetype *srcArchetype;

            int chunkCount     = 0;
            int archetypeCount = 0;

            srcArchetype = srcArchetypeManager.m_LastArchetype;
            while (srcArchetype != null)
            {
                archetypeCount++;
                chunkCount  += srcArchetype->ChunkCount;
                srcArchetype = srcArchetype->PrevArchetype;
            }

            var remapChunks     = new NativeArray <RemapChunk>(chunkCount, Allocator.Temp);
            var remapArchetypes = new NativeArray <RemapArchetype>(archetypeCount, Allocator.Temp);

            int chunkIndex     = 0;
            int archetypeIndex = 0;

            srcArchetype = srcArchetypeManager.m_LastArchetype;
            while (srcArchetype != null)
            {
                if (srcArchetype->ChunkCount != 0)
                {
                    if (srcArchetype->NumManagedArrays != 0)
                    {
                        throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays");
                    }

                    var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(srcArchetype->Types, srcArchetype->TypesCount, dstGroupManager);

                    remapArchetypes[archetypeIndex] = new RemapArchetype {
                        srcArchetype = srcArchetype, dstArchetype = dstArchetype
                    };

                    for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next)
                    {
                        remapChunks[chunkIndex] = new RemapChunk {
                            chunk = (Chunk *)c, dstArchetype = dstArchetype
                        };
                        chunkIndex++;
                    }

                    archetypeIndex++;

                    dstEntityDataManager->IncrementComponentTypeOrderVersion(dstArchetype);
                }

                srcArchetype = srcArchetype->PrevArchetype;
            }

            for (int j = 0; j < remapChunks.Length; j++)
            {
                ref RemapChunk remapChunk   = ref UnsafeUtilityEx.ArrayElementAsRef <RemapChunk>(remapChunks.GetUnsafePtr(), j);
                ref Chunk *    chunk        = ref remapChunk.chunk;
Esempio n. 8
0
        public static void MoveChunks(EntityManager srcEntities, ArchetypeManager dstArchetypeManager,
                                      EntityGroupManager dstGroupManager, EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var srcArchetypeManager  = srcEntities.ArchetypeManager;
            var srcEntityDataManager = srcEntities.Entities;
            var srcSharedComponents  = srcEntities.m_SharedComponentManager;

            var entityRemapping = new NativeArray <EntityRemapUtility.EntityRemapInfo>(srcEntityDataManager->Capacity, Allocator.TempJob);

            var moveChunksJob = new MoveChunksJob
            {
                srcEntityDataManager = srcEntityDataManager,
                dstEntityDataManager = dstEntityDataManager,
                entityRemapping      = entityRemapping
            }.Schedule();

            JobHandle.ScheduleBatchedJobs();

            var samplerShared = CustomSampler.Create("MoveAllSharedComponents");

            samplerShared.Begin();
            var remapShared = dstSharedComponents.MoveAllSharedComponents(srcSharedComponents, Allocator.TempJob);

            samplerShared.End();

            Archetype *srcArchetype;

            int chunkCount     = 0;
            int archetypeCount = 0;

            srcArchetype = srcArchetypeManager.m_LastArchetype;
            while (srcArchetype != null)
            {
                archetypeCount++;
                chunkCount  += srcArchetype->ChunkCount;
                srcArchetype = srcArchetype->PrevArchetype;
            }

            var remapChunks     = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob);
            var remapArchetypes = new NativeArray <RemapArchetype>(archetypeCount, Allocator.TempJob);

            int chunkIndex     = 0;
            int archetypeIndex = 0;

            srcArchetype = srcArchetypeManager.m_LastArchetype;
            while (srcArchetype != null)
            {
                if (srcArchetype->ChunkCount != 0)
                {
                    if (srcArchetype->NumManagedArrays != 0)
                    {
                        throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays");
                    }

                    // Make copy. GetOrCreateArchetype writes to type array.
                    UnsafeUtility.MemCpy(componentTypeInArchetypeArray, srcArchetype->Types, UnsafeUtility.SizeOf <ComponentTypeInArchetype>() * srcArchetype->TypesCount);

                    var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray, srcArchetype->TypesCount, dstGroupManager);

                    remapArchetypes[archetypeIndex] = new RemapArchetype {
                        srcArchetype = srcArchetype, dstArchetype = dstArchetype
                    };

                    for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next)
                    {
                        remapChunks[chunkIndex] = new RemapChunk {
                            chunk = (Chunk *)c, dstArchetype = dstArchetype
                        };
                        chunkIndex++;
                    }

                    archetypeIndex++;

                    dstEntityDataManager->IncrementComponentTypeOrderVersion(dstArchetype);
                }

                srcArchetype = srcArchetype->PrevArchetype;
            }

            var remapChunksJob = new RemapChunksJob
            {
                dstEntityDataManager = dstEntityDataManager,
                remapChunks          = remapChunks,
                remapShared          = remapShared,
                entityRemapping      = entityRemapping
            }.Schedule(remapChunks.Length, 1, moveChunksJob);

            var remapArchetypesJob = new RemapArchetypesJob
            {
                remapArchetypes = remapArchetypes
            }.Schedule(archetypeIndex, 1, remapChunksJob);

            remapArchetypesJob.Complete();

            entityRemapping.Dispose();
            remapShared.Dispose();
        }
Esempio n. 9
0
        public void TryRemoveEntityId(Entity *entities, int count, ArchetypeManager archetypeManager,
                                      SharedComponentDataManager sharedComponentDataManager,
                                      EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var entityIndex = 0;

            while (entityIndex != count)
            {
                int indexInChunk;
                int batchCount;
                fixed(EntityDataManager *manager = &this)
                {
                    var chunk = EntityChunkBatch(manager, entities + entityIndex, count - entityIndex, out indexInChunk,
                                                 out batchCount);
                    var archetype = GetArchetype(entities[entityIndex]);

                    if (!archetype->SystemStateCleanupNeeded)
                    {
                        DeallocateDataEntitiesInChunk(manager, entities + entityIndex, chunk, indexInChunk, batchCount);
                        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(archetypeManager, chunk, chunk->Count - batchCount,
                                                                    chunk,
                                                                    indexInChunk, batchCount);
                            }

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

                        chunk->Archetype->EntityCount -= batchCount;
                        archetypeManager.SetChunkCount(chunk, chunk->Count - batchCount);
                    }
                    else
                    {
                        for (var batchEntityIndex = 0; batchEntityIndex < batchCount; batchEntityIndex++)
                        {
                            var entity                   = entities[entityIndex + batchEntityIndex];
                            var removedTypes             = 0;
                            var removedComponentIsShared = false;
                            for (var t = 1; t < archetype->TypesCount; ++t)
                            {
                                var type = archetype->Types[t];

                                if (!(type.IsSystemStateComponent || type.IsSystemStateSharedComponent))
                                {
                                    ++removedTypes;
                                    removedComponentIsShared |= type.IsSharedComponent;
                                }
                                else
                                {
                                    componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t];
                                }
                            }

                            componentTypeInArchetypeArray[archetype->TypesCount - removedTypes] =
                                new ComponentTypeInArchetype(ComponentType.Create <CleanupEntity>());

                            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                                archetype->TypesCount - removedTypes + 1, groupManager);

                            int *sharedComponentDataIndices = null;
                            if (newType->NumSharedComponents > 0)
                            {
                                var oldSharedComponentDataIndices =
                                    GetComponentChunk(entity)->SharedComponentValueArray;
                                if (removedComponentIsShared)
                                {
                                    int *tempAlloc = stackalloc int[newType->NumSharedComponents];
                                    sharedComponentDataIndices = tempAlloc;

                                    var srcIndex = 0;
                                    var dstIndex = 0;
                                    for (var t = 0; t < archetype->TypesCount; ++t)
                                    {
                                        if (archetype->SharedComponentOffset[t] != -1)
                                        {
                                            var typeIndex             = archetype->Types[t].TypeIndex;
                                            var systemStateType       = typeof(ISystemStateComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex));
                                            var systemStateSharedType = typeof(ISystemStateSharedComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex));
                                            if (!(systemStateType || systemStateSharedType))
                                            {
                                                srcIndex++;
                                            }
                                            else
                                            {
                                                sharedComponentDataIndices[dstIndex] =
                                                    oldSharedComponentDataIndices[srcIndex];
                                                srcIndex++;
                                                dstIndex++;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // reuse old sharedComponentDataIndices
                                    sharedComponentDataIndices = oldSharedComponentDataIndices;
                                }
                            }

                            IncrementComponentOrderVersion(archetype, GetComponentChunk(entity),
                                                           sharedComponentDataManager);
                            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
                        }
                    }
                }

                entityIndex += batchCount;
            }
        }
Esempio n. 10
0
        public static void MoveChunks(ArchetypeManager srcArchetypeManager, EntityDataManager *srcEntityDataManager,
                                      SharedComponentDataManager srcSharedComponents, ArchetypeManager dstArchetypeManager,
                                      EntityGroupManager dstGroupManager, SharedComponentDataManager dstSharedComponentDataManager,
                                      EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents)
        {
            var entityRemapping = new NativeArray <EntityRemapUtility.EntityRemapInfo>(srcEntityDataManager->Capacity, Allocator.Temp);
            var entityPatches   = new NativeList <EntityRemapUtility.EntityPatchInfo>(128, Allocator.Temp);

            dstEntityDataManager->AllocateEntitiesForRemapping(srcEntityDataManager, ref entityRemapping);

            var srcArchetype = srcArchetypeManager.m_LastArchetype;

            while (srcArchetype != null)
            {
                if (srcArchetype->EntityCount != 0)
                {
                    if (srcArchetype->NumManagedArrays != 0)
                    {
                        throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays");
                    }
                    var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(srcArchetype->Types,
                                                                                srcArchetype->TypesCount, dstGroupManager);

                    entityPatches.Clear();
                    for (var i = 1; i != dstArchetype->TypesCount; i++)
                    {
                        EntityRemapUtility.AppendEntityPatches(ref entityPatches,
                                                               TypeManager.GetComponentType(dstArchetype->Types[i].TypeIndex).EntityOffsets,
                                                               dstArchetype->Offsets[i], dstArchetype->SizeOfs[i]);
                    }

                    for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next)
                    {
                        var chunk = (Chunk *)c;

                        dstEntityDataManager->RemapChunk(dstArchetype, chunk, 0, chunk->Count, ref entityRemapping);
                        EntityRemapUtility.PatchEntities(ref entityPatches, chunk->Buffer, chunk->Count, ref entityRemapping);

                        chunk->Archetype = dstArchetype;

                        if (dstArchetype->NumSharedComponents > 0)
                        {
                            dstSharedComponents.MoveSharedComponents(srcSharedComponents,
                                                                     chunk->SharedComponentValueArray, dstArchetype->NumSharedComponents);
                        }
                    }

                    UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkList.End, &srcArchetype->ChunkList);
                    if (!srcArchetype->ChunkListWithEmptySlots.IsEmpty)
                    {
                        UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkListWithEmptySlots.End,
                                                              &srcArchetype->ChunkListWithEmptySlots);
                    }

                    dstArchetype->EntityCount += srcArchetype->EntityCount;
                    dstArchetype->ChunkCount  += srcArchetype->ChunkCount;
                    srcArchetype->EntityCount  = 0;
                    srcArchetype->ChunkCount   = 0;
                }

                srcArchetype = srcArchetype->PrevArchetype;
            }

            srcEntityDataManager->FreeAllEntities();

            entityRemapping.Dispose();
            entityPatches.Dispose();
        }