diff --git a/Sources/Voxelotl/ChunkGeneration.swift b/Sources/Voxelotl/ChunkGeneration.swift index c3467cc..aa9267a 100644 --- a/Sources/Voxelotl/ChunkGeneration.swift +++ b/Sources/Voxelotl/ChunkGeneration.swift @@ -14,12 +14,17 @@ public struct ChunkGeneration { self.queue.qualityOfService = .userInitiated } - public mutating func generate(chunkID: SIMD3) { - if !generatingChunkSet.insert(chunkID).inserted { - return - } + public mutating func cancelAndClearAll() { + self.queue.cancelAllOperations() + self.queue.waitUntilAllOperationsAreFinished() + self.localReadyChunks.removeAll() + self.generatingChunkSet.removeAll() + } - self.queueGenerateJob(chunkID: chunkID) + public mutating func generate(chunkID: SIMD3) { + if generatingChunkSet.insert(chunkID).inserted { + self.queueGenerateJob(chunkID: chunkID) + } } func queueGenerateJob(chunkID: SIMD3) { diff --git a/Sources/Voxelotl/Common/ConcurrentDictionary.swift b/Sources/Voxelotl/Common/ConcurrentDictionary.swift index f61062b..7bf480a 100644 --- a/Sources/Voxelotl/Common/ConcurrentDictionary.swift +++ b/Sources/Voxelotl/Common/ConcurrentDictionary.swift @@ -70,6 +70,12 @@ public class ConcurrentDictionary: Collection { } } + public func removeAll(keepingCapacity keep: Bool = false) { + self.locked { + self.inner.removeAll(keepingCapacity: keep) + } + } + fileprivate func locked(_ perform: () -> X) -> X { self.lock.lock() defer { diff --git a/Sources/Voxelotl/Game.swift b/Sources/Voxelotl/Game.swift index ab51996..6b56126 100644 --- a/Sources/Voxelotl/Game.swift +++ b/Sources/Voxelotl/Game.swift @@ -32,6 +32,8 @@ class Game: GameDelegate { } private func generateWorld() { + self.world.removeAllChunks() + self.renderChunks.removeAll() let seed = UInt64(Arc4Random.instance.next()) | UInt64(Arc4Random.instance.next()) << 32 printErr(seed) #if DEBUG diff --git a/Sources/Voxelotl/World.swift b/Sources/Voxelotl/World.swift index 7828e78..214154c 100644 --- a/Sources/Voxelotl/World.swift +++ b/Sources/Voxelotl/World.swift @@ -68,6 +68,11 @@ public class World { } } + func removeAllChunks() { + self._chunkGeneration.cancelAndClearAll() + self._chunks.removeAll() + } + func generate(width: Int, height: Int, depth: Int, seed: UInt64) { self._generator.reset(seed: seed) let orig = SIMD3(width, height, depth) / 2