/// <summary> /// Copies all entities from srcEntityManager and replaces all entities in this EntityManager /// </summary> /// <remarks> /// Gurantees that the chunk layout & order of the entities will match exactly, thus this method can be used for deterministic rollback. /// This feature is not complete and only supports a subset of the EntityManager features at the moment: /// * Currently it copies all SystemStateComponents (They should not be copied) /// * Currently does not support class based components /// </remarks> public void CopyAndReplaceEntitiesFrom(EntityManager srcEntityManager) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (srcEntityManager == null || !srcEntityManager.IsCreated) { throw new ArgumentNullException(nameof(srcEntityManager)); } if (!IsCreated) { throw new ArgumentException("This EntityManager has been destroyed"); } #endif srcEntityManager.CompleteAllJobs(); CompleteAllJobs(); using (var srcChunks = srcEntityManager.m_UniversalQueryWithChunks.CreateArchetypeChunkArray(Allocator.TempJob)) using (var dstChunks = m_UniversalQueryWithChunks.CreateArchetypeChunkArray(Allocator.TempJob)) { using (var archetypeChunkChanges = ArchetypeChunkChangeUtility.GetArchetypeChunkChanges(srcChunks, dstChunks, Allocator.TempJob)) { EntityManagerDifferUtility.CopyAndReplaceChunks(srcEntityManager, this, m_UniversalQueryWithChunks, archetypeChunkChanges); Unity.Entities.EntityComponentStore.AssertSameEntities(srcEntityManager.EntityComponentStore, EntityComponentStore); } } }
/// <summary> /// Creates a stateful change tracker over the given world. /// </summary> /// <param name="srcWorld">The input world to track changes for.</param> /// <param name="allocator">Allocator used for the cached state.</param> public EntityManagerDiffer(World srcWorld, Allocator allocator) { m_SrcWorld = srcWorld ?? throw new ArgumentNullException(nameof(srcWorld)); m_ShadowWorld = new World(srcWorld.Name + " (Shadow)"); m_SrcWorldEntityQuery = EntityManagerDifferUtility.CreateQuery(srcWorld.EntityManager); m_ShadowWorldEntityQuery = EntityManagerDifferUtility.CreateQuery(m_ShadowWorld.EntityManager); m_TypeInfoStream = new TypeInfoStream(allocator); }
/// <summary> /// Generates a detailed change set for the world. /// All entities to be considered for diffing must have the <see cref="EntityGuid"/> component with a unique value. /// The resulting <see cref="EntityChanges"/> must be disposed when no longer needed. /// </summary> /// <param name="options">A set of options which can be toggled.</param> /// <param name="allocator">The allocator to use for the results object.</param> /// <returns>A Change set containing the differences between the two worlds.</returns> public EntityChanges GetChanges(EntityManagerDifferOptions options, Allocator allocator) { s_GetChangesMarker.Begin(); var changes = EntityManagerDifferUtility.GetChanges( m_SrcWorld.EntityManager, m_SrcWorldEntityQuery, m_ShadowWorld.EntityManager, m_ShadowWorldEntityQuery, m_TypeInfoStream, options, allocator); s_GetChangesMarker.End(); return(changes); }