static Chunk *CloneChunkWithoutAllocatingEntities(EntityManager dstEntityManager, Chunk *srcChunk, ManagedComponentStore srcManagedComponentStore)
        {
            var dstEntityComponentStore  = dstEntityManager.EntityComponentStore;
            var dstManagedComponentStore = dstEntityManager.ManagedComponentStore;

            // Copy shared component data
            var dstSharedIndices = stackalloc int[srcChunk->Archetype->NumSharedComponents];

            srcChunk->SharedComponentValues.CopyTo(dstSharedIndices, 0, srcChunk->Archetype->NumSharedComponents);
            dstManagedComponentStore.CopySharedComponents(srcManagedComponentStore, dstSharedIndices, srcChunk->Archetype->NumSharedComponents);

            // @TODO: Why don't we memcpy the whole chunk. So we include all extra fields???

            // Allocate a new chunk
            var srcArchetype = srcChunk->Archetype;
            var dstArchetype = dstEntityComponentStore->GetOrCreateArchetype(srcArchetype->Types, srcArchetype->TypesCount);

            var dstChunk = dstEntityComponentStore->GetCleanChunkNoMetaChunk(dstArchetype, dstSharedIndices);

            dstManagedComponentStore.Playback(ref dstEntityComponentStore->ManagedChangesTracker);

            dstChunk->metaChunkEntity = srcChunk->metaChunkEntity;

            // Release any references obtained by GetCleanChunk & CopySharedComponents
            for (var i = 0; i < srcChunk->Archetype->NumSharedComponents; i++)
            {
                dstManagedComponentStore.RemoveReference(dstSharedIndices[i]);
            }

            dstEntityComponentStore->SetChunkCountKeepMetaChunk(dstChunk, srcChunk->Count);
            dstManagedComponentStore.Playback(ref dstEntityComponentStore->ManagedChangesTracker);

            dstChunk->Archetype->EntityCount += srcChunk->Count;

            var copySize = Chunk.GetChunkBufferSize();

            UnsafeUtility.MemCpy((byte *)dstChunk + Chunk.kBufferOffset, (byte *)srcChunk + Chunk.kBufferOffset, copySize);

            // @TODO: Class components should be duplicated instead of copied by ref?
            if (dstChunk->ManagedArrayIndex != -1)
            {
                ManagedComponentStore.CopyManagedObjects(srcManagedComponentStore, srcChunk->Archetype, srcChunk->ManagedArrayIndex, srcChunk->Capacity, 0, dstManagedComponentStore, dstChunk->Archetype, dstChunk->ManagedArrayIndex, dstChunk->Capacity, 0, srcChunk->Count);
            }

            BufferHeader.PatchAfterCloningChunk(dstChunk);
            dstChunk->SequenceNumber = srcChunk->SequenceNumber;

            return(dstChunk);
        }
예제 #2
0
        static void DestroyBatch(Entity *entities, Chunk *chunk, int indexInChunk, int batchCount,
                                 EntityComponentStore *entityComponentStore,
                                 ManagedComponentStore managedComponentStore)
        {
            var archetype = chunk->Archetype;

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

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

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

                chunk->Archetype->EntityCount -= batchCount;
                SetChunkCount(chunk, chunk->Count - batchCount, entityComponentStore, managedComponentStore);
            }
            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)
                {
                    managedComponentStore.IncrementComponentOrderVersion(archetype, chunk->SharedComponentValues);
                    entityComponentStore->IncrementComponentTypeOrderVersion(archetype);

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