Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class Matcher<First: SignalProducer, Second: SignalProducer>: SignalProducer {
- struct Answers {
- var first: [First.Output] = []
- var second: [Second.Output] = []
- }
- var syncQueue = DispatchQueue(label: "com.active-operation.matcher.sync-queue", qos: .default, attributes: .concurrent)
- var lock = NSRecursiveLock()
- public var onSignal: Block<(First.Output, Second.Output)>?
- public func run(with input: (First.Input, Second.Input)) {
- first.onSignal = { [weak self] value in
- guard let self = self else { return }
- self.answers.mutate { $0.first.append(value) }
- self.checkResults()
- }
- second.onSignal = { [weak self] value in
- guard let self = self else { return }
- self.answers.mutate { $0.second.append(value) }
- self.checkResults()
- }
- first.run(with: input.0)
- second.run(with: input.1)
- }
- public init(first: First, second: Second, matching: @escaping (First.Output, Second.Output) -> Bool) {
- self.first = first
- self.second = second
- self.matching = matching
- }
- private let first: First
- private let second: Second
- private let matching: (First.Output, Second.Output) -> Bool
- private var answers = Atomic<Answers>(.init())
- private var isFinished: Bool = false
- private func checkResults() {
- defer { lock.unlock() }
- lock.lock()
- guard !isFinished else { return }
- let result = answers.value
- for firstItem in result.first {
- for secondItem in result.second {
- if matching(firstItem, secondItem) {
- self.isFinished = true
- let ok = (firstItem, secondItem)
- onSignal?(ok)
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement