Exemple #1
0
        /// <inheritdoc />
        public void RemoveChunk(ChunkCoordinates position, bool dispose = true)
        {
            BlockLightCalculations.Remove(position);
            UpdateQueue.Remove(position);
            UpdateBorderQueue.Remove(position);
            FastUpdateQueue.Remove(position);
            Scheduled.Remove(position);

            if (Chunks.TryRemove(position, out var column))
            {
                foreach (var blockEntity in column.GetBlockEntities)
                {
                    World.EntityManager.RemoveBlockEntity(
                        new BlockCoordinates((column.X << 4) + blockEntity.X, blockEntity.Y, (column.Z << 4) + blockEntity.Z));
                }

                if (dispose)
                {
                    column.Dispose();
                }
            }
        }
Exemple #2
0
        private bool ProcessQueue()
        {
            var maxThreads = Options.VideoOptions.ChunkThreads.Value;

            if (Interlocked.Read(ref _threadsRunning) >= maxThreads)
            {
                return(false);
            }

            FancyQueue <ChunkCoordinates> queue = FastUpdateQueue;

            if (queue.IsEmpty)
            {
                queue = UpdateQueue;
            }

            if (queue.IsEmpty)
            {
                queue = UpdateBorderQueue;
            }

            //maxThreads = Math.Max(1, Math.Min(Options.VideoOptions.ChunkThreads, EnqueuedChunkUpdates / 4));

            if (queue.IsEmpty || Interlocked.Read(ref _threadsRunning) >= maxThreads)
            {
                return(false);
            }

            //if (Interlocked.Read(ref _threadsRunning) )

            Interlocked.Increment(ref _threadsRunning);

            ThreadPool.QueueUserWorkItem(
                oo =>
            {
                try
                {
                    while (!CancellationToken.IsCancellationRequested && queue.TryDequeue(out var chunkCoordinates, cc => IsWithinView(cc, World.Camera)))
                    {
                        if (TryGetChunk(chunkCoordinates, out var chunk))
                        {
                            if (!Monitor.TryEnter(chunk.UpdateLock, 0))
                            {
                                continue;
                            }

                            try
                            {
                                bool newChunk = chunk.IsNew;

                                if (BlockLightCalculations != null)
                                {
                                    if (newChunk)
                                    {
                                        //BlockLightCalculations.Recalculate(chunk);
                                    }
                                    if (BlockLightCalculations.HasEnqueued(chunkCoordinates))
                                    {
                                        BlockLightCalculations.Process(chunkCoordinates);
                                    }
                                }

                                //SkyLightCalculator.TryProcess(chunkCoordinates);

                                if (SkyLightCalculator != null)
                                {
                                    if (newChunk)
                                    {
                                        SkyLightCalculator.RecalcSkyLight(chunk, World);
                                    }
                                }

                                chunk.UpdateBuffer(Graphics, World);

                                /*	if (newChunk)
                                 *      {
                                 *              ScheduleChunkUpdate(new ChunkCoordinates(chunk.X + 1, chunk.Z), ScheduleType.Border);
                                 *              ScheduleChunkUpdate(new ChunkCoordinates(chunk.X - 1, chunk.Z), ScheduleType.Border);
                                 *              ScheduleChunkUpdate(new ChunkCoordinates(chunk.X, chunk.Z + 1), ScheduleType.Border);
                                 *              ScheduleChunkUpdate(new ChunkCoordinates(chunk.X, chunk.Z - 1), ScheduleType.Border);
                                 *      }*/
                            }
                            finally
                            {
                                Scheduled.Remove(chunkCoordinates);
                                Monitor.Exit(chunk.UpdateLock);
                            }
                        }

                        if (queue != FastUpdateQueue && !FastUpdateQueue.IsEmpty)
                        {
                            queue = FastUpdateQueue;
                        }
                        else if (queue == FastUpdateQueue && FastUpdateQueue.IsEmpty)
                        {
                            queue = UpdateQueue;
                        }
                        else if (queue == UpdateBorderQueue && !UpdateQueue.IsEmpty)
                        {
                            queue = UpdateQueue;
                        }
                        else if (queue == UpdateQueue && UpdateQueue.IsEmpty)
                        {
                            queue = UpdateBorderQueue;
                        }
                    }
                }
                finally
                {
                    Interlocked.Decrement(ref _threadsRunning);
                }
            });

            return(true);
        }