Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
muukii committed Mar 19, 2024
1 parent 8e829d8 commit 02554c5
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
11 changes: 7 additions & 4 deletions Sources/Verge/Library/StoreSubscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public final class StoreSubscription: Hashable, Cancellable, @unchecked Sendable

guard wasCancelled.compareExchange(expected: false, desired: true, ordering: .relaxed).exchanged else { return }

storeCancellable?.dissociate(self)
source.cancel()
associatedStore = nil
}
Expand Down Expand Up @@ -113,7 +114,8 @@ public final class StoreStateSubscription: Hashable, Cancellable, @unchecked Sen
private weak var storeCancellable: VergeAnyCancellable?
private var associatedStore: (any StoreType)?
private var associatedReferences: [AnyObject] = []
private let onAction: (StoreStateSubscription, Action) -> Void

private var onAction: ((StoreStateSubscription, Action) -> Void)?

init(
_ eventEmitterCancellable: EventEmitterCancellable,
Expand All @@ -132,8 +134,9 @@ public final class StoreStateSubscription: Hashable, Cancellable, @unchecked Sen
}

AtomicReferenceStorage.atomicLoad(at: &source, ordering: .relaxed).cancel()

storeCancellable?.dissociate(self)
associatedStore = nil
onAction = nil
}

func cancelSubscription() {
Expand Down Expand Up @@ -174,7 +177,7 @@ public final class StoreStateSubscription: Hashable, Cancellable, @unchecked Sen
return
}

onAction(self, .suspend)
onAction?(self, .suspend)

}

Expand All @@ -197,7 +200,7 @@ public final class StoreStateSubscription: Hashable, Cancellable, @unchecked Sen
return
}

onAction(self, .resume)
onAction?(self, .resume)
}

func associate(store: some StoreType) -> StoreStateSubscription {
Expand Down
57 changes: 49 additions & 8 deletions Sources/Verge/Library/VergeAnyCancellable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ import Combine
/// A typealias to `Set<AnyCancellable>`.
public typealias VergeAnyCancellables = Set<AnyCancellable>

final class Reference: Equatable, Hashable {

static func == (lhs: Reference, rhs: Reference) -> Bool {
lhs === rhs
}

func hash(into hasher: inout Hasher) {
ObjectIdentifier(value).hash(into: &hasher)
}

let value: AnyObject

init(value: AnyObject) {
self.value = value
}

}

/// A type-erasing cancellable object that executes a provided closure when canceled.
/// An AnyCancellable instance automatically calls cancel() when deinitialized.
/// To cancel depending owner, can be written following
Expand Down Expand Up @@ -39,7 +57,7 @@ public final class VergeAnyCancellable: Hashable, Cancellable, @unchecked Sendab
}

private var actions: ContiguousArray<() -> Void>? = .init()
private var retainObjects: ContiguousArray<AnyObject> = .init()
private var retainObjects: Set<Reference> = .init()

public init() {
}
Expand All @@ -65,11 +83,27 @@ public final class VergeAnyCancellable: Hashable, Cancellable, @unchecked Sendab

assert(!wasCancelled)

retainObjects.append(object)
retainObjects.insert(.init(value: object))

return self
}

public func dissociate(_ object: AnyObject) {

lock.lock()

let target = retainObjects.remove(.init(value: object))

lock.unlock()

guard let target else {
return
}

withExtendedLifetime(target, {})

}

public func insert(_ cancellable: Cancellable) {

lock.lock()
Expand Down Expand Up @@ -102,21 +136,28 @@ public final class VergeAnyCancellable: Hashable, Cancellable, @unchecked Sendab
public func cancel() {

lock.lock()
defer {

guard !wasCancelled else {
lock.unlock()
return
}

guard !wasCancelled else { return }
wasCancelled = true

let _retainObjects = self.retainObjects
retainObjects.removeAll()

actions?.forEach {

let _actions = self.actions
self.actions = nil

lock.unlock()

withExtendedLifetime(_retainObjects, {})

_actions?.forEach {
$0()
}

actions = nil

}

}
Expand Down

0 comments on commit 02554c5

Please sign in to comment.