mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-03 05:10:57 +00:00
implement a safe concurrent dictionary
This commit is contained in:
parent
a149de885c
commit
65af0b321d
@ -7,6 +7,9 @@ add_executable(Voxelotl MACOSX_BUNDLE
|
|||||||
shadertypes.h
|
shadertypes.h
|
||||||
shader.metal
|
shader.metal
|
||||||
|
|
||||||
|
# Common library
|
||||||
|
Common/ConcurrentDictionary.swift
|
||||||
|
|
||||||
# Maths library
|
# Maths library
|
||||||
Math/FloatExtensions.swift
|
Math/FloatExtensions.swift
|
||||||
Math/IntegerExtensions.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
|
#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("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" REGULAR_EXPRESSION "\\.(swift|metal)$")
|
||||||
source_group("Source Files\\Random" REGULAR_EXPRESSION "Random/")
|
source_group("Source Files\\Random" REGULAR_EXPRESSION "Random/")
|
||||||
source_group("Source Files\\Math" REGULAR_EXPRESSION "Math/")
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -63,8 +63,7 @@ public class World {
|
|||||||
self._generator.reset(seed: seed)
|
self._generator.reset(seed: seed)
|
||||||
let orig = SIMD3(width, height, depth) / 2
|
let orig = SIMD3(width, height, depth) / 2
|
||||||
|
|
||||||
var localChunks: [SIMD3<Int>: Chunk] = [:]
|
let localChunks = ConcurrentDictionary<SIMD3<Int>, Chunk>()
|
||||||
let localChunksLock = NSLock()
|
|
||||||
let queue = OperationQueue()
|
let queue = OperationQueue()
|
||||||
queue.qualityOfService = .userInitiated
|
queue.qualityOfService = .userInitiated
|
||||||
for z in 0..<depth {
|
for z in 0..<depth {
|
||||||
@ -73,10 +72,6 @@ public class World {
|
|||||||
let chunkID = SIMD3(x, y, z) &- orig
|
let chunkID = SIMD3(x, y, z) &- orig
|
||||||
queue.addOperation {
|
queue.addOperation {
|
||||||
let chunk = self._generator.makeChunk(id: chunkID)
|
let chunk = self._generator.makeChunk(id: chunkID)
|
||||||
localChunksLock.lock()
|
|
||||||
defer {
|
|
||||||
localChunksLock.unlock()
|
|
||||||
}
|
|
||||||
localChunks[chunkID] = chunk
|
localChunks[chunkID] = chunk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user