public void SetFilter(ArchetypeManager typeManager, ComponentGroupFilter filter) { Assert.IsTrue(filter.FilterCount <= 2 && filter.FilterCount >= 0); ResetFilter(typeManager); m_Filter = filter; }
internal void GetComponentChunkIterators(ForEachComponentGroupFilter forEachFilter) { var numFilters = forEachFilter.SharedComponentIndex.Length; var firstArchetype = new NativeArray <IntPtr>(numFilters, Allocator.Temp); var firstNonEmptyChunk = new NativeArray <IntPtr>(numFilters, Allocator.Temp); ComponentChunkIterator.CalculateInitialChunkIterators(m_GroupData->FirstMatchingArchetype, forEachFilter.IndexInComponentGroup, forEachFilter.SharedComponentIndex, firstArchetype, firstNonEmptyChunk, forEachFilter.ItemLength); for (var i = 0; i < numFilters; ++i) { var filter = new ComponentGroupFilter(); filter.Type = FilterType.SharedComponent; filter.Shared.Count = 1; filter.Shared.IndexInComponentGroup[0] = forEachFilter.IndexInComponentGroup; filter.Shared.SharedComponentIndex[0] = forEachFilter.SharedComponentIndex[i]; forEachFilter.ItemIterator[i] = new ComponentChunkIterator((MatchingArchetypes *)firstArchetype[i], m_EntityDataManager->GlobalSystemVersion, ref filter); } firstArchetype.Dispose(); firstNonEmptyChunk.Dispose(); }
internal ComponentGroup(EntityGroupData *groupData, ComponentJobSafetyManager safetyManager, ArchetypeManager typeManager, EntityDataManager *entityDataManager) { m_GroupData = groupData; m_EntityDataManager = entityDataManager; m_Filter = default(ComponentGroupFilter); m_SafetyManager = safetyManager; ArchetypeManager = typeManager; EntityDataManager = entityDataManager; }
public void SetFilter(NativeArray <int> indexList) { var filter = new ComponentGroupFilter(); filter.Type = FilterType.IndexList; filter.Indices.Length = indexList.Length; filter.Indices.Indices = (int *)indexList.GetUnsafeReadOnlyPtr(); m_ComponentGroupData.SetFilter(ArchetypeManager, ref filter); }
public void SetFilter(ArchetypeManager typeManager, ref ComponentGroupFilter filter) { #if ENABLE_UNITY_COLLECTIONS_CHECKS filter.AssertValid(); #endif var version = m_Filter.RequiredChangeVersion; ResetFilter(typeManager); m_Filter = filter; m_Filter.RequiredChangeVersion = version; }
public ComponentChunkIterator(MatchingArchetypes *match, int length, Chunk *firstChunk, ComponentGroupFilter filter) { m_FirstMatchingArchetype = match; m_CurrentMatchingArchetype = match; IndexInComponentGroup = -1; m_CurrentArchetypeIndex = 0; m_CurrentChunk = firstChunk; m_CurrentChunkIndex = 0; m_Filter = filter; }
public void SetFilterChanged(ComponentType componentType) { var filter = new ComponentGroupFilter(); filter.Type = FilterType.Changed; filter.Changed.Count = 1; filter.Changed.IndexInComponentGroup[0] = GetIndexInComponentGroup(componentType.TypeIndex); m_ComponentGroupData.SetFilter(ArchetypeManager, ref filter); }
public void SetFilterChanged(ComponentType componentType) { var filter = new ComponentGroupFilter(); filter.Type = FilterType.Changed; filter.Changed.Count = 1; filter.Changed.IndexInComponentGroup[0] = GetIndexInComponentGroup(componentType.TypeIndex); SetFilter(ref filter); }
public unsafe ComponentChunkIterator(MatchingArchetypes *match, uint globalSystemVersion, ref ComponentGroupFilter filter) { this.m_FirstMatchingArchetype = match; this.m_CurrentMatchingArchetype = match; this.IndexInComponentGroup = -1; this.m_CurrentChunk = null; this.m_CurrentArchetypeIndex = this.m_CurrentArchetypeEntityIndex = 0x7fffffff; this.m_CurrentChunkIndex = this.m_CurrentChunkEntityIndex = 0; this.m_GlobalSystemVersion = globalSystemVersion; this.m_Filter = filter; }
public ComponentChunkIterator(MatchingArchetypes *match, uint globalSystemVersion, ref ComponentGroupFilter filter) { m_FirstMatchingArchetype = match; m_CurrentMatchingArchetype = match; IndexInComponentGroup = -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; }
public bool MatchesFilter(MatchingArchetypes *match, ref ComponentGroupFilter filter) { if (filter.Type == FilterType.SharedComponent) { var sharedComponentsInChunk = SharedComponentValueArray; var filteredCount = filter.Shared.Count; fixed(int *indexInComponentGroupPtr = filter.Shared.IndexInComponentGroup, sharedComponentIndexPtr = filter.Shared.SharedComponentIndex) { for (var i = 0; i < filteredCount; ++i) { var indexInComponentGroup = indexInComponentGroupPtr[i]; var sharedComponentIndex = sharedComponentIndexPtr[i]; var componentIndexInArcheType = match->TypeIndexInArchetypeArray[indexInComponentGroup]; var componentIndexInChunk = match->Archetype->SharedComponentOffset[componentIndexInArcheType]; if (sharedComponentsInChunk[componentIndexInChunk] != sharedComponentIndex) { return(false); } } } return(true); } if (filter.Type == FilterType.Changed) { var changedCount = filter.Changed.Count; var requiredVersion = filter.RequiredChangeVersion; fixed(int *indexInComponentGroupPtr = filter.Changed.IndexInComponentGroup) { for (var i = 0; i < changedCount; ++i) { var indexInArchetype = match->TypeIndexInArchetypeArray[indexInComponentGroupPtr[i]]; var changeVersion = ChangeVersion[indexInArchetype]; if (ChangeVersionUtility.DidChange(changeVersion, requiredVersion)) { return(true); } } } return(false); } return(true); }
public void SetFilter <SharedComponent1>(SharedComponent1 sharedComponent1) where SharedComponent1 : struct, ISharedComponentData { var filter = new ComponentGroupFilter(); filter.Type = FilterType.SharedComponent; filter.Shared.Count = 1; filter.Shared.IndexInComponentGroup[0] = GetIndexInComponentGroup(TypeManager.GetTypeIndex <SharedComponent1>()); filter.Shared.SharedComponentIndex[0] = ArchetypeManager.GetSharedComponentDataManager() .InsertSharedComponent(sharedComponent1); m_ComponentGroupData.SetFilter(ArchetypeManager, ref filter); }
public void SetFilter <SharedComponent1>(ref SharedComponent1 sharedComponent1) where SharedComponent1 : struct, ISharedComponentData #if REF_EQUATABLE , IRefEquatable <SharedComponent1> #endif { var sm = ArchetypeManager.GetSharedComponentDataManager(); var filter = new ComponentGroupFilter(); filter.Type = FilterType.SharedComponent; filter.Shared.Count = 1; filter.Shared.IndexInComponentGroup[0] = GetIndexInComponentGroup(TypeManager.GetTypeIndex <SharedComponent1>()); filter.Shared.SharedComponentIndex[0] = sm.InsertSharedComponent(ref sharedComponent1); SetFilter(ref filter); }
public static void CopyFromComponentDataArray <T>(MatchingArchetypeList matchingArchetypes, NativeArray <T> componentDataArray, ArchetypeChunkComponentType <T> type, ComponentGroup componentGroup, ref ComponentGroupFilter filter, out JobHandle jobHandle, JobHandle dependsOn) where T : struct, IComponentData { var job = new CopyComponentArrayToChunks <T> { ComponentData = componentDataArray, ComponentType = type }; jobHandle = job.Schedule(componentGroup, dependsOn); }
public void SetFilter <SharedComponent1, SharedComponent2>(SharedComponent1 sharedComponent1, SharedComponent2 sharedComponent2) where SharedComponent1 : struct, ISharedComponentData where SharedComponent2 : struct, ISharedComponentData { var sm = ArchetypeManager.GetSharedComponentDataManager(); var filter = new ComponentGroupFilter(); filter.Type = FilterType.SharedComponent; filter.Shared.Count = 2; filter.Shared.IndexInComponentGroup[0] = GetIndexInComponentGroup(TypeManager.GetTypeIndex <SharedComponent1>()); filter.Shared.SharedComponentIndex[0] = sm.InsertSharedComponent(sharedComponent1); filter.Shared.IndexInComponentGroup[1] = GetIndexInComponentGroup(TypeManager.GetTypeIndex <SharedComponent2>()); filter.Shared.SharedComponentIndex[1] = sm.InsertSharedComponent(sharedComponent2); SetFilter(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">ComponentGroupFilter to use when calculating total number of entities.</param> /// <returns>Number of entities</returns> public static int CalculateLength(MatchingArchetypeList matchingArchetypes, ref ComponentGroupFilter filter) { // Update the archetype segments 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; } var archeType = match->Archetype; for (var ci = 0; ci < archeType->Chunks.Count; ++ci) { var c = archeType->Chunks.p[ci]; if (!c->MatchesFilter(match, ref filter)) { continue; } Assert.IsTrue(c->Count > 0); length += c->Count; } } } return(length); }
public static NativeArray <T> CreateComponentDataArray <T>(MatchingArchetypes *firstMatchingArchetype, Allocator allocator, ArchetypeChunkComponentType <T> type, ComponentGroup componentGroup, ref ComponentGroupFilter filter, out JobHandle jobHandle, JobHandle dependsOn) where T : struct, IComponentData { var entityCount = CalculateLength(firstMatchingArchetype, ref filter); var job = new GatherComponentDataJob <T> { ComponentData = new NativeArray <T>(entityCount, allocator), ComponentType = type }; jobHandle = job.Schedule(componentGroup, dependsOn); return(job.ComponentData); }
/// <summary> /// Creates a NativeArray containing the entities in a given ComponentGroup. /// </summary> /// <param name="firstMatchingArchetype">First node of MatchingArchetypes linked list.</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="componentGroup">ComponentGroup to gather entities from.</param> /// <param name="filter">ComponentGroupFilter 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 ComponentGroup.</returns> public static NativeArray <Entity> CreateEntityArray(MatchingArchetypes *firstMatchingArchetype, Allocator allocator, ArchetypeChunkEntityType type, ComponentGroup componentGroup, ref ComponentGroupFilter filter, out JobHandle jobHandle, JobHandle dependsOn) { var entityCount = CalculateLength(firstMatchingArchetype, ref filter); var job = new GatherEntitiesJob { EntityType = type, Entities = new NativeArray <Entity>(entityCount, allocator) }; jobHandle = job.Schedule(componentGroup, dependsOn); return(job.Entities); }
public void SetFilterChanged(ComponentType[] componentType) { if (componentType.Length > ComponentGroupFilter.ChangedFilter.Capacity) { throw new ArgumentException( $"ComponentGroup.SetFilterChanged accepts a maximum of {ComponentGroupFilter.ChangedFilter.Capacity} component array length"); } if (componentType.Length <= 0) { throw new ArgumentException( $"ComponentGroup.SetFilterChanged component array length must be larger than 0"); } var filter = new ComponentGroupFilter(); filter.Type = FilterType.Changed; filter.Changed.Count = componentType.Length; for (var i = 0; i != componentType.Length; i++) { filter.Changed.IndexInComponentGroup[i] = GetIndexInComponentGroup(componentType[i].TypeIndex); } m_ComponentGroupData.SetFilter(ArchetypeManager, ref filter); }
public bool MatchesFilter(MatchingArchetypes *match, ref ComponentGroupFilter filter) { var sharedComponentsInChunk = SharedComponentValueArray; var filteredCount = filter.FilterCount; Assert.IsTrue(filteredCount > 0); fixed(int *indexInComponentGroupPtr = filter.IndexInComponentGroup, sharedComponentIndexPtr = filter.SharedComponentIndex) { for (var i = 0; i < filteredCount; ++i) { var indexInComponentGroup = indexInComponentGroupPtr[i]; var sharedComponentIndex = sharedComponentIndexPtr[i]; var componentIndexInArcheType = match->TypeIndexInArchetypeArray[indexInComponentGroup]; var componentIndexInChunk = match->Archetype->SharedComponentOffset[componentIndexInArcheType]; if (sharedComponentsInChunk[componentIndexInChunk] != sharedComponentIndex) { return(false); } } } return(true); }
public unsafe bool MatchesFilter(MatchingArchetypes *match, ref ComponentGroupFilter filter) { bool flag3; if ((filter.Type & FilterType.SharedComponent) != FilterType.None) { int *sharedComponentValueArray = this.SharedComponentValueArray; int count = filter.Shared.Count; int *numPtr2 = &filter.Shared.IndexInComponentGroup.FixedElementField; int *numPtr3 = &filter.Shared.SharedComponentIndex.FixedElementField; int index = 0; while (true) { if (index >= count) { fixed(int **numPtrRef = null) { fixed(int **numPtrRef2 = null) { flag3 = true; } } } else { int num3 = numPtr2[index]; int num4 = numPtr3[index]; int num5 = &match.IndexInArchetype.FixedElementField[num3]; int num6 = match.Archetype.SharedComponentOffset[num5]; if (sharedComponentValueArray[num6] == num4) { index++; continue; } flag3 = false; } break; } } else if ((filter.Type & FilterType.Changed) == FilterType.None) { flag3 = true; } else { int count = filter.Changed.Count; uint requiredChangeVersion = filter.RequiredChangeVersion; int *numPtr4 = &filter.Changed.IndexInComponentGroup.FixedElementField; int index = 0; while (true) { if (index >= count) { fixed(int **numPtrRef3 = null) { flag3 = false; } } else { int num10 = &match.IndexInArchetype.FixedElementField[numPtr4[index]]; uint changeVersion = this.ChangeVersion[num10]; if (!ChangeVersionUtility.DidChange(changeVersion, requiredChangeVersion)) { index++; continue; } flag3 = true; } break; } } return(flag3); }
public static int CalculateLength(MatchingArchetypes *firstMatchingArchetype, ref ComponentGroupFilter filter) { if (filter.Type == FilterType.IndexList) { return(filter.Indices.Length); } // Update the archetype segments var length = 0; if (!filter.RequiresMatchesFilter) { for (var match = firstMatchingArchetype; match != null; match = match->Next) { length += match->Archetype->EntityCount; } } else { for (var match = firstMatchingArchetype; match != null; match = match->Next) { if (match->Archetype->EntityCount <= 0) { continue; } var archeType = match->Archetype; for (var c = (Chunk *)archeType->ChunkList.Begin; c != archeType->ChunkList.End; c = (Chunk *)c->ChunkListNode.Next) { if (!c->MatchesFilter(match, ref filter)) { continue; } Assert.IsTrue(c->Count > 0); length += c->Count; } } } return(length); }
internal void SetFilter(ref ComponentGroupFilter filter) { m_ComponentGroupData.SetFilter(ArchetypeManager, 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">ComponentGroupFilter to use when calculating total number of entities.</param> /// <returns>Number of entities</returns> public static int CalculateLength(MatchingArchetypeList matchingArchetypes, ref ComponentGroupFilter 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 indexInComponentGroup0 = filterCopy.Shared.IndexInComponentGroup[0]; var sharedComponentIndex0 = filterCopy.Shared.SharedComponentIndex[0]; var componentIndexInChunk0 = match->IndexInArchetype[indexInComponentGroup0] - 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 indexInComponentGroup1 = filterCopy.Shared.IndexInComponentGroup[1]; var sharedComponentIndex1 = filterCopy.Shared.SharedComponentIndex[1]; var componentIndexInChunk1 = match->IndexInArchetype[indexInComponentGroup1] - 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 indexInComponentGroup0 = filterCopy.Changed.IndexInComponentGroup[0]; var componentIndexInChunk0 = match->IndexInArchetype[indexInComponentGroup0]; 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 indexInComponentGroup1 = filterCopy.Changed.IndexInComponentGroup[1]; var componentIndexInChunk1 = match->IndexInArchetype[indexInComponentGroup1]; 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 ComponentGroupData(EntityGroupData *groupData, EntityDataManager *entityDataManager) { m_GroupData = groupData; m_EntityDataManager = entityDataManager; m_Filter = default(ComponentGroupFilter); }
public static unsafe int CalculateLength(MatchingArchetypes *firstMatchingArchetype, ref ComponentGroupFilter filter) { int num = 0; if (!filter.RequiresMatchesFilter) { MatchingArchetypes *next = firstMatchingArchetype; while (true) { if (next == null) { break; } num += next->Archetype.EntityCount; next = next->Next; } } else { MatchingArchetypes *match = firstMatchingArchetype; while (true) { if (match == null) { break; } if (match->Archetype.EntityCount > 0) { Archetype *archetype = match->Archetype; Chunk * begin = (Chunk *)archetype->ChunkList.Begin; while (true) { if (begin == archetype->ChunkList.End) { break; } if (begin.MatchesFilter(match, ref filter)) { Assert.IsTrue(begin->Count > 0); num += begin->Count; } begin = (Chunk *)begin->ChunkListNode.Next; } } match = match->Next; } } return(num); }
/// <summary> /// Creates a NativeArray with all the chunks in a given archetype. /// </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> /// <returns>NativeArray of all the chunks in the matchingArchetypes list.</returns> public static NativeArray <ArchetypeChunk> CreateArchetypeChunkArray(MatchingArchetypeList matchingArchetypes, Allocator allocator, out JobHandle jobHandle, ref ComponentGroupFilter filter, JobHandle dependsOn = default(JobHandle)) { var archetypeCount = matchingArchetypes.Count; var offsets = new NativeArray <int>(archetypeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var chunkCount = 0; { for (int i = 0; i < matchingArchetypes.Count; ++i) { var archetype = matchingArchetypes.p[i]->Archetype; offsets[i] = chunkCount; chunkCount += archetype->Chunks.Count; } } if (filter.Type == FilterType.None) { var chunks = new NativeArray <ArchetypeChunk>(chunkCount, allocator, NativeArrayOptions.UninitializedMemory); var gatherChunksJob = new GatherChunks { MatchingArchetypes = matchingArchetypes.p, Offsets = offsets, Chunks = chunks }; var gatherChunksJobHandle = gatherChunksJob.Schedule(archetypeCount, 1, dependsOn); jobHandle = gatherChunksJobHandle; 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 GatherChunksWithFiltering { MatchingArchetypes = matchingArchetypes.p, Filter = filter, Offsets = offsets, FilteredCounts = filteredCounts, SparseChunks = sparseChunks }; 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); } }
public static int CalculateLength(MatchingArchetypes *firstMatchingArchetype, ref ComponentGroupFilter filter) { // Update the archetype segments var length = 0; if (!filter.RequiresMatchesFilter) { for (var match = firstMatchingArchetype; match != null; match = match->Next) { length += match->Archetype->EntityCount; } } else { /* * Can't be enabled yet because a bunch of tests rely on it, need to make some decisions on this... #if ENABLE_UNITY_COLLECTIONS_CHECKS * if ((filter.Type & FilterType.Changed) != 0) * { * throw new System.ArgumentException("CalculateLength() can't be used with change filtering since it requires all component data to have been processed"); * } #endif */ for (var match = firstMatchingArchetype; match != null; match = match->Next) { if (match->Archetype->EntityCount <= 0) { continue; } var archeType = match->Archetype; for (var c = (Chunk *)archeType->ChunkList.Begin; c != archeType->ChunkList.End; c = (Chunk *)c->ChunkListNode.Next) { if (!c->MatchesFilter(match, ref filter)) { continue; } Assert.IsTrue(c->Count > 0); length += c->Count; } } } return(length); }
internal static JobHandle PreparePrefilteredChunkLists(int unfilteredChunkCount, MatchingArchetypeList archetypes, ComponentGroupFilter 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); }