internal void DestroyEntity(MatchingArchetypeList archetypeList, EntityQueryFilter filter) { Profiler.BeginSample("DestroyEntity(EntityQuery entityQueryFilter)"); Profiler.BeginSample("GetAllMatchingChunks"); var jobHandle = new JobHandle(); using (var chunks = ComponentChunkIterator.CreateArchetypeChunkArray(archetypeList, Allocator.TempJob, out jobHandle, ref filter)) { jobHandle.Complete(); Profiler.EndSample(); if (chunks.Length != 0) { BeforeStructuralChange(); Profiler.BeginSample("EditorOnlyChecks"); EntityComponentStore->AssertCanDestroy(chunks); EntityComponentStore->AssertWillDestroyAllInLinkedEntityGroup(chunks, GetArchetypeChunkBufferType <LinkedEntityGroup>(false)); Profiler.EndSample(); Profiler.BeginSample("DeleteChunks"); EntityManagerCreateDestroyEntitiesUtility.DestroyEntities(chunks, EntityComponentStore, ManagedComponentStore); Profiler.EndSample(); } } Profiler.EndSample(); }
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); } }
internal void RemoveComponent(MatchingArchetypeList archetypeList, EntityQueryFilter filter, ComponentType componentType) { var jobHandle = new JobHandle(); 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->AssertCanRemoveComponent(chunks, componentType); EntityManagerChangeArchetypeUtility.RemoveComponent(chunks, componentType, EntityComponentStore, ManagedComponentStore); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityGroupManager.AddAdditionalArchetypes(changedArchetypes); } }
internal void AddComponent(MatchingArchetypeList archetypeList, EntityQueryFilter filter, ComponentType componentType) { var jobHandle = new JobHandle(); using (var chunks = ComponentChunkIterator.CreateArchetypeChunkArray(archetypeList, Allocator.TempJob, out jobHandle, ref filter)) { jobHandle.Complete(); if (chunks.Length == 0) { return; } BeforeStructuralChange(); EntityComponentStore->AssertCanAddComponent(chunks, componentType); using (var entityBatchList = m_EntityComponentStore->CreateEntityBatchList(chunks)) { EntityManagerChangeArchetypeUtility.AddComponent(entityBatchList, componentType, 0, EntityComponentStore, ManagedComponentStore, EntityGroupManager); } } }
internal EntityQuery(EntityQueryData *queryData, ComponentJobSafetyManager *safetyManager, EntityComponentStore *entityComponentStore, ManagedComponentStore managedComponentStore) { m_QueryData = queryData; m_Filter = default(EntityQueryFilter); m_SafetyManager = safetyManager; m_EntityComponentStore = entityComponentStore; m_ManagedComponentStore = managedComponentStore; }
internal EntityQuery(EntityGroupData *groupData, ComponentJobSafetyManager *safetyManager, ArchetypeManager typeManager, EntityDataManager *entityDataManager) { m_GroupData = groupData; m_EntityDataManager = entityDataManager; m_Filter = default(EntityQueryFilter); m_SafetyManager = safetyManager; ArchetypeManager = typeManager; EntityDataManager = entityDataManager; }
/// <summary> /// Sets this EntityQuery's filter while preserving its version number. /// </summary> /// <param name="filter">EntityQueryFilter to use all data but RequiredChangeVersion from.</param> void SetFilter(ref EntityQueryFilter filter) { #if ENABLE_UNITY_COLLECTIONS_CHECKS filter.AssertValid(); #endif var version = m_Filter.RequiredChangeVersion; ResetFilter(); m_Filter = filter; m_Filter.RequiredChangeVersion = version; }
/// <summary> /// Filters out entities in chunks for which the specified component has not changed. /// </summary> /// <remarks> /// Saves a given ComponentType's index in RequiredComponents in this group's Changed filter. /// </remarks> /// <param name="componentType">ComponentType to mark as changed on this EntityQuery's filter.</param> public void SetFilterChanged(ComponentType componentType) { var filter = new EntityQueryFilter(); filter.Type = FilterType.Changed; filter.Changed.Count = 1; filter.Changed.IndexInEntityQuery[0] = GetIndexInEntityQuery(componentType.TypeIndex); SetFilter(ref filter); }
/// <summary> /// Creates a NativeArray with all the chunks in a given archetype filtered by the provided EntityQueryFilter. /// This function will sync the needed types in the EntityQueryFilter. /// </summary> /// <param name="matchingArchetypes">List of matching archetypes.</param> /// <param name="allocator">Allocator to use for the array.</param> /// <param name="jobHandle">Handle to the GatherChunks job used to fill the output array.</param> /// <param name="filter">Filter used to filter the resulting chunks</param> /// <param name="dependencyManager">The ComponentDependencyManager belonging to this world</param> /// <param name="dependsOn">All jobs spawned will depend on this JobHandle</param> /// <returns>NativeArray of all the chunks in the matchingArchetypes list.</returns> public static NativeArray <ArchetypeChunk> CreateArchetypeChunkArray( UnsafeMatchingArchetypePtrList matchingArchetypes, Allocator allocator, ref EntityQueryFilter filter, ComponentDependencyManager *dependencyManager) { EntityQuery.SyncFilterTypes(ref matchingArchetypes, ref filter, dependencyManager); var chunks = CreateArchetypeChunkArrayWithoutSync(matchingArchetypes, allocator, out var jobHandle, ref filter); jobHandle.Complete(); return(chunks); }
internal void RemoveComponent(UnsafeMatchingArchetypePtrList archetypeList, EntityQueryFilter filter, ComponentType componentType) { //@TODO: Missing EntityQuery.SyncFilter var jobHandle = new JobHandle(); using (var chunks = ComponentChunkIterator.CreateArchetypeChunkArray(archetypeList, Allocator.TempJob, out jobHandle, ref filter)) { jobHandle.Complete(); RemoveComponent(chunks, componentType); } }
internal ArchetypeChunkIterator(UnsafeMatchingArchetypePtrList match, ComponentJobSafetyManager *safetyManager, uint globalSystemVersion, ref EntityQueryFilter filter) { m_MatchingArchetypeList = match; m_CurrentArchetypeIndex = 0; m_CurrentChunkInArchetypeIndex = -1; m_CurrentChunkFirstEntityIndexInQuery = 0; m_PreviousMatchingChunk = null; m_Filter = filter; m_GlobalSystemVersion = globalSystemVersion; m_SafetyManager = safetyManager; }
public bool MatchesFilter(MatchingArchetype *match, ref EntityQueryFilter filter) { if ((filter.Type & FilterType.SharedComponent) != 0) { var sharedComponentsInChunk = SharedComponentValues; var filteredCount = filter.Shared.Count; fixed(int *indexInEntityQueryPtr = filter.Shared.IndexInEntityQuery, sharedComponentIndexPtr = filter.Shared.SharedComponentIndex) { for (var i = 0; i < filteredCount; ++i) { var indexInEntityQuery = indexInEntityQueryPtr[i]; var sharedComponentIndex = sharedComponentIndexPtr[i]; var componentIndexInArcheType = match->IndexInArchetype[indexInEntityQuery]; var componentIndexInChunk = componentIndexInArcheType - match->Archetype->FirstSharedComponent; if (sharedComponentsInChunk[componentIndexInChunk] != sharedComponentIndex) { return(false); } } } return(true); } if ((filter.Type & FilterType.Changed) != 0) { var changedCount = filter.Changed.Count; var requiredVersion = filter.RequiredChangeVersion; fixed(int *indexInEntityQueryPtr = filter.Changed.IndexInEntityQuery) { for (var i = 0; i < changedCount; ++i) { var indexInArchetype = match->IndexInArchetype[indexInEntityQueryPtr[i]]; var changeVersion = GetChangeVersion(indexInArchetype); if (ChangeVersionUtility.DidChange(changeVersion, requiredVersion)) { return(true); } } } return(false); } return(true); }
public ComponentChunkIterator(MatchingArchetypeList match, uint globalSystemVersion, ref EntityQueryFilter filter) { m_MatchingArchetypeList = match; m_CurrentMatchingArchetypeIndex = match.Count - 1; IndexInEntityQuery = -1; m_CurrentChunk = null; m_CurrentArchetypeIndex = m_CurrentArchetypeEntityIndex = int.MaxValue; // This will trigger UpdateCacheResolvedIndex to update the cache on first access m_CurrentChunkIndex = m_CurrentChunkEntityIndex = 0; m_GlobalSystemVersion = globalSystemVersion; m_Filter = filter; }
/// <summary> /// Filters this EntityQuery so that it only selects entities with shared component values /// matching the values specified by the `sharedComponent1` parameter. /// </summary> /// <param name="sharedComponent1">The shared component values on which to filter.</param> /// <typeparam name="SharedComponent1">The type of shared component. (The type must also be /// one of the types used to create the EntityQuery.</typeparam> public void SetFilter <SharedComponent1>(SharedComponent1 sharedComponent1) where SharedComponent1 : struct, ISharedComponentData { var sm = ManagedComponentStore; var filter = new EntityQueryFilter(); filter.Type = FilterType.SharedComponent; filter.Shared.Count = 1; filter.Shared.IndexInEntityQuery[0] = GetIndexInEntityQuery(TypeManager.GetTypeIndex <SharedComponent1>()); filter.Shared.SharedComponentIndex[0] = sm.InsertSharedComponent(sharedComponent1); SetFilter(ref filter); }
public static void GatherEntitiesToArray(EntityQueryData *queryData, ref EntityQueryFilter filter, out EntityQuery.GatherEntitiesResult result) { if (s_EntityQueryResultBuffer == null) { s_EntityQueryResultBuffer = (Entity *)UnsafeUtility.Malloc(k_EntityQueryResultBufferSize * sizeof(Entity), 64, Allocator.Persistent); } var buffer = s_EntityQueryResultBuffer; var curOffset = currentOffsetInResultBuffer; // Main method that copies the entities of each chunk of a matching archetype to the buffer bool AddArchetype(MatchingArchetype *matchingArchetype, ref EntityQueryFilter queryFilter) { var archetype = matchingArchetype->Archetype; var entityCountInArchetype = archetype->EntityCount; if (entityCountInArchetype == 0) { return(true); } var chunkCount = archetype->Chunks.Count; var chunks = archetype->Chunks.p; var counts = archetype->Chunks.GetChunkEntityCountArray(); for (int i = 0; i < chunkCount; ++i) { // Ignore the chunk if the query uses filter and the chunk doesn't comply if (queryFilter.RequiresMatchesFilter && (chunks[i]->MatchesFilter(matchingArchetype, ref queryFilter) == false)) { continue; } var entityCountInChunk = counts[i]; if ((curOffset + entityCountInChunk) > k_EntityQueryResultBufferSize) { return(false); } UnsafeUtility.MemCpy(buffer + curOffset, chunks[i]->Buffer, entityCountInChunk * sizeof(Entity)); curOffset += entityCountInChunk; } return(true); } // Parse all the matching archetypes and add the entities that fits the query and its filter bool success = true; ref var matchingArchetypes = ref queryData->MatchingArchetypes;
public static void CopyFromComponentDataArray <T>(MatchingArchetypeList matchingArchetypes, NativeArray <T> componentDataArray, ArchetypeChunkComponentType <T> type, EntityQuery entityQuery, ref EntityQueryFilter filter, out JobHandle jobHandle, JobHandle dependsOn) where T : struct, IComponentData { var job = new CopyComponentArrayToChunks <T> { ComponentData = componentDataArray, ComponentType = type }; jobHandle = job.Schedule(entityQuery, dependsOn); }
/// <summary> /// Filters this EntityQuery based on the values of two separate shared components. /// </summary> /// <remarks> /// The filter only selects entities for which both shared component values /// specified by the `sharedComponent1` and `sharedComponent2` parameters match. /// </remarks> /// <param name="sharedComponent1">Shared component values on which to filter.</param> /// <param name="sharedComponent2">Shared component values on which to filter.</param> /// <typeparam name="SharedComponent1">The type of shared component. (The type must also be /// one of the types used to create the EntityQuery.</typeparam> /// <typeparam name="SharedComponent2">The type of shared component. (The type must also be /// one of the types used to create the EntityQuery.</typeparam> public void SetFilter <SharedComponent1, SharedComponent2>(SharedComponent1 sharedComponent1, SharedComponent2 sharedComponent2) where SharedComponent1 : struct, ISharedComponentData where SharedComponent2 : struct, ISharedComponentData { var sm = ArchetypeManager.GetSharedComponentDataManager(); var filter = new EntityQueryFilter(); filter.Type = FilterType.SharedComponent; filter.Shared.Count = 2; filter.Shared.IndexInEntityQuery[0] = GetIndexInEntityQuery(TypeManager.GetTypeIndex <SharedComponent1>()); filter.Shared.SharedComponentIndex[0] = sm.InsertSharedComponent(sharedComponent1); filter.Shared.IndexInEntityQuery[1] = GetIndexInEntityQuery(TypeManager.GetTypeIndex <SharedComponent2>()); filter.Shared.SharedComponentIndex[1] = sm.InsertSharedComponent(sharedComponent2); SetFilter(ref filter); }
public bool ChunkMatchesFilter(int chunkIndex, ref EntityQueryFilter filter) { var chunks = Archetype->Chunks; // Must match ALL shared component data for (int i = 0; i < filter.Shared.Count; ++i) { var indexInEntityQuery = filter.Shared.IndexInEntityQuery[i]; var sharedComponentIndex = filter.Shared.SharedComponentIndex[i]; var componentIndexInChunk = IndexInArchetype[indexInEntityQuery] - Archetype->FirstSharedComponent; var sharedComponents = chunks.GetSharedComponentValueArrayForType(componentIndexInChunk); // if we don't have a match, we can early out if (sharedComponents[chunkIndex] != sharedComponentIndex) { return(false); } } if (filter.Changed.Count == 0) { return(true); } // Must have AT LEAST ONE type have changed for (int i = 0; i < filter.Changed.Count; ++i) { var indexInEntityQuery = filter.Changed.IndexInEntityQuery[i]; var componentIndexInChunk = IndexInArchetype[indexInEntityQuery]; var changeVersions = chunks.GetChangeVersionArrayForType(componentIndexInChunk); var requiredVersion = filter.RequiredChangeVersion; if (ChangeVersionUtility.DidChange(changeVersions[chunkIndex], requiredVersion)) { return(true); } } return(false); }
/// <summary> /// Creates a NativeArray containing the entities in a given EntityQuery. /// </summary> /// <param name="matchingArchetypes">List of matching archetypes.</param> /// <param name="allocator">Allocator to use for the array.</param> /// <param name="type">An atomic safety handle required by GatherEntitiesJob so it can call GetNativeArray() on chunks.</param> /// <param name="entityQuery">EntityQuery to gather entities from.</param> /// <param name="filter">EntityQueryFilter for calculating the length of the output array.</param> /// <param name="jobHandle">Handle to the GatherEntitiesJob job used to fill the output array.</param> /// <param name="dependsOn">Handle to a job this GatherEntitiesJob must wait on.</param> /// <returns>NativeArray of the entities in a given EntityQuery.</returns> public static NativeArray <Entity> CreateEntityArray(UnsafeMatchingArchetypePtrList matchingArchetypes, Allocator allocator, ArchetypeChunkEntityType type, EntityQuery entityQuery, ref EntityQueryFilter filter, out JobHandle jobHandle, JobHandle dependsOn) { var entityCount = CalculateEntityCount(matchingArchetypes, ref filter); var job = new GatherEntitiesJob { EntityType = type, Entities = new NativeArray <Entity>(entityCount, allocator) }; jobHandle = job.Schedule(entityQuery, dependsOn); return(job.Entities); }
public static NativeArray <T> CreateComponentDataArray <T>(UnsafeMatchingArchetypePtrList matchingArchetypes, Allocator allocator, ArchetypeChunkComponentType <T> type, EntityQuery entityQuery, ref EntityQueryFilter filter, out JobHandle jobHandle, JobHandle dependsOn) where T : struct, IComponentData { var entityCount = CalculateEntityCount(matchingArchetypes, ref filter); var job = new GatherComponentDataJob <T> { ComponentData = new NativeArray <T>(entityCount, allocator), ComponentType = type }; jobHandle = job.Schedule(entityQuery, dependsOn); return(job.ComponentData); }
internal void DestroyEntity(UnsafeMatchingArchetypePtrList archetypeList, EntityQueryFilter filter) { Profiler.BeginSample("DestroyEntity(EntityQuery entityQueryFilter)"); Profiler.BeginSample("GetAllMatchingChunks"); var jobHandle = new JobHandle(); // @TODO: Missing EntityQuery.SyncFilter using (var chunks = ComponentChunkIterator.CreateArchetypeChunkArray(archetypeList, Allocator.TempJob, out jobHandle, ref filter)) { jobHandle.Complete(); Profiler.EndSample(); if (chunks.Length != 0) { BeforeStructuralChange(); Profiler.BeginSample("EditorOnlyChecks"); EntityComponentStore->AssertCanDestroy(chunks); EntityComponentStore->AssertWillDestroyAllInLinkedEntityGroup(chunks, GetArchetypeChunkBufferType <LinkedEntityGroup>(false)); Profiler.EndSample(); // #todo @macton DestroyEntities should support IJobChunk. But internal writes need to be handled. Profiler.BeginSample("DeleteChunks"); new DestroyChunks { EntityComponentStore = EntityComponentStore, Chunks = chunks }.Run(); Profiler.EndSample(); Profiler.BeginSample("Managed Playback"); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); Profiler.EndSample(); } } Profiler.EndSample(); }
/// <summary> /// Filters out entities in chunks for which the specified components have not changed. /// </summary> /// <remarks> /// Saves given ComponentTypes' indices in RequiredComponents in this group's Changed filter. /// </remarks> /// <param name="componentType">Array of up to two ComponentTypes to mark as changed on this EntityQuery's filter.</param> public void SetFilterChanged(ComponentType[] componentType) { if (componentType.Length > EntityQueryFilter.ChangedFilter.Capacity) { throw new ArgumentException( $"EntityQuery.SetFilterChanged accepts a maximum of {EntityQueryFilter.ChangedFilter.Capacity} component array length"); } if (componentType.Length <= 0) { throw new ArgumentException( $"EntityQuery.SetFilterChanged component array length must be larger than 0"); } var filter = new EntityQueryFilter(); filter.Type = FilterType.Changed; filter.Changed.Count = componentType.Length; for (var i = 0; i != componentType.Length; i++) { filter.Changed.IndexInEntityQuery[i] = GetIndexInEntityQuery(componentType[i].TypeIndex); } SetFilter(ref filter); }
/// <summary> /// Creates a NativeArray with all the chunks in a given archetype filtered by the provided EntityQueryFilter. /// This function will not sync the needed types in the EntityQueryFilter so they have to be synced manually before calling this function. /// </summary> /// <param name="matchingArchetypes">List of matching archetypes.</param> /// <param name="allocator">Allocator to use for the array.</param> /// <param name="jobHandle">Handle to the GatherChunks job used to fill the output array.</param> /// <param name="filter">Filter used to filter the resulting chunks</param> /// <param name="dependsOn">All jobs spawned will depend on this JobHandle</param> /// <returns>NativeArray of all the chunks in the matchingArchetypes list.</returns> public static NativeArray <ArchetypeChunk> CreateArchetypeChunkArrayAsync(UnsafeMatchingArchetypePtrList matchingArchetypes, Allocator allocator, out JobHandle jobHandle, ref EntityQueryFilter filter, JobHandle dependsOn = default(JobHandle)) { var archetypeCount = matchingArchetypes.Length; var offsets = new NativeArray <int>(archetypeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var chunkCount = 0; { for (int i = 0; i < matchingArchetypes.Length; ++i) { var archetype = matchingArchetypes.Ptr[i]->Archetype; offsets[i] = chunkCount; chunkCount += archetype->Chunks.Count; } } if (!filter.RequiresMatchesFilter) { var chunks = new NativeArray <ArchetypeChunk>(chunkCount, allocator, NativeArrayOptions.UninitializedMemory); var gatherChunksJob = new GatherChunksJob { MatchingArchetypes = matchingArchetypes.Ptr, entityComponentStore = matchingArchetypes.entityComponentStore, Offsets = offsets, Chunks = chunks }; jobHandle = gatherChunksJob.Schedule(archetypeCount, 1, dependsOn); return(chunks); } else { var filteredCounts = new NativeArray <int>(archetypeCount + 1, Allocator.TempJob); var sparseChunks = new NativeArray <ArchetypeChunk>(chunkCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var gatherChunksJob = new GatherChunksWithFilteringJob { MatchingArchetypes = matchingArchetypes.Ptr, Filter = filter, Offsets = offsets, FilteredCounts = filteredCounts, SparseChunks = sparseChunks, entityComponentStore = matchingArchetypes.entityComponentStore }; gatherChunksJob.Schedule(archetypeCount, 1, dependsOn).Complete(); // accumulated filtered counts: filteredCounts[i] becomes the destination offset int totalChunks = 0; for (int i = 0; i < archetypeCount; ++i) { int currentCount = filteredCounts[i]; filteredCounts[i] = totalChunks; totalChunks += currentCount; } filteredCounts[archetypeCount] = totalChunks; var joinedChunks = new NativeArray <ArchetypeChunk>(totalChunks, allocator, NativeArrayOptions.UninitializedMemory); jobHandle = new JoinChunksJob { DestinationOffsets = filteredCounts, SparseChunks = sparseChunks, Offsets = offsets, JoinedChunks = joinedChunks }.Schedule(archetypeCount, 1); return(joinedChunks); } }
void DestroyEntity(UnsafeMatchingArchetypePtrList archetypeList, EntityQueryFilter filter) { var access = GetCheckedEntityDataAccess(); access->DestroyEntity(archetypeList, filter); }
public bool MatchesFilter(MatchingArchetype *match, ref EntityQueryFilter filter) { return(match->ChunkMatchesFilter(ListIndex, ref filter)); }
/// <summary> /// Total number of entities contained in a given MatchingArchetype list. /// </summary> /// <param name="matchingArchetypes">List of matching archetypes.</param> /// <param name="filter">EntityQueryFilter to use when calculating total number of entities.</param> /// <returns>Number of entities</returns> public static int CalculateLength(MatchingArchetypeList matchingArchetypes, ref EntityQueryFilter filter) { var filterCopy = filter; // Necessary to avoid a nasty compiler error cause by fixed buffer types var length = 0; if (!filter.RequiresMatchesFilter) { for (var m = matchingArchetypes.Count - 1; m >= 0; --m) { var match = matchingArchetypes.p[m]; length += match->Archetype->EntityCount; } } else { for (var m = matchingArchetypes.Count - 1; m >= 0; --m) { var match = matchingArchetypes.p[m]; if (match->Archetype->EntityCount <= 0) { continue; } int filteredCount = 0; var archetype = match->Archetype; int chunkCount = archetype->Chunks.Count; var chunkEntityCountArray = archetype->Chunks.GetChunkEntityCountArray(); if (filter.Type == FilterType.SharedComponent) { var indexInEntityQuery0 = filterCopy.Shared.IndexInEntityQuery[0]; var sharedComponentIndex0 = filterCopy.Shared.SharedComponentIndex[0]; var componentIndexInChunk0 = match->IndexInArchetype[indexInEntityQuery0] - archetype->FirstSharedComponent; var sharedComponents0 = archetype->Chunks.GetSharedComponentValueArrayForType(componentIndexInChunk0); if (filter.Shared.Count == 1) { for (var i = 0; i < chunkCount; ++i) { if (sharedComponents0[i] == sharedComponentIndex0) { filteredCount += chunkEntityCountArray[i]; } } } else { var indexInEntityQuery1 = filterCopy.Shared.IndexInEntityQuery[1]; var sharedComponentIndex1 = filterCopy.Shared.SharedComponentIndex[1]; var componentIndexInChunk1 = match->IndexInArchetype[indexInEntityQuery1] - archetype->FirstSharedComponent; var sharedComponents1 = archetype->Chunks.GetSharedComponentValueArrayForType(componentIndexInChunk1); for (var i = 0; i < chunkCount; ++i) { if (sharedComponents0[i] == sharedComponentIndex0 && sharedComponents1[i] == sharedComponentIndex1) { filteredCount += chunkEntityCountArray[i]; } } } } else { var indexInEntityQuery0 = filterCopy.Changed.IndexInEntityQuery[0]; var componentIndexInChunk0 = match->IndexInArchetype[indexInEntityQuery0]; var changeVersions0 = archetype->Chunks.GetChangeVersionArrayForType(componentIndexInChunk0); var requiredVersion = filter.RequiredChangeVersion; if (filter.Changed.Count == 1) { for (var i = 0; i < chunkCount; ++i) { if (ChangeVersionUtility.DidChange(changeVersions0[i], requiredVersion)) { filteredCount += chunkEntityCountArray[i]; } } } else { var indexInEntityQuery1 = filterCopy.Changed.IndexInEntityQuery[1]; var componentIndexInChunk1 = match->IndexInArchetype[indexInEntityQuery1]; var changeVersions1 = archetype->Chunks.GetChangeVersionArrayForType(componentIndexInChunk1); for (var i = 0; i < chunkCount; ++i) { if (ChangeVersionUtility.DidChange(changeVersions0[i], requiredVersion) || ChangeVersionUtility.DidChange(changeVersions1[i], requiredVersion)) { filteredCount += chunkEntityCountArray[i]; } } } } length += filteredCount; } } return(length); }
internal static JobHandle PreparePrefilteredChunkLists(int unfilteredChunkCount, MatchingArchetypeList archetypes, EntityQueryFilter filter, JobHandle dependsOn, ScheduleMode mode, out NativeArray <byte> prefilterDataArray, out void *deferredCountData) { // Allocate one buffer for all prefilter data and distribute it // We keep the full buffer as a "dummy array" so we can deallocate it later with [DeallocateOnJobCompletion] var sizeofChunkArray = sizeof(ArchetypeChunk) * unfilteredChunkCount; var sizeofIndexArray = sizeof(int) * unfilteredChunkCount; var prefilterDataSize = sizeofChunkArray + sizeofIndexArray + sizeof(int); var prefilterData = (byte *)UnsafeUtility.Malloc(prefilterDataSize, 64, Allocator.TempJob); prefilterDataArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(prefilterData, prefilterDataSize, Allocator.TempJob); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref prefilterDataArray, AtomicSafetyHandle.Create()); #endif JobHandle prefilterHandle = default(JobHandle); if (filter.RequiresMatchesFilter) { var prefilteringJob = new GatherChunksAndOffsetsWithFilteringJob { Archetypes = archetypes, Filter = filter, PrefilterData = prefilterData, UnfilteredChunkCount = unfilteredChunkCount }; if (mode == ScheduleMode.Batched) { prefilterHandle = prefilteringJob.Schedule(dependsOn); } else { prefilteringJob.Run(); } } else { var gatherJob = new GatherChunksAndOffsetsJob { Archetypes = archetypes, PrefilterData = prefilterData, UnfilteredChunkCount = unfilteredChunkCount }; if (mode == ScheduleMode.Batched) { prefilterHandle = gatherJob.Schedule(dependsOn); } else { gatherJob.Run(); } } // ScheduleParallelForDeferArraySize expects a ptr to a structure with a void* and a count. // It only uses the count, so this is safe to fudge deferredCountData = prefilterData + sizeofChunkArray + sizeofIndexArray; deferredCountData = (byte *)deferredCountData - sizeof(void *); return(prefilterHandle); }
void DestroyEntity(UnsafeMatchingArchetypePtrList archetypeList, EntityQueryFilter filter) { m_EntityDataAccess.DestroyEntity(archetypeList, filter); }
public void RemoveComponentWithValidation(UnsafeMatchingArchetypePtrList archetypeList, EntityQueryFilter filter, ComponentType componentType, ComponentDependencyManager *dependencyManager) { var chunks = ChunkIterationUtility.CreateArchetypeChunkArray(archetypeList, Collections.Allocator.TempJob, ref filter, dependencyManager); RemoveComponentWithValidation(chunks, componentType); chunks.Dispose(); }
public void AddComponentWithValidation(UnsafeMatchingArchetypePtrList archetypeList, EntityQueryFilter filter, ComponentType componentType, ComponentDependencyManager *dependencyManager) { AssertCanAddComponent(archetypeList, componentType); var chunks = ChunkIterationUtility.CreateArchetypeChunkArray(archetypeList, Collections.Allocator.TempJob, ref filter, dependencyManager); if (chunks.Length > 0) { //@TODO the fast path for a chunk that contains a single entity is only possible if the chunk doesn't have a Locked Entity Order //but we should still be allowed to add zero sized components to chunks with a Locked Entity Order, even ones that only contain a single entity /* * if ((chunks.Length == 1) && (chunks[0].Count == 1)) * { * var entityPtr = (Entity*) chunks[0].m_Chunk->Buffer; * StructuralChange.AddComponentEntity(EntityComponentStore, entityPtr, componentType.TypeIndex); * } * else * { */ AddComponent((ArchetypeChunk *)NativeArrayUnsafeUtility.GetUnsafePtr(chunks), chunks.Length, componentType); /* * } */ } chunks.Dispose(); }