internal void DestroyInstance() { EndExclusiveEntityTransaction(); m_DependencyManager->PreDisposeCheck(); #if ENABLE_UNITY_COLLECTIONS_CHECKS m_UniversalQuery._DisallowDisposing = null; m_UniversalQueryWithChunks._DisallowDisposing = null; #endif m_UniversalQuery.Dispose(); m_UniversalQueryWithChunks.Dispose(); m_UniversalQuery = null; m_UniversalQueryWithChunks = null; m_DependencyManager->Dispose(); UnsafeUtility.Free(m_DependencyManager, Allocator.Persistent); m_DependencyManager = null; Entities.EntityComponentStore.Destroy(m_EntityComponentStore); m_EntityComponentStore = null; m_EntityQueryManager.Dispose(); m_EntityQueryManager = null; m_ExclusiveEntityTransaction.OnDestroy(); m_ManagedComponentStore.Dispose(); m_World = null; m_Debug = null; }
internal void AddComponent(UnsafeMatchingArchetypePtrList archetypeList, EntityQueryFilter filter, ComponentType componentType) { var jobHandle = new JobHandle(); //@TODO: Missing EntityQuery.SyncFilter using (var chunks = ComponentChunkIterator.CreateArchetypeChunkArray(archetypeList, Allocator.TempJob, out jobHandle, ref filter)) { jobHandle.Complete(); if (chunks.Length == 0) { return; } BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->AssertCanAddComponent(chunks, componentType); using (var entityBatchList = m_EntityComponentStore->CreateEntityBatchList(chunks)) { EntityComponentStore->AddComponentFromMainThread(entityBatchList, componentType, 0); } var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); } }
void MoveEntitiesFrom(EntityManager srcEntities, NativeArray <ArchetypeChunk> chunks, NativeArray <EntityRemapUtility.EntityRemapInfo> 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(); MoveChunksFrom(chunks, entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); }
// ---------------------------------------------------------------------------------------------------------- // PUBLIC // ---------------------------------------------------------------------------------------------------------- /// <summary> /// Moves all entities managed by the specified EntityManager to the <see cref="World"/> of this EntityManager and fills /// an array with their <see cref="Entity"/> objects. /// </summary> /// <remarks> /// 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. /// </remarks> /// <param name="output">An array to receive the Entity objects of the transferred entities.</param> /// <param name="srcEntities">The EntityManager whose entities are appropriated.</param> /// <param name="entityRemapping">A set of entity transformations to make during the transfer.</param> /// <exception cref="ArgumentException"></exception> public void MoveEntitiesFrom(out NativeArray <Entity> output, EntityManager srcEntities, NativeArray <EntityRemapUtility.EntityRemapInfo> 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(); MoveChunksFrom(entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore); EntityRemapUtility.GetTargets(out output, entityRemapping); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); //@TODO: Need to increment the component versions based the moved chunks... }
/// <summary> /// Adds a component to each of the chunks identified by a EntityQuery and set the component values. /// </summary> /// <remarks> /// This function finds all chunks whose archetype satisfies the EntityQuery and adds the specified /// component to them. /// /// A chunk component is common to all entities in a chunk. You can access a chunk <see cref="IComponentData"/> /// instance through either the chunk itself or through an entity stored in that chunk. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before adding the component 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. /// </remarks> /// <param name="entityQuery">The EntityQuery identifying the chunks to modify.</param> /// <param name="componentData">The data to set.</param> /// <typeparam name="T">The type of component, which must implement IComponentData.</typeparam> public void AddChunkComponentData <T>(EntityQuery entityQuery, T componentData) where T : struct, IComponentData { using (var chunks = entityQuery.CreateArchetypeChunkArray(Allocator.TempJob)) { if (chunks.Length == 0) { return; } BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->AssertCanAddChunkComponent(chunks, ComponentType.ChunkComponent <T>()); var type = ComponentType.ReadWrite <T>(); var chunkType = ComponentType.FromTypeIndex(TypeManager.MakeChunkComponentTypeIndex(type.TypeIndex)); using (var entityBatchList = EntityComponentStore->CreateEntityBatchList(chunks)) { EntityComponentStore->AddComponentFromMainThread(entityBatchList, chunkType, 0); EntityComponentStore->SetChunkComponent <T>(entityBatchList, componentData); } var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); } }
// @TODO: Define what CompareComponents() does /// <summary> /// /// </summary> /// <param name="componentTypes"></param> /// <returns></returns> public bool CompareComponents(ComponentType[] componentTypes) { fixed(ComponentType *componentTypesPtr = componentTypes) { return(EntityQueryManager.CompareComponents(componentTypesPtr, componentTypes.Length, m_QueryData)); } }
public void MoveEntitiesFromInternalAll(EntityManager srcEntities, NativeArray <EntityRemapUtility.EntityRemapInfo> 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(); MoveChunksFromAll(entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); }
internal void DestroyInstance() { EndExclusiveEntityTransaction(); m_ComponentJobSafetyManager->PreDisposeCheck(); m_UniversalQuery.Dispose(); m_UniversalQuery = null; m_UniversalQueryWithChunks.Dispose(); m_UniversalQueryWithChunks = null; m_ComponentJobSafetyManager->Dispose(); UnsafeUtility.Free(m_ComponentJobSafetyManager, Allocator.Persistent); m_ComponentJobSafetyManager = null; Entities.EntityComponentStore.Destroy(m_EntityComponentStore); m_EntityComponentStore = null; m_EntityQueryManager.Dispose(); m_EntityQueryManager = null; m_ExclusiveEntityTransaction.OnDestroy(); m_ManagedComponentStore.Dispose(); m_World = null; m_Debug = null; }
internal ExclusiveEntityTransaction(EntityQueryManager entityQueryManager, ManagedComponentStore managedComponentStore, EntityComponentStore *componentStore) { #if ENABLE_UNITY_COLLECTIONS_CHECKS m_Safety = new AtomicSafetyHandle(); #endif EntityComponentStore = componentStore; m_EntityQueryManager = GCHandle.Alloc(entityQueryManager, GCHandleType.Weak); m_ManagedComponentStore = GCHandle.Alloc(managedComponentStore, GCHandleType.Weak); }
/// <summary> /// Removes a component from an entity. /// </summary> /// <remarks> /// Removing a component changes an entity's archetype and results in the entity being moved to a different /// chunk. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before removing the component 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. /// </remarks> /// <param name="entity">The entity to modify.</param> /// <param name="type">The type of component to remove.</param> public void RemoveComponent(Entity entity, ComponentType type) { BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->RemoveComponent(entity, type); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); }
public EntityArchetype GetEntityOnlyArchetype() { if (!m_EntityOnlyArchetype.Valid) { var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); ComponentTypeInArchetype entityType = new ComponentTypeInArchetype(ComponentType.ReadWrite <Entity>()); var archetype = EntityComponentStore->GetOrCreateArchetype(&entityType, 1); m_EntityOnlyArchetype = new EntityArchetype { Archetype = archetype }; var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); } return(m_EntityOnlyArchetype); }
// ---------------------------------------------------------------------------------------------------------- // INTERNAL // ---------------------------------------------------------------------------------------------------------- internal void AddComponent(Entity entity, ComponentType componentType, bool ignoreDuplicateAdd) { if (ignoreDuplicateAdd && HasComponent(entity, componentType)) { return; } BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->AssertCanAddComponent(entity, componentType); EntityComponentStore->AddComponent(entity, componentType); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); }
public void SetArchetype(Entity entity, EntityArchetype archetype) { BeforeStructuralChange(); EntityComponentStore->AssertEntitiesExist(&entity, 1); var oldArchetype = EntityComponentStore->GetArchetype(entity); var newArchetype = archetype.Archetype; Unity.Entities.EntityComponentStore.AssertArchetypeDoesNotRemoveSystemStateComponents(oldArchetype, newArchetype); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->SetArchetype(entity, archetype); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); }
internal void AddSharedComponentData(NativeArray <ArchetypeChunk> chunks, int sharedComponentIndex, ComponentType componentType) { if (chunks.Length == 0) { return; } BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->AssertCanAddComponent(chunks, componentType); EntityComponentStore->AddSharedComponent(chunks, componentType, sharedComponentIndex); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); ManagedComponentStore.RemoveReference(sharedComponentIndex); }
internal EntityManager(World world) { TypeManager.Initialize(); StructuralChange.Initialize(); m_World = world; m_DependencyManager = (ComponentDependencyManager *)UnsafeUtility.Malloc(sizeof(ComponentDependencyManager), 64, Allocator.Persistent); m_DependencyManager->OnCreate(); m_EntityComponentStore = Entities.EntityComponentStore.Create(world.SequenceNumber << 32); m_ManagedComponentStore = new ManagedComponentStore(); m_EntityQueryManager = new EntityQueryManager(m_DependencyManager); m_EntityDataAccess = new EntityDataAccess(this, true); m_ExclusiveEntityTransaction = new ExclusiveEntityTransaction(this); m_UniversalQuery = CreateEntityQuery( new EntityQueryDesc { Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled } ); m_UniversalQueryWithChunks = CreateEntityQuery( new EntityQueryDesc { All = new[] { ComponentType.ReadWrite <ChunkHeader>() }, Options = EntityQueryOptions.IncludeDisabled | EntityQueryOptions.IncludePrefab }, new EntityQueryDesc { Options = EntityQueryOptions.IncludeDisabled | EntityQueryOptions.IncludePrefab } ); #if ENABLE_UNITY_COLLECTIONS_CHECKS m_UniversalQuery._DisallowDisposing = "EntityManager.UniversalQuery may not be disposed"; m_UniversalQueryWithChunks._DisallowDisposing = "EntityManager.UniversalQuery may not be disposed"; #endif }
/// <summary> /// Remove a component from a set of entities. /// </summary> /// <remarks> /// Removing a component changes an entity's archetype and results in the entity being moved to a different /// chunk. /// /// If an <see cref="Entity"/> object in the `entities` array refers to an entity that has been destroyed, this function /// throws an ArgumentError exception. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before creating these chunks 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. /// </remarks> /// <param name="entities">An array of Entity objects.</param> /// <param name="componentType">The type of component to remove.</param> public void RemoveComponent(NativeArray <Entity> entities, ComponentType componentType) { if (entities.Length == 0) { return; } BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); using (var entityBatchList = m_EntityComponentStore->CreateEntityBatchList(entities)) { EntityComponentStore->RemoveComponentFromMainThread(entityBatchList, componentType, 0); } var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); }
internal EntityManager(World world) { TypeManager.Initialize(); StructuralChange.Initialize(); m_World = world; m_ComponentJobSafetyManager = (ComponentJobSafetyManager *)UnsafeUtility.Malloc(sizeof(ComponentJobSafetyManager), 64, Allocator.Persistent); m_ComponentJobSafetyManager->OnCreate(); m_EntityComponentStore = Entities.EntityComponentStore.Create(world.SequenceNumber << 32); m_ManagedComponentStore = new ManagedComponentStore(); m_EntityQueryManager = new EntityQueryManager(m_ComponentJobSafetyManager); m_EntityDataAccess = new EntityDataAccess(this, true); m_ExclusiveEntityTransaction = new ExclusiveEntityTransaction(this); m_UniversalQuery = CreateEntityQuery( new EntityQueryDesc { Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled } ); m_UniversalQueryWithChunks = CreateEntityQuery( new EntityQueryDesc { All = new[] { ComponentType.ReadWrite <ChunkHeader>() }, Options = EntityQueryOptions.IncludeDisabled | EntityQueryOptions.IncludePrefab }, new EntityQueryDesc { Options = EntityQueryOptions.IncludeDisabled | EntityQueryOptions.IncludePrefab } ); }
// ---------------------------------------------------------------------------------------------------------- // INTERNAL // ---------------------------------------------------------------------------------------------------------- void MoveEntitiesFromInternalQuery(EntityManager srcEntities, EntityQuery filter, NativeArray <EntityRemapUtility.EntityRemapInfo> 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)"); } if (srcEntities == this) { throw new ArgumentException("srcEntities must not be the same as this EntityManager."); } #endif BeforeStructuralChange(); srcEntities.BeforeStructuralChange(); using (var chunks = filter.CreateArchetypeChunkArray(Allocator.TempJob)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS 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 var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); MoveChunksFromFiltered(chunks, entityRemapping, srcEntities.EntityComponentStore, srcEntities.ManagedComponentStore); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); } }
/// <summary> /// /// </summary> /// <param name="queryDesc"></param> /// <returns></returns> public bool CompareQuery(EntityQueryDesc[] queryDesc) { return(EntityQueryManager.CompareQuery(queryDesc, m_QueryData)); }
/// <summary> /// /// </summary> /// <param name="componentTypes"></param> /// <returns></returns> public bool CompareComponents(NativeArray <ComponentType> componentTypes) { return(EntityQueryManager.CompareComponents((ComponentType *)componentTypes.GetUnsafeReadOnlyPtr(), componentTypes.Length, m_QueryData)); }
internal bool CompareComponents(ComponentType *componentTypes, int count) { return(EntityQueryManager.CompareComponents(componentTypes, count, m_QueryData)); }