public void SetFilter(ArchetypeManager typeManager, ComponentGroupFilter filter)
        {
            Assert.IsTrue(filter.FilterCount <= 2 && filter.FilterCount >= 0);

            ResetFilter(typeManager);
            m_Filter = filter;
        }
Esempio n. 2
0
        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();
        }
Esempio n. 3
0
 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;
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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;
 }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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;
 }
Esempio n. 10
0
 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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 15
0
        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);
        }
Esempio n. 17
0
        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);
        }
Esempio n. 18
0
        /// <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);
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
        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);
        }
Esempio n. 21
0
        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);
        }
Esempio n. 22
0
        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);
        }
Esempio n. 23
0
 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);
        }
Esempio n. 25
0
 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);
            }
        }
Esempio n. 28
0
        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);
        }