Skip to content

Commit b674823

Browse files
author
Walker Haynes
committed
[Swift 6] Fully enable "StrictConcurrency"
1 parent 84c45f7 commit b674823

File tree

6 files changed

+26
-13
lines changed

6 files changed

+26
-13
lines changed

Package.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ let package = Package(
4343
.target(
4444
name: "Grape",
4545
dependencies: ["ForceSimulation"],
46-
path: "Sources/Grape"
46+
path: "Sources/Grape",
47+
swiftSettings: [
48+
.enableExperimentalFeature("StrictConcurrency")
49+
]
4750
// link ForceSimulation in release mode
4851
// swiftSettings: [.unsafeFlags(["-Xfrontend", "-disable-availability-checking"])]
4952
),

Sources/Grape/Modifiers/GraphForegroundScale.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import SwiftUI
33
@usableFromInline
44
enum GrapeEnvironment { }
55

6+
67
extension GrapeEnvironment {
78
@usableFromInline
89
struct GraphForegroundScale: EnvironmentKey {
910
@usableFromInline
10-
static let defaultValue: [AnyHashable: GraphicsContext.Shading] = [:]
11+
static nonisolated(unsafe) let defaultValue: [AnyHashable: GraphicsContext.Shading] = [:]
1112
}
1213
}
1314

Sources/Grape/Views/ForceDirectedGraph+Gesture.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import ForceSimulation
22
import SwiftUI
33

44
#if !os(tvOS)
5+
@MainActor
56
extension ForceDirectedGraph {
67
@inlinable
78
static var minimumAlphaAfterDrag: CGFloat { 0.5 }
@@ -78,7 +79,7 @@ import SwiftUI
7879
@inlinable
7980
static var minimumDragDistance: CGFloat { 3.0 }
8081
}
81-
82+
@MainActor
8283
extension ForceDirectedGraph {
8384
@inlinable
8485
internal func onTapGesture(
@@ -92,7 +93,7 @@ import SwiftUI
9293
#endif
9394

9495
#if os(iOS) || os(macOS)
95-
extension ForceDirectedGraph {
96+
@MainActor extension ForceDirectedGraph {
9697

9798
@inlinable
9899
static var minimumScaleDelta: CGFloat { 0.001 }
@@ -180,6 +181,7 @@ import SwiftUI
180181
}
181182
#endif
182183

184+
@MainActor
183185
extension ForceDirectedGraph {
184186
@inlinable
185187
public func onTicked(

Sources/Grape/Views/ForceDirectedGraph+View.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ForceSimulation
22
import SwiftUI
33

4+
@MainActor
45
extension ForceDirectedGraph: View {
56

67
@inlinable

Sources/Grape/Views/ForceDirectedGraph.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ where NodeID == Content.NodeID {
7575
/// initial kinetic states. This is only applied on the new nodes that is not seen before when the
7676
/// graph is created (or updated).
7777
@inlinable
78+
@MainActor
7879
public init(
7980
states: ForceDirectedGraphState = ForceDirectedGraphState(),
8081
ticksPerSecond: Double = 60.0,

Sources/Grape/Views/ForceDirectedGraphModel.swift

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Observation
44
import SwiftUI
55

66
// @Observable
7+
@MainActor
78
public final class ForceDirectedGraphModel<Content: GraphContent> {
89

910
@usableFromInline
@@ -28,8 +29,8 @@ public final class ForceDirectedGraphModel<Content: GraphContent> {
2829
// }
2930
// }
3031

31-
// @usableFromInline
32-
// internal var _modelTransformExtenalBinding: Binding<ViewportTransform>
32+
// @usableFromInline
33+
// internal var _modelTransformExtenalBinding: Binding<ViewportTransform>
3334

3435
@inlinable
3536
internal var modelTransform: ViewportTransform {
@@ -127,6 +128,7 @@ public final class ForceDirectedGraphModel<Content: GraphContent> {
127128
let ticksPerSecond: Double
128129

129130
@usableFromInline
131+
@MainActor
130132
var scheduledTimer: Timer? = nil
131133

132134
@usableFromInline
@@ -228,7 +230,7 @@ public final class ForceDirectedGraphModel<Content: GraphContent> {
228230
withObservationTracking { [weak self] in
229231
guard let self else { return }
230232
self.updateModelRunningState(isRunning: self.stateMixinRef.isRunning)
231-
} onChange: { [weak self] in
233+
} onChange: { @Sendable [weak self] in
232234
guard let self else { return }
233235
Task { @MainActor [weak self] in
234236
self?.continuouslyTrackingRunning()
@@ -266,7 +268,8 @@ public final class ForceDirectedGraphModel<Content: GraphContent> {
266268

267269
@inlinable
268270
deinit {
269-
self.stop()
271+
self.scheduledTimer?.invalidate()
272+
self.scheduledTimer = nil
270273
}
271274

272275
@usableFromInline
@@ -294,26 +297,30 @@ extension StrokeStyle {
294297
}
295298

296299
// Render related
300+
@MainActor
297301
extension ForceDirectedGraphModel {
298302

299303
@inlinable
300-
// @MainActor
301304
func start(minAlpha: Double = 0.6) {
302305
guard self.scheduledTimer == nil else { return }
303306
print("Simulation started")
304307
if simulationContext.storage.kinetics.alpha < minAlpha {
305308
simulationContext.storage.kinetics.alpha = minAlpha
306309
}
310+
307311
self.scheduledTimer = Timer.scheduledTimer(
308312
withTimeInterval: 1.0 / ticksPerSecond,
309313
repeats: true
310314
) { [weak self] _ in
311-
self?.tick()
315+
if let capturedSelf = self {
316+
Task { @MainActor [weak capturedSelf] in
317+
capturedSelf?.tick()
318+
}
319+
}
312320
}
313321
}
314322

315323
@inlinable
316-
// @MainActor
317324
func tick() {
318325
withMutation(keyPath: \.currentFrame) {
319326
simulationContext.storage.tick()
@@ -323,15 +330,13 @@ extension ForceDirectedGraphModel {
323330
}
324331

325332
@inlinable
326-
// @MainActor
327333
func stop() {
328334
print("Simulation stopped")
329335
self.scheduledTimer?.invalidate()
330336
self.scheduledTimer = nil
331337
}
332338

333339
@inlinable
334-
@MainActor
335340
func render(
336341
_ graphicsContext: inout GraphicsContext,
337342
_ size: CGSize

0 commit comments

Comments
 (0)