示例#1
0
        public void Execute()
        {
            var batchCounter = 0;

            for (var m = 0; m < MatchingArchetypes.Length; ++m)
            {
                var match = MatchingArchetypes.Ptr[m];
                if (match->Archetype->EntityCount <= 0)
                {
                    continue;
                }

                var archetype  = match->Archetype;
                int chunkCount = archetype->Chunks.Count;

                for (int chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
                {
                    var chunk = archetype->Chunks.p[chunkIndex];
                    for (int batchIndex = 0; batchIndex < BatchesPerChunk; ++batchIndex)
                    {
                        if (match->ChunkMatchesFilter(chunkIndex, ref Filter))
                        {
                            Batches[batchCounter++] = ArchetypeChunk.EntityBatchFromChunk(chunk, BatchesPerChunk, batchIndex, EntityComponentStore);
                        }
                    }
                }
            }
        }
            internal unsafe static void ExecuteInternal(
                ref JobEntityBatchWrapper <T> jobWrapper,
                ref JobRanges ranges,
                int jobIndex)
            {
                var chunks = jobWrapper.CachedChunks;

                bool isParallel  = jobWrapper.IsParallel == 1;
                bool isFiltering = jobWrapper.Filter.RequiresMatchesFilter;

                while (true)
                {
                    int beginBatchIndex = 0;
                    int endBatchIndex   = chunks.Length;

                    // If we are running the job in parallel, steal some work.
                    if (isParallel)
                    {
                        // If we have no range to steal, exit the loop.
                        if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out beginBatchIndex, out endBatchIndex))
                        {
                            break;
                        }
                    }

                    // Do the actual user work.
                    for (int batchIndex = beginBatchIndex; batchIndex < endBatchIndex; ++batchIndex)
                    {
                        var chunkIndex        = batchIndex / jobWrapper.JobsPerChunk;
                        var batchIndexInChunk = batchIndex % jobWrapper.JobsPerChunk;
                        var chunk             = chunks.Ptr[chunkIndex];

                        if (isFiltering && chunk->MatchesFilter(jobWrapper.MatchingArchetypes.Ptr[chunks.PerChunkMatchingArchetypeIndex.Ptr[chunkIndex]], ref jobWrapper.Filter))
                        {
                            continue;
                        }

                        jobWrapper.JobData.Execute(ArchetypeChunk.EntityBatchFromChunk(chunk, jobWrapper.JobsPerChunk, batchIndexInChunk, chunks.EntityComponentStore), batchIndex);
                    }

                    // If we are not running in parallel, our job is done.
                    if (!isParallel)
                    {
                        break;
                    }
                }
            }
        public void Execute()
        {
            var batches       = (ArchetypeChunk *)PrefilterData;
            var entityIndices = (int *)(batches + FilteredChunkCount * BatchesPerChunk);

            var filteredBatchCounter = 0;
            var entityIndexAggregate = 0;

            for (var m = 0; m < MatchingArchetypes.Length; ++m)
            {
                var match = MatchingArchetypes.Ptr[m];
                if (match->Archetype->EntityCount <= 0)
                {
                    continue;
                }

                var archetype  = match->Archetype;
                int chunkCount = archetype->Chunks.Count;

                for (int chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
                {
                    var chunk = archetype->Chunks[chunkIndex];
                    for (int batchIndex = 0; batchIndex < BatchesPerChunk; ++batchIndex)
                    {
                        if (match->ChunkMatchesFilter(chunkIndex, ref Filter))
                        {
                            var batch = ArchetypeChunk.EntityBatchFromChunk(chunk, BatchesPerChunk, batchIndex, EntityComponentStore);
                            batches[filteredBatchCounter]       = batch;
                            entityIndices[filteredBatchCounter] = entityIndexAggregate;

                            ++filteredBatchCounter;
                            entityIndexAggregate += batch.BatchEntityCount;
                        }
                    }
                }
            }

            var chunkCounter = entityIndices + FilteredChunkCount * BatchesPerChunk;

            *chunkCounter = filteredBatchCounter;
        }
            internal unsafe static void ExecuteInternal(
                ref JobEntityBatchWrapper <T> jobWrapper,
                IntPtr bufferRangePatchData,
                ref JobRanges ranges,
                int jobIndex)
            {
                var chunks          = jobWrapper.CachedChunks;
                var prebuiltBatches = (ArchetypeChunk *)jobWrapper.PrebuiltBatchList.Ptr;

                bool isParallel  = jobWrapper.IsParallel == 1;
                bool isFiltering = jobWrapper.Filter.RequiresMatchesFilter;

                while (true)
                {
                    int beginBatchIndex = 0;
                    int endBatchIndex   = jobWrapper.UsePrebuiltBatchList == 1 ? jobWrapper.PrebuiltBatchList.Length : chunks.Length;

                    // If we are running the job in parallel, steal some work.
                    if (isParallel)
                    {
                        // If we have no range to steal, exit the loop.
                        if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out beginBatchIndex, out endBatchIndex))
                        {
                            break;
                        }

                        JobsUtility.PatchBufferMinMaxRanges(bufferRangePatchData, UnsafeUtility.AddressOf(ref jobWrapper), 0, 0);
                    }

                    // Do the actual user work.
                    if (jobWrapper.UsePrebuiltBatchList == 1)
                    {
                        for (int batchIndex = beginBatchIndex; batchIndex < endBatchIndex; ++batchIndex)
                        {
                            var batch = prebuiltBatches[batchIndex];

                            if (isFiltering && !batch.m_Chunk->MatchesFilter(jobWrapper.MatchingArchetypes.Ptr[jobWrapper.PrebuiltBatchListMatchingArchetypeIndices.Ptr[batchIndex]], ref jobWrapper.Filter))
                            {
                                continue;
                            }

                            Assert.AreNotEqual(0, batch.Count);
                            jobWrapper.JobData.Execute(batch, batchIndex);
                        }
                    }
                    else
                    {
                        if (jobWrapper.JobsPerChunk == 1)
                        {
                            // 1 batch per chunk, with/without filtering
                            for (int batchIndex = beginBatchIndex; batchIndex < endBatchIndex; ++batchIndex)
                            {
                                var chunkIndex = batchIndex;
                                var chunk      = chunks.Ptr[chunkIndex];

                                if (isFiltering && !chunk->MatchesFilter(jobWrapper.MatchingArchetypes.Ptr[chunks.PerChunkMatchingArchetypeIndex.Ptr[chunkIndex]], ref jobWrapper.Filter))
                                {
                                    continue;
                                }

                                var batch = new ArchetypeChunk(chunk, chunks.EntityComponentStore);
                                Assert.AreNotEqual(0, batch.Count);
                                jobWrapper.JobData.Execute(batch, batchIndex);
                            }
                        }
                        else
                        {
                            // 2+ batches per chunk, with/without filtering
                            // This is the most general case; if only one code path survives, it should be this one.
                            for (int batchIndex = beginBatchIndex; batchIndex < endBatchIndex; ++batchIndex)
                            {
                                var chunkIndex        = batchIndex / jobWrapper.JobsPerChunk;
                                var batchIndexInChunk = batchIndex % jobWrapper.JobsPerChunk;
                                var chunk             = chunks.Ptr[chunkIndex];

                                if (isFiltering && !chunk->MatchesFilter(
                                        jobWrapper.MatchingArchetypes.Ptr[
                                            chunks.PerChunkMatchingArchetypeIndex.Ptr[chunkIndex]],
                                        ref jobWrapper.Filter))
                                {
                                    continue;
                                }

                                if (ArchetypeChunk.EntityBatchFromChunk(chunk, chunk->Count, jobWrapper.JobsPerChunk,
                                                                        batchIndexInChunk, chunks.EntityComponentStore, out var batch))
                                {
                                    jobWrapper.JobData.Execute(batch, batchIndex);
                                }
                            }
                        }
                    }

                    // If we are not running in parallel, our job is done.
                    if (!isParallel)
                    {
                        break;
                    }
                }
            }
示例#5
0
        public void Execute()
        {
            var batches       = (ArchetypeChunk *)PrefilterData;
            var entityIndices = (int *)(batches + FilteredChunkCount * BatchesPerChunk);

            var filteredBatchCounter = 0;
            var entityIndexAggregate = 0;

            if (BatchesPerChunk == 1)
            {
                if (Filter.RequiresMatchesFilter)
                {
                    // one batch per chunk, filtering enabled
                    for (var m = 0; m < MatchingArchetypes.Length; ++m)
                    {
                        var match = MatchingArchetypes.Ptr[m];
                        if (match->Archetype->EntityCount <= 0)
                        {
                            continue;
                        }

                        var archetype             = match->Archetype;
                        int chunkCount            = archetype->Chunks.Count;
                        var chunkEntityCountArray = archetype->Chunks.GetChunkEntityCountArray();

                        for (int chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
                        {
                            var chunk = archetype->Chunks[chunkIndex];
                            if (match->ChunkMatchesFilter(chunkIndex, ref Filter))
                            {
                                var batch = new ArchetypeChunk(chunk, EntityComponentStore);
                                batches[filteredBatchCounter]       = batch;
                                entityIndices[filteredBatchCounter] = entityIndexAggregate;

                                ++filteredBatchCounter;
                                entityIndexAggregate += chunkEntityCountArray[chunkIndex];
                            }
                        }
                    }
                }
                else
                {
                    // one batch per chunk, filtering disabled
                    for (var m = 0; m < MatchingArchetypes.Length; ++m)
                    {
                        var match = MatchingArchetypes.Ptr[m];
                        if (match->Archetype->EntityCount <= 0)
                        {
                            continue;
                        }

                        var archetype             = match->Archetype;
                        int chunkCount            = archetype->Chunks.Count;
                        var chunkEntityCountArray = archetype->Chunks.GetChunkEntityCountArray();

                        for (int chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
                        {
                            var chunk = archetype->Chunks[chunkIndex];
                            var batch = new ArchetypeChunk(chunk, EntityComponentStore);
                            batches[filteredBatchCounter]       = batch;
                            entityIndices[filteredBatchCounter] = entityIndexAggregate;

                            ++filteredBatchCounter;
                            entityIndexAggregate += chunkEntityCountArray[chunkIndex];
                        }
                    }
                }
            }
            else
            {
                if (Filter.RequiresMatchesFilter)
                {
                    // 2+ batches per chunk, filtering enabled.
                    // This is the most general case; if only one code path survives, it should be this one.
                    for (var m = 0; m < MatchingArchetypes.Length; ++m)
                    {
                        var match = MatchingArchetypes.Ptr[m];
                        if (match->Archetype->EntityCount <= 0)
                        {
                            continue;
                        }

                        var archetype             = match->Archetype;
                        int chunkCount            = archetype->Chunks.Count;
                        var chunkEntityCountArray = archetype->Chunks.GetChunkEntityCountArray();

                        for (int chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
                        {
                            if (match->ChunkMatchesFilter(chunkIndex, ref Filter))
                            {
                                var chunk            = archetype->Chunks[chunkIndex];
                                var chunkEntityCount = chunkEntityCountArray[chunkIndex];
                                for (int batchIndex = 0; batchIndex < BatchesPerChunk; ++batchIndex)
                                {
                                    if (ArchetypeChunk.EntityBatchFromChunk(chunk, chunkEntityCount, BatchesPerChunk,
                                                                            batchIndex, EntityComponentStore, out var batch))
                                    {
                                        batches[filteredBatchCounter]       = batch;
                                        entityIndices[filteredBatchCounter] = entityIndexAggregate;

                                        ++filteredBatchCounter;
                                        entityIndexAggregate += batch.Count;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // 2+ batches per chunk, filtering disabled
                    for (var m = 0; m < MatchingArchetypes.Length; ++m)
                    {
                        var match = MatchingArchetypes.Ptr[m];
                        if (match->Archetype->EntityCount <= 0)
                        {
                            continue;
                        }

                        var archetype             = match->Archetype;
                        int chunkCount            = archetype->Chunks.Count;
                        var chunkEntityCountArray = archetype->Chunks.GetChunkEntityCountArray();

                        for (int chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
                        {
                            var chunk            = archetype->Chunks[chunkIndex];
                            var chunkEntityCount = chunkEntityCountArray[chunkIndex];
                            for (int batchIndex = 0; batchIndex < BatchesPerChunk; ++batchIndex)
                            {
                                if (ArchetypeChunk.EntityBatchFromChunk(chunk, chunkEntityCount, BatchesPerChunk,
                                                                        batchIndex, EntityComponentStore, out var batch))
                                {
                                    batches[filteredBatchCounter]       = batch;
                                    entityIndices[filteredBatchCounter] = entityIndexAggregate;

                                    ++filteredBatchCounter;
                                    entityIndexAggregate += batch.Count;
                                }
                            }
                        }
                    }
                }
            }

            var chunkCounter = entityIndices + FilteredChunkCount * BatchesPerChunk;

            *chunkCounter = filteredBatchCounter;
        }