88import ConcurrencyExtras
99import Foundation
1010
11- public final class ObservationToken : Sendable , Hashable {
12- let _onCancel = LockIsolated ( ( @Sendable ( ) - > Void) ? . none)
11+ public final class ObservationToken : @unchecked Sendable , Hashable {
12+ private let _isCancelled = LockIsolated ( false )
13+ package var onCancel : @Sendable ( ) -> Void
1314
14- package init ( _ onCancel: ( @Sendable ( ) -> Void ) ? = nil ) {
15- _onCancel. setValue ( onCancel)
15+ public var isCancelled : Bool {
16+ _isCancelled. withValue { $0 }
17+ }
18+
19+ package init ( onCancel: @escaping @Sendable ( ) -> Void = { } ) {
20+ self . onCancel = onCancel
1621 }
1722
1823 @available ( * , deprecated, renamed: " cancel " )
@@ -21,13 +26,10 @@ public final class ObservationToken: Sendable, Hashable {
2126 }
2227
2328 public func cancel( ) {
24- _onCancel. withValue {
25- if $0 == nil {
26- return
27- }
28-
29- $0 ? ( )
30- $0 = nil
29+ _isCancelled. withValue { isCancelled in
30+ guard !isCancelled else { return }
31+ defer { isCancelled = true }
32+ onCancel ( )
3133 }
3234 }
3335
@@ -36,7 +38,7 @@ public final class ObservationToken: Sendable, Hashable {
3638 }
3739
3840 public static func == ( lhs: ObservationToken , rhs: ObservationToken ) -> Bool {
39- ObjectIdentifier ( lhs) == ObjectIdentifier ( rhs)
41+ lhs === rhs
4042 }
4143
4244 public func hash( into hasher: inout Hasher ) {
@@ -45,6 +47,10 @@ public final class ObservationToken: Sendable, Hashable {
4547}
4648
4749extension ObservationToken {
50+ public func store( in collection: inout some RangeReplaceableCollection < ObservationToken > ) {
51+ collection. append ( self )
52+ }
53+
4854 public func store( in set: inout Set < ObservationToken > ) {
4955 set. insert ( self )
5056 }
@@ -53,7 +59,7 @@ extension ObservationToken {
5359package final class EventEmitter < Event: Sendable > : Sendable {
5460 public typealias Listener = @Sendable ( Event ) -> Void
5561
56- private let listeners = LockIsolated < [ ObjectIdentifier : Listener ] > ( [ : ] )
62+ private let listeners = LockIsolated < [ ( key : ObjectIdentifier , listener : Listener ) ] > ( [ ] )
5763 private let _lastEvent : LockIsolated < Event >
5864 package var lastEvent : Event { _lastEvent. value }
5965
@@ -77,14 +83,14 @@ package final class EventEmitter<Event: Sendable>: Sendable {
7783 let token = ObservationToken ( )
7884 let key = ObjectIdentifier ( token)
7985
80- token. _onCancel . setValue { [ weak self] in
86+ token. onCancel = { [ weak self] in
8187 self ? . listeners. withValue {
82- $0 [ key] = nil
88+ $0. removeAll { $0 . key == key }
8389 }
8490 }
8591
8692 listeners. withValue {
87- $0 [ key] = listener
93+ $0. append ( ( key, listener) )
8894 }
8995
9096 return token
@@ -95,9 +101,9 @@ package final class EventEmitter<Event: Sendable>: Sendable {
95101 let listeners = listeners. value
96102
97103 if let token {
98- listeners [ ObjectIdentifier ( token) ] ? ( event)
104+ listeners. first { $0 . key == ObjectIdentifier ( token) } ? . listener ( event)
99105 } else {
100- for listener in listeners. values {
106+ for (_ , listener) in listeners {
101107 listener ( event)
102108 }
103109 }
0 commit comments