Skip to content

Commit 4333150

Browse files
authored
remove stray foundation dependency (#35)
* remove stray foundation dependency * add a test for good measure
1 parent 5dd51e2 commit 4333150

File tree

5 files changed

+67
-35
lines changed

5 files changed

+67
-35
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ For embedded builds, Swift 6.2 or later with matching *Swift SDKs for WebAssembl
3434
- ~~better control over animations~~
3535
- ~~somehow migrate over to "var body" instead of "var content" (what was I thinking....)~~
3636
- ~~automatic FLIP animations for certain layout changes (child-layout after changes, maybe size of containers)~~
37-
- fix those Foundation imports, review thread-local + mutex usage
37+
- ~~fix those Foundation imports, review thread-local + mutex usage~~
3838
- more built-in animatable CSS modifiers (colors, borders, borders?, blur)
3939
- basic phaseAnimator implementations
4040
- implement auto-flip animation for custom CSS values (on value triggers)
Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
1+
#if _runtime(_multithreaded)
12
import Synchronization
3+
final class MutexBox<State: ~Copyable>: Sendable {
4+
private let state: Mutex<State>
25

3-
#if canImport(Foundation)
4-
import Foundation
5-
#endif
6-
7-
// TODO: figure this out
8-
enum _ThreadLocal {
9-
#if !canImport(Foundation) || os(WASI)
10-
nonisolated(unsafe) static var value: UnsafeMutableRawPointer?
11-
#else
12-
private struct Key: Hashable {}
6+
init(_ state: consuming sending State) {
7+
self.state = Mutex(state)
8+
}
139

14-
static var value: UnsafeMutableRawPointer? {
15-
get { Thread.current.threadDictionary[Key()] as! UnsafeMutableRawPointer? }
16-
set { Thread.current.threadDictionary[Key()] = newValue }
10+
func withLock<Result>(_ body: sending (inout sending State) -> sending Result) -> sending Result {
11+
state.withLock(body)
1712
}
18-
#endif
19-
}
2013

21-
// TODO: Mutex causes swift compiler crash on github CI - figure out why
22-
#if hasFeature(Embedded) || os(Linux)
23-
// TODO: figure this out
14+
var id: ObjectIdentifier { ObjectIdentifier(self) }
15+
}
16+
#else
2417
final class MutexBox<State>: @unchecked Sendable {
2518
private var state: State
2619

@@ -34,18 +27,4 @@ final class MutexBox<State>: @unchecked Sendable {
3427

3528
var id: ObjectIdentifier { ObjectIdentifier(self) }
3629
}
37-
#else
38-
final class MutexBox<State: ~Copyable>: Sendable {
39-
private let state: Mutex<State>
40-
41-
init(_ state: consuming sending State) {
42-
self.state = Mutex(state)
43-
}
44-
45-
func withLock<Result>(_ body: sending (inout sending State) -> sending Result) -> sending Result {
46-
state.withLock(body)
47-
}
48-
49-
var id: ObjectIdentifier { ObjectIdentifier(self) }
50-
}
5130
#endif
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#if _runtime(_multithreaded)
2+
#if canImport(Darwin)
3+
import Darwin
4+
#elseif canImport(Glibc)
5+
@preconcurrency import Glibc
6+
#else
7+
#error("Unsupported platform")
8+
#endif
9+
10+
enum _ThreadLocal {
11+
static let key: pthread_key_t = __makeKey()
12+
13+
static var value: UnsafeMutableRawPointer? {
14+
get { pthread_getspecific(key) }
15+
set { pthread_setspecific(key, newValue) }
16+
}
17+
18+
static func __makeKey() -> pthread_key_t {
19+
var key: pthread_key_t = 0
20+
pthread_key_create(&key, nil)
21+
return key
22+
}
23+
}
24+
#else
25+
// single-threaded runtime
26+
enum _ThreadLocal {
27+
nonisolated(unsafe) static var value: UnsafeMutableRawPointer?
28+
}
29+
#endif

Tests/ElementaryDOMTests/Reconciler/TestDOM.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import Foundation
2-
31
@testable import ElementaryDOM
42

53
private extension DOM.Event {

Tests/ReactivityTests/ReactiveClassesTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,32 @@ struct ReactiveClassesTests {
2020
foo.one = "test"
2121
#expect(tracker.hasChanged)
2222
}
23+
24+
@Test
25+
func tracksChangesInParellel() async {
26+
await withTaskGroup { group in
27+
for _ in 0..<1000 {
28+
group.addTask {
29+
let foo = Foo()
30+
let tracker = ChangeTracker()
31+
await Task.yield()
32+
withReactiveTracking {
33+
_ = foo.one
34+
} onChange: {
35+
tracker.hasChanged = true
36+
}
37+
await Task.yield()
38+
foo.two = "test"
39+
await Task.yield()
40+
#expect(!tracker.hasChanged)
41+
await Task.yield()
42+
foo.one = "test"
43+
#expect(tracker.hasChanged)
44+
}
45+
}
46+
}
47+
48+
}
2349
}
2450

2551
final class ChangeTracker: Sendable {

0 commit comments

Comments
 (0)