Ejemplo n.º 1
0
            /// <inheritdoc />
            public void Update(EntityManager entityManager)
            {
                if (this.entities.IsCreated)
                {
                    entityManager.DestroyEntity(this.entities);
                    this.entities.Dispose();
                }

                var count = this.GetCount();

                if (count == 0)
                {
                    return;
                }

                // Felt like Temp should be the allocator but gets disposed for some reason.
                this.entities = new NativeArray <Entity>(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                if (!this.archetype.Valid)
                {
                    this.archetype = entityManager.CreateArchetype(typeof(T));
                }

                entityManager.CreateEntity(this.archetype, this.entities);

                JobHandle handle = default;

                var chunkIndex  = new NativeUnit <int>(Allocator.TempJob);
                var entityIndex = new NativeUnit <int>(Allocator.TempJob);

                var componentType = entityManager.GetArchetypeChunkComponentType <T>(false);

                var chunks = entityManager.CreateArchetypeChunkArray(this.query, Allocator.TempJob);

                foreach (var queue in this.queues)
                {
                    handle = new SetJob
                    {
                        Chunks        = chunks,
                        Queue         = queue,
                        ChunkIndex    = chunkIndex,
                        EntityIndex   = entityIndex,
                        ComponentType = componentType,
                    }
                    .Schedule(handle);
                }

                handle.Complete();

                chunks.Dispose();
                chunkIndex.Dispose();
                entityIndex.Dispose();

                foreach (var queue in this.queues)
                {
                    queue.Dispose();
                }

                this.queues.Clear();
            }
            public static JobHandle MergeSlices <T>(
                NativeList <T> result,
                NativeList <T>[] buffers,
                ref SortState state,
                JobHandle inputDeps)
                where T : struct, IComparable <T>
            {
                var proceedToNextBuffer = false;
                var mergeAmount         = state.ProcessAmount * state.ConcurrentSorts;
                var leftIndexUnit       = new NativeUnit <int>(state.LeftIndex, Allocator.TempJob);
                var rightIndexUnit      = new NativeUnit <int>(state.RightIndex, Allocator.TempJob);
                var resultIndexUnit     = new NativeUnit <int>(state.ResultIndex, Allocator.TempJob);

                state.WriteBufferIndex += state.WriteBufferIndex == 0 ? state.BaseSliceCount : 0;
                while (state.WriteBufferIndex < buffers.Length && mergeAmount > 0)
                {
                    var mergeInputDeps = default(JobHandle);
                    if (state.ResultIndex == 0)
                    {
                        mergeInputDeps = buffers[state.WriteBufferIndex].Resize(buffers[state.ReadBufferIndex].Length + buffers[state.ReadBufferIndex + 1].Length, inputDeps);
                    }
                    mergeInputDeps = new Merge <T> {
                        LeftArray     = buffers[state.ReadBufferIndex].AsDeferredJobArray(),
                        RightArray    = buffers[state.ReadBufferIndex + 1].AsDeferredJobArray(),
                        Target        = buffers[state.WriteBufferIndex].AsDeferredJobArray(),
                        LeftIndex     = leftIndexUnit,
                        RightIndex    = rightIndexUnit,
                        ResultIndex   = resultIndexUnit,
                        MaxMergeCount = mergeAmount
                    }.Schedule(mergeInputDeps);
                    mergeInputDeps.Complete();
                    mergeAmount -= resultIndexUnit.Value - state.ResultIndex;
                    // We've reached the end of the write buffer so we can proceed to the next one
                    proceedToNextBuffer = resultIndexUnit.Value == buffers[state.WriteBufferIndex].Length;
                    if (proceedToNextBuffer)
                    {
                        state.ReadBufferIndex += 2;
                        state.WriteBufferIndex++;
                        leftIndexUnit.Value = rightIndexUnit.Value = resultIndexUnit.Value = 0;
                        state.LeftIndex     = state.RightIndex = state.ResultIndex = 0;
                    }
                    else
                    {
                        break;
                    }
                }

                state.LeftIndex   = proceedToNextBuffer ? 0 : leftIndexUnit.Value;
                state.RightIndex  = proceedToNextBuffer ? 0 : rightIndexUnit.Value;
                state.ResultIndex = proceedToNextBuffer ? 0 : resultIndexUnit.Value;

                leftIndexUnit.Dispose();
                rightIndexUnit.Dispose();
                resultIndexUnit.Dispose();
                return(inputDeps);
            }