/// <summary> /// Constructs a set of changes between the given src and dst chunks. /// </summary> /// <remarks> /// A chunk is considered unchanged if the <see cref="Chunk.SequenceNumber"/> matches and all type change versions match. /// </remarks> internal static ArchetypeChunkChanges GetArchetypeChunkChanges( NativeArray <ArchetypeChunk> srcChunks, NativeArray <ArchetypeChunk> dstChunks, Allocator allocator, out JobHandle jobHandle, JobHandle dependsOn = default) { var archetypeChunkChanges = new ArchetypeChunkChanges(allocator); var srcChunksBySequenceNumber = new NativeHashMap <ulong, ArchetypeChunk>(srcChunks.Length, Allocator.TempJob); var buildChunkSequenceNumberMap = new BuildChunkSequenceNumberMap { Chunks = srcChunks, ChunksBySequenceNumber = srcChunksBySequenceNumber.AsParallelWriter() }.Schedule(srcChunks.Length, 64, dependsOn); var gatherArchetypeChunkChanges = new GatherArchetypeChunkChanges { SrcChunks = srcChunks, DstChunks = dstChunks, SrcChunksBySequenceNumber = srcChunksBySequenceNumber, CreatedChunks = archetypeChunkChanges.CreatedSrcChunks.Chunks, CreatedChunkFlags = archetypeChunkChanges.CreatedSrcChunks.Flags, CreatedChunkEntityCounts = archetypeChunkChanges.CreatedSrcChunks.EntityCounts, DestroyedChunks = archetypeChunkChanges.DestroyedDstChunks.Chunks, DestroyedChunkFlags = archetypeChunkChanges.DestroyedDstChunks.Flags, DestroyedChunkEntityCounts = archetypeChunkChanges.DestroyedDstChunks.EntityCounts, }.Schedule(buildChunkSequenceNumberMap); jobHandle = srcChunksBySequenceNumber.Dispose(gatherArchetypeChunkChanges); return(archetypeChunkChanges); }
internal static void CopyAndReplaceChunks( EntityManager srcEntityManager, EntityManager dstEntityManager, EntityQuery dstEntityQuery, ArchetypeChunkChanges archetypeChunkChanges) { s_CopyAndReplaceChunksProfilerMarker.Begin(); var dstAccess = dstEntityManager.GetCheckedEntityDataAccess(); var srcAccess = srcEntityManager.GetCheckedEntityDataAccess(); var archetypeChanges = dstAccess->EntityComponentStore->BeginArchetypeChangeTracking(); DestroyChunks(dstEntityManager, archetypeChunkChanges.DestroyedDstChunks.Chunks); CloneAndAddChunks(srcEntityManager, dstEntityManager, archetypeChunkChanges.CreatedSrcChunks.Chunks); dstAccess->EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges, dstAccess->EntityQueryManager); srcAccess->EntityComponentStore->InvalidateChunkListCacheForChangedArchetypes(); dstAccess->EntityComponentStore->InvalidateChunkListCacheForChangedArchetypes(); //@TODO-opt: use a query that searches for all chunks that have chunk components on it //@TODO-opt: Move this into a job // Any chunk might have been recreated, so the ChunkHeader might be invalid using (var allDstChunks = dstEntityQuery.CreateArchetypeChunkArray(Allocator.TempJob)) { foreach (var chunk in allDstChunks) { var metaEntity = chunk.m_Chunk->metaChunkEntity; if (metaEntity != Entity.Null) { if (dstEntityManager.Exists(metaEntity)) { dstEntityManager.SetComponentData(metaEntity, new ChunkHeader { ArchetypeChunk = chunk }); } } } } srcAccess->EntityComponentStore->IncrementGlobalSystemVersion(); dstAccess->EntityComponentStore->IncrementGlobalSystemVersion(); s_CopyAndReplaceChunksProfilerMarker.End(); }