using System; using Unity.Collections; namespace Unity.Entities { public sealed unsafe partial class EntityManager { // ---------------------------------------------------------------------------------------------------------- // PUBLIC // ---------------------------------------------------------------------------------------------------------- /// /// Moves all entities managed by the specified EntityManager to the of this EntityManager and fills /// an array with their objects. /// /// /// After the move, the entities are managed by this EntityManager. Use the `output` array to make post-move /// changes to the transferred entities. /// /// Each world has one EntityManager, which manages all the entities in that world. This function /// allows you to transfer entities from one World to another. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before moving the entities and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// /// An array to receive the Entity objects of the transferred entities. /// The EntityManager whose entities are appropriated. /// A set of entity transformations to make during the transfer. /// public void MoveEntitiesFrom(out NativeArray output, EntityManager srcEntities, NativeArray entityRemapping) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (srcEntities == this) throw new ArgumentException("srcEntities must not be the same as this EntityManager."); if (!srcEntities.m_ManagedComponentStore.AllSharedComponentReferencesAreFromChunks(srcEntities .EntityComponentStore)) throw new ArgumentException( "EntityManager.MoveEntitiesFrom failed - All ISharedComponentData references must be from EntityManager. (For example EntityQuery.SetFilter with a shared component type is not allowed during EntityManager.MoveEntitiesFrom)"); #endif BeforeStructuralChange(); srcEntities.BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityManagerMoveEntitiesUtility.MoveChunks(entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore, EntityComponentStore, ManagedComponentStore); EntityRemapUtility.GetTargets(out output, entityRemapping); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityGroupManager.AddAdditionalArchetypes(changedArchetypes); //@TODO: Need to increment the component versions based the moved chunks... } /// /// Moves a selection of the entities managed by the specified EntityManager to the of this EntityManager /// and fills an array with their objects. /// /// /// After the move, the entities are managed by this EntityManager. Use the `output` array to make post-move /// changes to the transferred entities. /// /// Each world has one EntityManager, which manages all the entities in that world. This function /// allows you to transfer entities from one World to another. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before moving the entities and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// /// An array to receive the Entity objects of the transferred entities. /// The EntityManager whose entities are appropriated. /// A EntityQuery that defines the entities to move. Must be part of the source /// World. /// A set of entity transformations to make during the transfer. /// public void MoveEntitiesFrom(out NativeArray output, EntityManager srcEntities, EntityQuery filter, NativeArray entityRemapping) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (filter.EntityComponentStore != srcEntities.EntityComponentStore) throw new ArgumentException( "EntityManager.MoveEntitiesFrom failed - srcEntities and filter must belong to the same World)"); #endif using (var chunks = filter.CreateArchetypeChunkArray(Allocator.TempJob)) { MoveEntitiesFrom(out output, srcEntities, chunks, entityRemapping); } } /// /// Moves all entities managed by the specified EntityManager to the of this EntityManager and fills /// an array with their Entity objects. /// /// /// After the move, the entities are managed by this EntityManager. Use the `output` array to make post-move /// changes to the transferred entities. /// /// Each world has one EntityManager, which manages all the entities in that world. This function /// allows you to transfer entities from one World to another. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before moving the entities and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// /// An array to receive the Entity objects of the transferred entities. /// The EntityManager whose entities are appropriated. public void MoveEntitiesFrom(out NativeArray output, EntityManager srcEntities) { var entityRemapping = srcEntities.CreateEntityRemapArray(Allocator.TempJob); try { MoveEntitiesFrom(out output, srcEntities, entityRemapping); } finally { entityRemapping.Dispose(); } } /// /// Moves a selection of the entities managed by the specified EntityManager to the of this EntityManager. /// /// /// After the move, the entities are managed by this EntityManager. /// /// Each world has one EntityManager, which manages all the entities in that world. This function /// allows you to transfer entities from one World to another. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before moving the entities and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// /// The EntityManager whose entities are appropriated. /// A EntityQuery that defines the entities to move. Must be part of the source /// World. /// A set of entity transformations to make during the transfer. /// Thrown if the EntityQuery object used as the `filter` comes /// from a different world than the `srcEntities` EntityManager. public void MoveEntitiesFrom(EntityManager srcEntities, EntityQuery filter, NativeArray entityRemapping) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (filter.EntityComponentStore != srcEntities.EntityComponentStore) throw new ArgumentException( "EntityManager.MoveEntitiesFrom failed - srcEntities and filter must belong to the same World)"); #endif using (var chunks = filter.CreateArchetypeChunkArray(Allocator.TempJob)) { MoveEntitiesFrom(srcEntities, chunks, entityRemapping); } } /// /// Creates a remapping array with one element for each entity in the . /// /// The type of memory allocation to use when creating the array. /// An array containing a no-op identity transformation for each entity. public NativeArray CreateEntityRemapArray(Allocator allocator) { return new NativeArray(m_EntityComponentStore->EntitiesCapacity, allocator); } // @TODO Proper description of remap utility. /// /// Moves all entities managed by the specified EntityManager to the of this EntityManager. /// /// /// After the move, the entities are managed by this EntityManager. /// /// Each World has one EntityManager, which manages all the entities in that world. This function /// allows you to transfer entities from one world to another. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before moving the entities and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// /// The EntityManager whose entities are appropriated. /// A set of entity transformations to make during the transfer. /// Thrown if you attempt to transfer entities to the EntityManager /// that already owns them. public void MoveEntitiesFrom(EntityManager srcEntities, NativeArray entityRemapping) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (srcEntities == this) throw new ArgumentException("srcEntities must not be the same as this EntityManager."); if (entityRemapping.Length < srcEntities.m_EntityComponentStore->EntitiesCapacity) throw new ArgumentException( "entityRemapping.Length isn't large enough, use srcEntities.CreateEntityRemapArray"); if (!srcEntities.m_ManagedComponentStore.AllSharedComponentReferencesAreFromChunks(srcEntities .EntityComponentStore)) throw new ArgumentException( "EntityManager.MoveEntitiesFrom failed - All ISharedComponentData references must be from EntityManager. (For example EntityQuery.SetFilter with a shared component type is not allowed during EntityManager.MoveEntitiesFrom)"); #endif BeforeStructuralChange(); srcEntities.BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityManagerMoveEntitiesUtility.MoveChunks(entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore, EntityComponentStore, ManagedComponentStore); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityGroupManager.AddAdditionalArchetypes(changedArchetypes); //@TODO: Need to increment the component versions based the moved chunks... } /// /// Moves all entities managed by the specified EntityManager to the world of this EntityManager. /// /// /// The entities moved are owned by this EntityManager. /// /// Each has one EntityManager, which manages all the entities in that world. This function /// allows you to transfer entities from one World to another. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before moving the entities and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// /// The EntityManager whose entities are appropriated. public void MoveEntitiesFrom(EntityManager srcEntities) { var entityRemapping = srcEntities.CreateEntityRemapArray(Allocator.TempJob); try { MoveEntitiesFrom(srcEntities, entityRemapping); } finally { entityRemapping.Dispose(); } } // ---------------------------------------------------------------------------------------------------------- // INTERNAL // ---------------------------------------------------------------------------------------------------------- void MoveEntitiesFrom(out NativeArray output, EntityManager srcEntities, NativeArray chunks, NativeArray entityRemapping) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (srcEntities == this) throw new ArgumentException("srcEntities must not be the same as this EntityManager."); for (int i = 0; i < chunks.Length; ++i) if (chunks[i].m_Chunk->Archetype->HasChunkHeader) throw new ArgumentException( "MoveEntitiesFrom can not move chunks that contain ChunkHeader components."); #endif BeforeStructuralChange(); srcEntities.BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityManagerMoveEntitiesUtility.MoveChunks(chunks, entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore, EntityComponentStore, ManagedComponentStore); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityGroupManager.AddAdditionalArchetypes(changedArchetypes); EntityRemapUtility.GetTargets(out output, entityRemapping); } void MoveEntitiesFrom(EntityManager srcEntities, NativeArray chunks, NativeArray entityRemapping) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (srcEntities == this) throw new ArgumentException("srcEntities must not be the same as this EntityManager."); if (entityRemapping.Length < srcEntities.m_EntityComponentStore->EntitiesCapacity) throw new ArgumentException( "entityRemapping.Length isn't large enough, use srcEntities.CreateEntityRemapArray"); for (int i = 0; i < chunks.Length; ++i) if (chunks[i].m_Chunk->Archetype->HasChunkHeader) throw new ArgumentException( "MoveEntitiesFrom can not move chunks that contain ChunkHeader components."); #endif BeforeStructuralChange(); srcEntities.BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityManagerMoveEntitiesUtility.MoveChunks(chunks, entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore, EntityComponentStore, ManagedComponentStore); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityGroupManager.AddAdditionalArchetypes(changedArchetypes); } } }