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); }
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); } } } }