mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-02 13:00:53 +00:00
Merge pull request #3 from GayPizzaSpecifications/parallel-regen
Parallelize chunk generation using fan-out pattern.
This commit is contained in:
commit
b1f2f645f6
@ -7,6 +7,9 @@ add_executable(Voxelotl MACOSX_BUNDLE
|
||||
shadertypes.h
|
||||
shader.metal
|
||||
|
||||
# Common library
|
||||
Common/ConcurrentDictionary.swift
|
||||
|
||||
# Maths library
|
||||
Math/FloatExtensions.swift
|
||||
Math/IntegerExtensions.swift
|
||||
@ -98,6 +101,7 @@ set_source_files_properties(test.png PROPERTIES MACOSX_PACKAGE_LOCATION Resource
|
||||
|
||||
#TODO: should use TREE mode as documented in https://cmake.org/cmake/help/latest/command/source_group.html
|
||||
source_group("Resources" FILES Assets.xcassets test.png)
|
||||
source_group("Source Files\\Common" REGULAR_EXPRESSION "Common/")
|
||||
source_group("Source Files" REGULAR_EXPRESSION "\\.(swift|metal)$")
|
||||
source_group("Source Files\\Random" REGULAR_EXPRESSION "Random/")
|
||||
source_group("Source Files\\Math" REGULAR_EXPRESSION "Math/")
|
||||
|
73
Sources/Voxelotl/Common/ConcurrentDictionary.swift
Normal file
73
Sources/Voxelotl/Common/ConcurrentDictionary.swift
Normal file
@ -0,0 +1,73 @@
|
||||
import Foundation
|
||||
|
||||
public class ConcurrentDictionary<V: Hashable, T>: Collection {
|
||||
private var inner: [V : T]
|
||||
private var lock: NSLock = .init()
|
||||
|
||||
public var keys: Dictionary<V, T>.Keys {
|
||||
self.locked {
|
||||
inner.keys
|
||||
}
|
||||
}
|
||||
|
||||
public var values: Dictionary<V, T>.Values {
|
||||
self.locked {
|
||||
self.inner.values
|
||||
}
|
||||
}
|
||||
|
||||
public var startIndex: Dictionary<V, T>.Index {
|
||||
self.locked {
|
||||
self.inner.startIndex
|
||||
}
|
||||
}
|
||||
|
||||
public var endIndex: Dictionary<V, T>.Index {
|
||||
self.locked {
|
||||
self.inner.endIndex
|
||||
}
|
||||
}
|
||||
|
||||
public init(inner: [V:T]) {
|
||||
self.inner = inner
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
self.init(inner: [:])
|
||||
}
|
||||
|
||||
public func index(after i: Dictionary<V, T>.Index) -> Dictionary<V, T>.Index {
|
||||
self.locked {
|
||||
self.inner.index(after: i)
|
||||
}
|
||||
}
|
||||
|
||||
public subscript(key: V) -> T? {
|
||||
set(newValue) {
|
||||
self.locked {
|
||||
self.inner[key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
get {
|
||||
self.locked {
|
||||
self.inner[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public subscript(index: Dictionary<V, T>.Index) -> Dictionary<V, T>.Element {
|
||||
self.locked {
|
||||
self.inner[index]
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func locked<X>(_ perform: () -> X) -> X {
|
||||
self.lock.lock()
|
||||
defer {
|
||||
self.lock.unlock()
|
||||
}
|
||||
let value = perform()
|
||||
return value
|
||||
}
|
||||
}
|
@ -62,15 +62,26 @@ public class World {
|
||||
func generate(width: Int, height: Int, depth: Int, seed: UInt64) {
|
||||
self._generator.reset(seed: seed)
|
||||
let orig = SIMD3(width, height, depth) / 2
|
||||
|
||||
let localChunks = ConcurrentDictionary<ChunkID, Chunk>()
|
||||
let queue = OperationQueue()
|
||||
queue.qualityOfService = .userInitiated
|
||||
for z in 0..<depth {
|
||||
for y in 0..<height {
|
||||
for x in 0..<width {
|
||||
let chunkID = SIMD3(x, y, z) &- orig
|
||||
self._chunks[chunkID] = self._generator.makeChunk(id: chunkID)
|
||||
self._chunkDamage.insert(chunkID)
|
||||
queue.addOperation {
|
||||
let chunk = self._generator.makeChunk(id: chunkID)
|
||||
localChunks[chunkID] = chunk
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
queue.waitUntilAllOperationsAreFinished()
|
||||
for (chunkID, chunk) in localChunks {
|
||||
self._chunks[chunkID] = chunk
|
||||
self._chunkDamage.insert(chunkID)
|
||||
}
|
||||
}
|
||||
|
||||
func generate(chunkID: ChunkID) {
|
||||
|
Loading…
Reference in New Issue
Block a user