diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2022-09-25 16:34:23 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2022-09-26 16:35:38 +0200 |
| commit | f389956c2cd884df142adbf00ff2ac7e2f69c2b2 (patch) | |
| tree | 5f7d4869324760eb4ba0107c0356edc89efd1457 /ios/Operations/AsyncBlockOperation.swift | |
| parent | 2e83b1ca27ff243a615ff10c94c20840b38dfd45 (diff) | |
| download | mullvadvpn-f389956c2cd884df142adbf00ff2ac7e2f69c2b2.tar.xz mullvadvpn-f389956c2cd884df142adbf00ff2ac7e2f69c2b2.zip | |
Move AsyncOperation into Operations static library and add separate tests
Diffstat (limited to 'ios/Operations/AsyncBlockOperation.swift')
| -rw-r--r-- | ios/Operations/AsyncBlockOperation.swift | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/ios/Operations/AsyncBlockOperation.swift b/ios/Operations/AsyncBlockOperation.swift new file mode 100644 index 0000000000..72b95c98a3 --- /dev/null +++ b/ios/Operations/AsyncBlockOperation.swift @@ -0,0 +1,84 @@ +// +// AsyncBlockOperation.swift +// MullvadVPN +// +// Created by pronebird on 06/07/2020. +// Copyright © 2020 Mullvad VPN AB. All rights reserved. +// + +import Foundation + +/// Asynchronous block operation +public class AsyncBlockOperation: AsyncOperation { + private var executionBlock: ((AsyncBlockOperation) -> Void)? + private var cancellationBlocks: [() -> Void] = [] + + override public init(dispatchQueue: DispatchQueue? = nil) { + super.init(dispatchQueue: dispatchQueue) + } + + public init( + dispatchQueue: DispatchQueue? = nil, + block: @escaping (AsyncBlockOperation) -> Void + ) { + executionBlock = block + super.init(dispatchQueue: dispatchQueue) + } + + public init(dispatchQueue: DispatchQueue? = nil, block: @escaping () -> Void) { + executionBlock = { operation in + block() + operation.finish() + } + super.init(dispatchQueue: dispatchQueue) + } + + override public func main() { + let block = executionBlock + executionBlock = nil + + if let block = block { + block(self) + } else { + finish() + } + } + + override public func operationDidCancel() { + let blocks = cancellationBlocks + cancellationBlocks.removeAll() + + for block in blocks { + block() + } + } + + override public func operationDidFinish() { + cancellationBlocks.removeAll() + executionBlock = nil + } + + public func setExecutionBlock(_ block: @escaping (AsyncBlockOperation) -> Void) { + dispatchQueue.async { + assert(!self.isExecuting && !self.isFinished) + self.executionBlock = block + } + } + + public func setExecutionBlock(_ block: @escaping () -> Void) { + setExecutionBlock { operation in + block() + operation.finish() + } + } + + public func addCancellationBlock(_ block: @escaping () -> Void) { + dispatchQueue.async { + if self.isCancelled { + block() + } else { + self.cancellationBlocks.append(block) + } + } + } +} |
