/// <summary> /// Enabled entities are processed by systems, disabled entities are not. /// Adds or removes the <see cref="Disabled"/> component. By default EntityQuery does not include entities containing the Disabled component. /// /// If the entity was converted from a prefab and thus has a <see cref="LinkedEntityGroup"/> component, the entire group will enabled or disabled. /// </summary> /// <param name="entity">The entity to enable or disable</param> /// <param name="enabled">True if the entity should be enabled</param> public void SetEnabled(Entity entity, bool enabled) { if (GetEnabled(entity) == enabled) { return; } var disabledType = ComponentType.ReadWrite <Disabled>(); if (HasComponent <LinkedEntityGroup>(entity)) { //@TODO: AddComponent / Remove component should support Allocator.Temp using (var linkedEntities = GetBuffer <LinkedEntityGroup>(entity).Reinterpret <Entity>().ToNativeArray(Allocator.TempJob)) { if (enabled) { RemoveComponent(linkedEntities, disabledType); } else { AddComponent(linkedEntities, disabledType); } } } else { if (!enabled) { AddComponent(entity, disabledType); } else { RemoveComponent(entity, disabledType); } } }
internal EntityManager(World world) { TypeManager.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_ExclusiveEntityTransaction = new ExclusiveEntityTransaction(EntityQueryManager, m_ManagedComponentStore, EntityComponentStore); 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 } ); }
/// <summary> /// Gets the run-time type information required to access an array of component data in a chunk. /// </summary> /// <param name="isReadOnly">Whether the component data is only read, not written. Access components as /// read-only whenever possible.</param> /// <typeparam name="T">A struct that implements <see cref="IComponentData"/>.</typeparam> /// <returns>An object representing the type information required to safely access component data stored in a /// chunk.</returns> /// <remarks>Pass an <see cref="ArchetypeChunkComponentType"/> instance to a job that has access to chunk data, /// such as an <see cref="IJobChunk"/> job, to access that type of component inside the job.</remarks> public ArchetypeChunkComponentType <T> GetArchetypeChunkComponentType <T>(bool isReadOnly = false) where T : struct, IComponentData { AddReaderWriter(isReadOnly ? ComponentType.ReadOnly <T>() : ComponentType.ReadWrite <T>()); return(EntityManager.GetArchetypeChunkComponentType <T>(isReadOnly)); }
// ---------------------------------------------------------------------------------------------------------- // PUBLIC // ---------------------------------------------------------------------------------------------------------- public static Archetype *GetOrCreateArchetype(ComponentTypeInArchetype *inTypesSorted, int count, EntityComponentStore *entityComponentStore) { var srcArchetype = entityComponentStore->GetExistingArchetype(inTypesSorted, count); if (srcArchetype != null) { return(srcArchetype); } srcArchetype = entityComponentStore->CreateArchetype(inTypesSorted, count); var types = stackalloc ComponentTypeInArchetype[count + 1]; // Setup Instantiable archetype { UnsafeUtility.MemCpy(types, inTypesSorted, sizeof(ComponentTypeInArchetype) * count); var hasCleanup = false; var removedTypes = 0; var prefabTypeIndex = TypeManager.GetTypeIndex <Prefab>(); var cleanupTypeIndex = TypeManager.GetTypeIndex <CleanupEntity>(); for (var t = 0; t < srcArchetype->TypesCount; ++t) { var type = srcArchetype->Types[t]; hasCleanup |= type.TypeIndex == cleanupTypeIndex; var skip = type.IsSystemStateComponent || type.TypeIndex == prefabTypeIndex; if (skip) { ++removedTypes; } else { types[t - removedTypes] = srcArchetype->Types[t]; } } // Entity has already been destroyed, so it shouldn't be instantiated anymore if (hasCleanup) { srcArchetype->InstantiableArchetype = null; } else if (removedTypes > 0) { var instantiableArchetype = GetOrCreateArchetype(types, count - removedTypes, entityComponentStore); srcArchetype->InstantiableArchetype = instantiableArchetype; Assert.IsTrue(instantiableArchetype->InstantiableArchetype == instantiableArchetype); Assert.IsTrue(instantiableArchetype->SystemStateResidueArchetype == null); } else { srcArchetype->InstantiableArchetype = srcArchetype; } } // Setup System state cleanup archetype if (srcArchetype->SystemStateCleanupNeeded) { var cleanupEntityType = new ComponentTypeInArchetype(ComponentType.ReadWrite <CleanupEntity>()); bool cleanupAdded = false; types[0] = inTypesSorted[0]; var newTypeCount = 1; for (var t = 1; t < srcArchetype->TypesCount; ++t) { var type = srcArchetype->Types[t]; if (type.IsSystemStateComponent) { if (!cleanupAdded && (cleanupEntityType < srcArchetype->Types[t])) { types[newTypeCount++] = cleanupEntityType; cleanupAdded = true; } types[newTypeCount++] = srcArchetype->Types[t]; } } if (!cleanupAdded) { types[newTypeCount++] = cleanupEntityType; } var systemStateResidueArchetype = GetOrCreateArchetype(types, newTypeCount, entityComponentStore); srcArchetype->SystemStateResidueArchetype = systemStateResidueArchetype; Assert.IsTrue(systemStateResidueArchetype->SystemStateResidueArchetype == systemStateResidueArchetype); Assert.IsTrue(systemStateResidueArchetype->InstantiableArchetype == null); } // Setup meta chunk archetype if (count > 1) { types[0] = new ComponentTypeInArchetype(typeof(Entity)); int metaArchetypeTypeCount = 1; for (int i = 1; i < count; ++i) { var t = inTypesSorted[i]; ComponentType typeToInsert; if (inTypesSorted[i].IsChunkComponent) { typeToInsert = new ComponentType { TypeIndex = TypeManager.ChunkComponentToNormalTypeIndex(t.TypeIndex) }; SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, typeToInsert); } } if (metaArchetypeTypeCount > 1) { SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, new ComponentType(typeof(ChunkHeader))); srcArchetype->MetaChunkArchetype = GetOrCreateArchetype(types, metaArchetypeTypeCount, entityComponentStore); } } return(srcArchetype); }
/// <summary> /// Gets the managed [UnityEngine.Component](https://docs.unity3d.com/ScriptReference/Component.html) object /// from an entity. /// </summary> /// <param name="entity">The entity.</param> /// <typeparam name="T">The type of the managed object.</typeparam> /// <returns>The managed object, cast to type T.</returns> public T GetComponentObject <T>(Entity entity) { var componentType = ComponentType.ReadWrite <T>(); return(GetComponentObject <T>(entity, componentType)); }
public DynamicBuffer <T> AddBuffer <T>(Entity entity) where T : struct, IBufferElementData { AddComponent(entity, ComponentType.ReadWrite <T>()); return(GetBuffer <T>(entity)); }
/// <summary> /// Sets the value of a component of an entity. /// </summary> /// <param name="entity">The entity.</param> /// <param name="componentData">The data to set.</param> /// <typeparam name="T">The component type.</typeparam> /// <exception cref="ArgumentException">Thrown if the component type has no fields.</exception> public static void SetComponentData <T>(this EntityManager manager, Entity entity, T componentData) where T : class, IComponentData { var type = ComponentType.ReadWrite <T>(); manager.SetComponentObject(entity, type, componentData); }
public DynamicBuffer <T> AddBuffer <T>(Entity entity) where T : struct, IBufferElementData { CheckWriteAccess(); m_EntityDataAccess.AddComponent(entity, ComponentType.ReadWrite <T>()); return(GetBuffer <T>(entity)); }
/// <summary> /// Gets the value of a component for an entity. /// </summary> /// <param name="entity">The entity.</param> /// <typeparam name="T">The type of component to retrieve.</typeparam> /// <returns>A struct of type T containing the component value.</returns> /// <exception cref="ArgumentException">Thrown if the component type has no fields.</exception> public static T GetComponentData <T>(this EntityManager manager, Entity entity) where T : class, IComponentData { var componentType = ComponentType.ReadWrite <T>(); return((T)manager.GetManagedComponentDataAsObject(entity, componentType)); }
/// <summary> /// Adds a shared component to an entity. /// </summary> /// <remarks> /// The fields of the `componentData` parameter are assigned to the added shared component. /// /// Adding a component to an entity changes its archetype and results in the entity being moved to a /// different chunk. The entity moves to a chunk with other entities that have the same shared component values. /// A new chunk is created if no chunk with the same archetype and shared component values currently exists. /// /// **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="entity">The entity.</param> /// <param name="componentData">An instance of the shared component having the values to set.</param> /// <typeparam name="T">The shared component type.</typeparam> public void AddSharedComponentData <T>(Entity entity, T componentData) where T : struct, ISharedComponentData { //TODO: optimize this (no need to move the entity to a new chunk twice) AddComponent(entity, ComponentType.ReadWrite <T>(), false); SetSharedComponentData(entity, componentData); }
/// <summary> /// Removes 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. /// /// **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="entities">An array identifying the entities to modify.</param> /// <typeparam name="T">The type of component to remove.</typeparam> public void RemoveComponent <T>(NativeArray <Entity> entities) { RemoveComponent(entities, ComponentType.ReadWrite <T>()); }
/// <summary> /// Removes a component from a set of entities defined by a EntityQuery. /// </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="entityQuery">The EntityQuery defining the entities to modify.</param> /// <typeparam name="T">The type of component to remove.</typeparam> public void RemoveComponent <T>(EntityQuery entityQuery) { RemoveComponent(entityQuery, ComponentType.ReadWrite <T>()); }
/// <summary> /// Gets the managed [UnityEngine.Component](https://docs.unity3d.com/ScriptReference/Component.html) object /// from an entity. /// </summary> /// <param name="entity">The entity.</param> /// <typeparam name="T">The type of the managed object.</typeparam> /// <returns>The managed object, cast to type T.</returns> public T GetComponentObject <T>(Entity entity) { return(m_EntityDataAccess.GetComponentObject <T>(entity, ComponentType.ReadWrite <T>(), m_ManagedComponentStore)); }
/// <summary> /// Gets a BufferFromEntity<T> object that can access a <seealso cref="DynamicBuffer{T}"/>. /// </summary> /// <remarks>Assign the returned object to a field of your Job struct so that you can access the /// contents of the buffer in a Job.</remarks> /// <param name="isReadOnly">Whether the buffer data is only read or is also written. Access data in /// a read-only fashion whenever possible.</param> /// <typeparam name="T">The type of <see cref="IBufferElementData"/> stored in the buffer.</typeparam> /// <returns>An array-like object that provides access to buffers, indexed by <see cref="Entity"/>.</returns> /// <seealso cref="ComponentDataFromEntity{T}"/> public BufferFromEntity <T> GetBufferFromEntity <T>(bool isReadOnly = false) where T : struct, IBufferElementData { AddReaderWriter(isReadOnly ? ComponentType.ReadOnly <T>() : ComponentType.ReadWrite <T>()); return(EntityManager.GetBufferFromEntity <T>(isReadOnly)); }
public void ReleaseBlobAsset(EntityManager entityManager, ulong hash) { var blobAssets = (BlobAssetPtr *)m_BlobAssets->Ptr; for (var i = 0; i < m_BlobAssets->Length; i++) { if (blobAssets[i].Hash != hash) { continue; } var entity = entityManager.CreateEntity(ComponentType.ReadWrite <RetainBlobAssets>(), ComponentType.ReadWrite <RetainBlobAssetPtr>()); entityManager.SetComponentData(entity, new RetainBlobAssets { FramesToRetainBlobAssets = m_FramesToRetainBlobAssets }); entityManager.SetComponentData(entity, new RetainBlobAssetPtr { BlobAsset = blobAssets[i].Header }); // Entity lifetime will be bound to the SystemStateComponents we added above, we can safely call DestroyEntity(), // it will be actually destroyed when both components will be removed at cleanup. entityManager.DestroyEntity(entity); m_BlobAssets->RemoveAtSwapBack <BlobAssetPtr>(i); return; } }
internal override ComponentType GetComponentType() { return(ComponentType.ReadWrite <T>()); }
/// <summary> /// Adds a component to an entity. /// </summary> /// <remarks> /// Adding a component changes the entity's archetype and results in the entity being moved to a different /// chunk. /// /// The added component has the default values for the type. /// /// If the <see cref="Entity"/> object 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 adding thes 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 object.</param> /// <typeparam name="T">The type of component to add.</typeparam> public void AddComponent <T>(Entity entity) { AddComponent(entity, ComponentType.ReadWrite <T>()); }