public static void Convert(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstIndex) { var srcArch = srcChunk->Archetype; var dstArch = dstChunk->Archetype; //Debug.Log($"Convert {EntityManager.EntityManagerDebug.GetArchetypeDebugString(srcArch)} to {EntityManager.EntityManagerDebug.GetArchetypeDebugString(dstArch)}"); var srcI = 0; var dstI = 0; while (srcI < srcArch->TypesCount && dstI < dstArch->TypesCount) { var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcArch->SizeOfs[srcI]; var dst = dstChunk->Buffer + dstArch->Offsets[dstI] + dstIndex * dstArch->SizeOfs[dstI]; if (srcArch->Types[srcI] < dstArch->Types[dstI]) { // Clear any buffers we're not going to keep. if (srcArch->Types[srcI].IsBuffer) { BufferHeader.Destroy((BufferHeader *)src); } ++srcI; } else if (srcArch->Types[srcI] > dstArch->Types[dstI]) { // Clear components in the destination that aren't copied if (dstArch->Types[dstI].IsBuffer) { BufferHeader.Initialize((BufferHeader *)dst, dstArch->Types[dstI].BufferCapacity); } else { UnsafeUtility.MemClear(dst, dstArch->SizeOfs[dstI]); } ++dstI; } else { UnsafeUtility.MemCpy(dst, src, srcArch->SizeOfs[srcI]); // Poison source buffer to make sure there is no aliasing. if (srcArch->Types[srcI].IsBuffer) { BufferHeader.Initialize((BufferHeader *)src, srcArch->Types[srcI].BufferCapacity); } ++srcI; ++dstI; } } // Handle remaining components in the source that aren't copied for (; srcI < srcArch->TypesCount; ++srcI) { var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcArch->SizeOfs[srcI]; if (srcArch->Types[srcI].IsBuffer) { BufferHeader.Destroy((BufferHeader *)src); } } // Clear remaining components in the destination that aren't copied for (; dstI < dstArch->TypesCount; ++dstI) { var dst = dstChunk->Buffer + dstArch->Offsets[dstI] + dstIndex * dstArch->SizeOfs[dstI]; if (dstArch->Types[dstI].IsBuffer) { BufferHeader.Initialize((BufferHeader *)dst, dstArch->Types[dstI].BufferCapacity); } else { UnsafeUtility.MemClear(dst, dstArch->SizeOfs[dstI]); } } }
public static void Convert(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstIndex, int count, ref EntityComponentStore entityComponentStore) { Assert.IsFalse(srcChunk == dstChunk); var srcArch = srcChunk->Archetype; var dstArch = dstChunk->Archetype; if (srcArch != dstArch) { Assert.IsFalse(srcArch == null); } var srcI = srcArch->NonZeroSizedTypesCount - 1; var dstI = dstArch->NonZeroSizedTypesCount - 1; var sourceTypesToDealloc = stackalloc int[srcI + 1]; int sourceTypesToDeallocCount = 0; while (dstI >= 0) { var srcType = srcArch->Types[srcI]; var dstType = dstArch->Types[dstI]; if (srcType > dstType) { //Type in source is not moved so deallocate it sourceTypesToDealloc[sourceTypesToDeallocCount++] = srcI; --srcI; continue; } var srcStride = srcArch->SizeOfs[srcI]; var dstStride = dstArch->SizeOfs[dstI]; var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride; var dst = dstChunk->Buffer + dstArch->Offsets[dstI] + dstIndex * dstStride; if (srcType == dstType) { UnsafeUtility.MemCpy(dst, src, count * srcStride); --srcI; --dstI; } else { if (dstType.IsBuffer) { InitializeBuffersInChunk(dst, count, dstStride, dstArch->BufferCapacities[dstI]); } else { UnsafeUtility.MemClear(dst, count * dstStride); } --dstI; } } if (sourceTypesToDeallocCount == 0) { return; } sourceTypesToDealloc[sourceTypesToDeallocCount] = 0; int iDealloc = 0; if (sourceTypesToDealloc[iDealloc] >= srcArch->FirstManagedComponent) { var freeCommandHandle = entityComponentStore.ManagedChangesTracker.BeginFreeManagedComponentCommand(); do { srcI = sourceTypesToDealloc[iDealloc]; var srcStride = srcArch->SizeOfs[srcI]; var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride; var a = (int *)src; for (int i = 0; i < count; i++) { var managedComponentIndex = a[i]; if (managedComponentIndex == 0) { continue; } entityComponentStore.FreeManagedComponentIndex(managedComponentIndex); entityComponentStore.ManagedChangesTracker.AddToFreeManagedComponentCommand(managedComponentIndex); } } while ((sourceTypesToDealloc[++iDealloc] >= srcArch->FirstManagedComponent)); entityComponentStore.ManagedChangesTracker.EndDeallocateManagedComponentCommand(freeCommandHandle); } while (sourceTypesToDealloc[iDealloc] >= srcArch->FirstBufferComponent) { srcI = sourceTypesToDealloc[iDealloc]; var srcStride = srcArch->SizeOfs[srcI]; var srcPtr = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride; for (int i = 0; i < count; i++) { BufferHeader.Destroy((BufferHeader *)srcPtr); srcPtr += srcStride; } ++iDealloc; } }