Exemplo n.º 1
0
        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 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();
        }
Exemplo n.º 3
0
        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);
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        ///     Total number of chunks in a given MatchingArchetype list.
        /// </summary>
        /// <param name="matchingArchetypes">List of matching archetypes.</param>
        /// <returns>Number of chunks in a list of archetypes.</returns>
        internal static int CalculateNumberOfChunksWithoutFiltering(MatchingArchetypeList matchingArchetypes)
        {
            var chunkCount = 0;

            for (var m = matchingArchetypes.Count - 1; m >= 0; --m)
            {
                var match = matchingArchetypes.p[m];
                chunkCount += match->Archetype->Chunks.Count;
            }

            return(chunkCount);
        }
 public ComponentChunkIterator(MatchingArchetypeList match, uint globalSystemVersion,
                               ref ComponentGroupFilter filter)
 {
     m_MatchingArchetypeList         = match;
     m_CurrentMatchingArchetypeIndex = match.Count - 1;
     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;
 }
Exemplo n.º 6
0
        internal void AddSharedComponentDataBoxed(MatchingArchetypeList archetypeList, EntityQueryFilter filter, int typeIndex, int hashCode, object componentData)
        {
            //TODO: optimize this (no need to move the entity to a new chunk twice)

            var newSharedComponentDataIndex = 0;

            if (componentData != null) // null means default
            {
                newSharedComponentDataIndex = ManagedComponentStore.InsertSharedComponentAssumeNonDefault(typeIndex,
                                                                                                          hashCode, componentData);
            }

            AddSharedComponentData(archetypeList, filter, newSharedComponentDataIndex, ComponentType.FromTypeIndex(typeIndex));
        }
Exemplo n.º 7
0
        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>
        ///     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);
        }
Exemplo n.º 9
0
        public static NativeArray <T> CreateComponentDataArray <T>(MatchingArchetypeList matchingArchetypes,
                                                                   Allocator allocator,
                                                                   ArchetypeChunkComponentType <T> type,
                                                                   EntityQuery entityQuery,
                                                                   ref EntityQueryFilter filter,
                                                                   out JobHandle jobHandle,
                                                                   JobHandle dependsOn)
            where T : struct, IComponentData
        {
            var entityCount = CalculateLength(matchingArchetypes, ref filter);

            var job = new GatherComponentDataJob <T>
            {
                ComponentData = new NativeArray <T>(entityCount, allocator),
                ComponentType = type
            };

            jobHandle = job.Schedule(entityQuery, dependsOn);

            return(job.ComponentData);
        }
Exemplo n.º 10
0
        /// <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(MatchingArchetypeList matchingArchetypes,
                                                             Allocator allocator,
                                                             ArchetypeChunkEntityType type,
                                                             EntityQuery entityQuery,
                                                             ref EntityQueryFilter filter,
                                                             out JobHandle jobHandle,
                                                             JobHandle dependsOn)

        {
            var entityCount = CalculateLength(matchingArchetypes, ref filter);

            var job = new GatherEntitiesJob
            {
                EntityType = type,
                Entities   = new NativeArray <Entity>(entityCount, allocator)
            };

            jobHandle = job.Schedule(entityQuery, dependsOn);

            return(job.Entities);
        }
Exemplo n.º 11
0
        /// <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)
        {
            var archetypeCount = matchingArchetypes.Count;

            var archetypes = new NativeArray <EntityArchetype>(archetypeCount, Allocator.TempJob);
            var offsets    = new NativeArray <int>(archetypeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var chunkCount = 0;
            {
                int i      = 0;
                var length = 0;
                for (var m = matchingArchetypes.Count - 1; m >= 0; --m)
                {
                    var match     = matchingArchetypes.p[m];
                    var archetype = match->Archetype;
                    archetypes[i] = new EntityArchetype

                    {
                        Archetype = archetype
                    };
                    offsets[i] = length;
                    length    += archetype->Chunks.Count;
                    i++;
                }
                chunkCount = length;
            }

            var chunks          = new NativeArray <ArchetypeChunk>(chunkCount, allocator, NativeArrayOptions.UninitializedMemory);
            var gatherChunksJob = new GatherChunks
            {
                Archetypes = archetypes,
                Offsets    = offsets,
                Chunks     = chunks
            };
            var gatherChunksJobHandle = gatherChunksJob.Schedule(archetypeCount, 1);

            jobHandle = gatherChunksJobHandle;

            return(chunks);
        }
Exemplo n.º 12
0
        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);
        }
Exemplo n.º 13
0
        /// <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);
        }
Exemplo n.º 14
0
        /// <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 EntityQueryFilter 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);
            }
        }
Exemplo n.º 15
0
 public MatchingArchetypeListDebugView(MatchingArchetypeList MatchingArchetypeList)
 {
     m_MatchingArchetypeList = MatchingArchetypeList;
 }