2024-09-03 09:48:29 -04:00
|
|
|
import Foundation
|
|
|
|
|
|
|
|
public struct ChunkMeshGeneration {
|
|
|
|
private let queue: OperationQueue
|
2024-09-08 03:47:26 +10:00
|
|
|
private let localReadyMeshes = ConcurrentDictionary<ChunkID, RendererMesh?>()
|
2024-09-03 09:48:29 -04:00
|
|
|
|
|
|
|
weak var game: Game?
|
|
|
|
weak var renderer: Renderer?
|
|
|
|
|
|
|
|
init(queue: DispatchQueue) {
|
|
|
|
self.queue = OperationQueue()
|
|
|
|
self.queue.underlyingQueue = queue
|
|
|
|
self.queue.maxConcurrentOperationCount = 8
|
|
|
|
self.queue.qualityOfService = .userInitiated
|
|
|
|
}
|
|
|
|
|
2024-09-08 03:47:26 +10:00
|
|
|
public mutating func generate(id chunkID: ChunkID, chunk: Chunk) {
|
|
|
|
self.queueGenerateJob(id: chunkID, chunk: chunk)
|
2024-09-03 09:48:29 -04:00
|
|
|
}
|
|
|
|
|
2024-09-08 03:47:26 +10:00
|
|
|
func queueGenerateJob(id chunkID: ChunkID, chunk: Chunk) {
|
2024-09-03 09:48:29 -04:00
|
|
|
self.queue.addOperation {
|
|
|
|
guard let game = self.game else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
guard let renderer = self.renderer else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
let mesh = ChunkMeshBuilder.build(world: game.world, chunk: chunk)
|
|
|
|
self.localReadyMeshes[chunkID] = renderer.createMesh(mesh)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public mutating func acceptReadyMeshes() {
|
|
|
|
guard let game = self.game else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
queue.waitUntilAllOperationsAreFinished()
|
|
|
|
|
|
|
|
for (chunkID, mesh) in self.localReadyMeshes.take() {
|
|
|
|
game.renderChunks.updateValue(mesh, forKey: chunkID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|