import Foundation public struct ChunkGeneration { private let queue: OperationQueue private let localReadyChunks = ConcurrentDictionary, Chunk>() private var generatingChunkSet = Set>() weak var world: World? init(queue: DispatchQueue) { self.queue = OperationQueue() self.queue.underlyingQueue = queue self.queue.maxConcurrentOperationCount = 8 self.queue.qualityOfService = .userInitiated } public mutating func generate(chunkID: SIMD3) { if !generatingChunkSet.insert(chunkID).inserted { return } self.queueGenerateJob(chunkID: chunkID) } func queueGenerateJob(chunkID: SIMD3) { self.queue.addOperation { guard let world = self.world else { return } let chunk = world.generateSingleChunkUncommitted(chunkID: chunkID) self.localReadyChunks[chunkID] = chunk } } public mutating func generateAdjacentIfNeeded(position: SIMD3) { guard let world = self.world else { return } let centerChunkID = World.makeID(position: position) for offset in ChunkGeneration.chunkGenerateNeighbors { let chunkID = centerChunkID &+ offset if world.getChunk(id: chunkID) == nil { self.generate(chunkID: chunkID) } } } public mutating func acceptReadyChunks() { guard let world = self.world else { return } if self.generatingChunkSet.isEmpty { return } for (chunkID, chunk) in self.localReadyChunks.take() { world.addChunk(chunkID: chunkID, chunk: chunk) self.generatingChunkSet.remove(chunkID) } } private static let chunkGenerateNeighbors: [SIMD3] = [ SIMD3(-1, -1, -1), SIMD3(0, -1, -1), SIMD3(1, -1, -1), SIMD3(-1, 0, -1), SIMD3(0, 0, -1), SIMD3(1, 0, -1), SIMD3(-1, 1, -1), SIMD3(0, 1, -1), SIMD3(1, 1, -1), SIMD3(-1, -1, 0), SIMD3(0, -1, 0), SIMD3(1, -1, 0), SIMD3(-1, 0, 0), SIMD3(0, 0, 0), SIMD3(1, 0, 0), SIMD3(-1, 1, 0), SIMD3(0, 1, 0), SIMD3(1, 1, 0), SIMD3(-1, -1, 1), SIMD3(0, -1, 1), SIMD3(1, -1, 1), SIMD3(-1, 0, 1), SIMD3(0, 0, 1), SIMD3(1, 0, 1), SIMD3(-1, 1, 1), SIMD3(0, 1, 1), SIMD3(1, 1, 1), ] }