@@ -94,7 +94,8 @@ public class ChunkManager : IDisposable, ITicked
9494 private ActionBlock < ChunkUpdateData > _actionBlock ;
9595 private PriorityBufferBlock < ChunkUpdateData > _priorityBuffer ;
9696 private List < ChunkCoordinates > _queued = new List < ChunkCoordinates > ( ) ;
97-
97+ private object _queuedLock = new object ( ) ;
98+
9899 public bool CalculateSkyLighting { get ; set ; } = true ;
99100 public bool CalculateBlockLighting { get ; set ; } = true ;
100101
@@ -111,20 +112,9 @@ public ChunkManager(IServiceProvider serviceProvider,
111112 Options = serviceProvider . GetRequiredService < IOptionsProvider > ( ) . AlexOptions ;
112113
113114 _resourceManager = serviceProvider . GetRequiredService < ResourceManager > ( ) ;
114- //var stillAtlas = serviceProvider.GetRequiredService<ResourceManager>().BlockAtlas.GetAtlas();
115115
116116 //var fogStart = 0;
117117 Shaders = new RenderingShaders ( ) ;
118- //Shaders.SetTextures(stillAtlas);
119- /*FogEnabled = Options.VideoOptions.Fog.Value;
120- FogDistance = Options.VideoOptions.RenderDistance.Value;
121- Options.VideoOptions.Fog.Bind(
122- (old, newValue) =>
123- {
124- FogEnabled = newValue;
125- FogDistance = RenderDistance;
126- });*/
127- //_renderSampler.MaxMipLevel = stillAtlas.LevelCount;
128118
129119 Chunks = new ConcurrentDictionary < ChunkCoordinates , ChunkColumn > ( ) ;
130120 CancellationToken = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
@@ -197,7 +187,7 @@ private void BuildActionBlock(int threads)
197187 {
198188 CancellationToken = CancellationToken . Token ,
199189 EnsureOrdered = false ,
200- MaxDegreeOfParallelism = Math . Max ( threads / 3 , 1 ) ,
190+ MaxDegreeOfParallelism = 1 ,
201191 NameFormat = "Chunk Builder: {0}-{1}"
202192 } ;
203193
@@ -332,16 +322,31 @@ public void EnsureStarted()
332322 _processingThread = task ;
333323 }
334324
325+
326+ private bool IsQueued ( ChunkCoordinates coordinates )
327+ {
328+ lock ( _queuedLock )
329+ return _queued . Contains ( coordinates ) ;
330+ }
331+
332+ private void RemoveQueued ( ChunkCoordinates coordinates )
333+ {
334+ lock ( _queuedLock )
335+ {
336+ _queued . Remove ( coordinates ) ;
337+ }
338+ }
339+
335340 private void DoUpdate ( ChunkUpdateData data )
336341 {
337342 Interlocked . Increment ( ref _threadsRunning ) ;
338343
339344 try
340345 {
341- if ( ! TryGetChunk ( data . Coordinates , out var chunk ) || ! chunk . Scheduled ) return ;
342-
343- if ( ! Monitor . TryEnter ( chunk . UpdateLock , 0 ) )
346+ if ( ! TryGetChunk ( data . Coordinates , out var chunk ) || ! chunk . Semaphore . Wait ( 0 ) )
347+ {
344348 return ;
349+ }
345350
346351 Stopwatch timingWatch = Stopwatch . StartNew ( ) ;
347352
@@ -358,24 +363,20 @@ private void DoUpdate(ChunkUpdateData data)
358363 chunk . CalculateLighting = false ;
359364 }
360365
361- //using (var ba = new CachedBlockAccess(World))
362- //{
363- if ( chunk . UpdateBuffer ( World , true ) )
364- {
365- chunk . Scheduled = false ;
366- OnChunkUpdate ? . Invoke ( this , new ChunkUpdatedEventArgs ( chunk , timingWatch . Elapsed ) ) ;
367- }
368- //}
366+ if ( chunk . UpdateBuffer ( World , true ) )
367+ {
368+ OnChunkUpdate ? . Invoke ( this , new ChunkUpdatedEventArgs ( chunk , timingWatch . Elapsed ) ) ;
369+ }
369370 }
370371 finally
371372 {
372- _queued . Remove ( data . Coordinates ) ;
373373 //chunk.Scheduled = false;
374- Monitor . Exit ( chunk . UpdateLock ) ;
374+ chunk . Semaphore . Release ( ) ;
375375 }
376376 }
377377 finally
378378 {
379+ RemoveQueued ( data . Coordinates ) ;
379380 Interlocked . Decrement ( ref _threadsRunning ) ;
380381 }
381382 }
@@ -416,7 +417,8 @@ public void AddChunk(ChunkColumn chunk, ChunkCoordinates position, bool doUpdate
416417
417418 private void OnRemoveChunk ( ChunkColumn column , bool dispose )
418419 {
419- _queued ? . Remove ( new ChunkCoordinates ( column . X , column . Z ) ) ;
420+ RemoveQueued ( new ChunkCoordinates ( column . X , column . Z ) ) ;
421+
420422 OnChunkRemoved ? . Invoke ( this , new ChunkRemovedEventArgs ( column ) ) ;
421423
422424 if ( dispose )
@@ -464,30 +466,36 @@ public void ScheduleChunkUpdate(ChunkCoordinates position,
464466 {
465467 if ( ! Chunks . TryGetValue ( position , out var cc ) ) return ;
466468
467- if ( cc . Scheduled && ! prioritize )
469+ if ( IsQueued ( position ) || ! Monitor . TryEnter ( cc . QueueLock , 0 ) )
468470 return ;
469-
470- cc . Scheduled = true ;
471-
472- //if (!cc.Neighboring.Contains(source))
473- // cc.Neighboring.Add(source);
474-
475- Priority priority = Priority . Medium ;
476-
477- if ( prioritize )
471+
472+ lock ( _queuedLock )
478473 {
479- priority = Priority . High ;
474+ if ( ! _queued . Contains ( position ) )
475+ {
476+ _queued . Add ( position ) ;
477+ }
480478 }
481- else if ( ( type & ScheduleType . Border ) != 0 )
479+
480+ try
482481 {
483- priority = Priority . Low ;
484- }
482+ Priority priority = Priority . Medium ;
485483
486- if ( ! _queued . Contains ( position ) )
487- {
488- _queued . Add ( position ) ;
484+ if ( prioritize )
485+ {
486+ priority = Priority . High ;
487+ }
488+ else if ( ( type & ScheduleType . Border ) != 0 )
489+ {
490+ priority = Priority . Low ;
491+ }
492+
489493 _priorityBuffer . Post ( new ChunkUpdateData ( position , type , source ) , priority ) ;
490494 }
495+ finally
496+ {
497+ Monitor . Exit ( cc . QueueLock ) ;
498+ }
491499 }
492500
493501 #region Drawing
@@ -688,7 +696,7 @@ public void OnTick()
688696
689697 if ( inView && index + 1 < max )
690698 {
691- if ( chunk . Value . IsNew && ! chunk . Value . Scheduled )
699+ if ( chunk . Value . IsNew )
692700 {
693701 ScheduleChunkUpdate ( chunk . Key , ScheduleType . Full ) ;
694702 }
0 commit comments