/// <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(); } } }
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); }