Skip to content

Commit 57342fb

Browse files
committed
Refactor IDGenerator
1 parent c165b48 commit 57342fb

File tree

2 files changed

+20
-19
lines changed

2 files changed

+20
-19
lines changed

Sources/GateEngine/ECS/Base/Component.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extension Component {
2424
}
2525

2626
public struct ComponentID: Equatable, Hashable, Sendable {
27-
nonisolated(unsafe) private static let idGenerator = IDGenerator<Int>(startValue: 0)
27+
private static let idGenerator = IDGenerator<Int>(startValue: 0)
2828
@usableFromInline
2929
internal let value: Int
3030
public init() {

Sources/GateEngine/Helpers/IDGenerator.swift

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,47 @@
55
* http://stregasgate.com
66
*/
77

8-
#if canImport(Atomics)
9-
public import Atomics
10-
#elseif canImport(Foundation.NSLock)
11-
import class Foundation.NSLock
12-
#endif
8+
// A protocol to make sure all the possible variations have the same interface
9+
public protocol IDGeneratorProtocol: Sendable {
10+
associatedtype T: BinaryInteger & Sendable
11+
func generateID() -> T
12+
init(startValue: T)
13+
}
1314

1415
#if canImport(Atomics)
15-
nonisolated public final class IDGenerator<T: AtomicInteger & Sendable> {
16+
public import Atomics
17+
public struct IDGenerator<T: AtomicInteger & Sendable>: IDGeneratorProtocol {
1618
var value: ManagedAtomic<T>
17-
1819
public init(startValue: T = 0) {
1920
value = ManagedAtomic<T>(startValue)
2021
}
2122

2223
public func generateID() -> T {
23-
return value.loadThenWrappingIncrement(ordering: .sequentiallyConsistent)
24+
return value.loadThenWrappingIncrement(ordering: .relaxed)
2425
}
2526
}
2627
#elseif canImport(Foundation.NSLock)
27-
nonisolated public final class IDGenerator<T: BinaryInteger & Sendable> {
28-
var value: T = 0
28+
import class Foundation.NSLock
29+
public final class IDGenerator<T: BinaryInteger & Sendable>: IDGeneratorProtocol {
30+
// isolation is managed with a lock, so this is safe
31+
nonisolated(unsafe) var value: T = 0
2932
let lock = NSLock()
3033

3134
public init(startValue: T = 0) {
3235
self.value = startValue
3336
}
3437

3538
public func generateID() -> T {
36-
lock.lock()
37-
let value = value
38-
self.value += 1
39-
defer {
40-
lock.unlock()
39+
return lock.withLock {
40+
let value = value
41+
self.value += 1
42+
return value
4143
}
42-
return value
4344
}
4445
}
4546
#else
46-
nonisolated public final class IDGenerator<T: BinaryInteger & Sendable> {
47-
var value: T = 0
47+
public final class IDGenerator<T: BinaryInteger & Sendable>: IDGeneratorProtocol {
48+
nonisolated(unsafe) var value: T = 0
4849

4950
public init(startValue: T = 0) {
5051
self.value = startValue

0 commit comments

Comments
 (0)