Advertisement
Guest User

Untitled

a guest
Sep 19th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 1.97 KB | None | 0 0
  1. public class Matcher<First: SignalProducer, Second: SignalProducer>: SignalProducer {
  2.    
  3.     struct Answers {
  4.         var first: [First.Output] = []
  5.         var second: [Second.Output] = []
  6.     }
  7.    
  8.     var syncQueue = DispatchQueue(label: "com.active-operation.matcher.sync-queue", qos: .default, attributes: .concurrent)
  9.     var lock = NSRecursiveLock()
  10.    
  11.     public var onSignal: Block<(First.Output, Second.Output)>?
  12.    
  13.     public func run(with input: (First.Input, Second.Input)) {
  14.         first.onSignal = { [weak self] value in
  15.             guard let self = self else { return }
  16.            
  17.             self.answers.mutate { $0.first.append(value) }
  18.             self.checkResults()
  19.         }
  20.        
  21.         second.onSignal = { [weak self] value in
  22.             guard let self = self else { return }
  23.            
  24.             self.answers.mutate { $0.second.append(value) }
  25.             self.checkResults()
  26.         }
  27.        
  28.         first.run(with: input.0)
  29.         second.run(with: input.1)
  30.     }
  31.    
  32.     public init(first: First, second: Second, matching: @escaping (First.Output, Second.Output) -> Bool) {
  33.         self.first = first
  34.         self.second = second
  35.         self.matching = matching
  36.     }
  37.    
  38.     private let first: First
  39.     private let second: Second
  40.     private let matching: (First.Output, Second.Output) -> Bool
  41.     private var answers = Atomic<Answers>(.init())
  42.     private var isFinished: Bool = false
  43.    
  44.     private func checkResults() {
  45.         defer { lock.unlock() }
  46.         lock.lock()
  47.        
  48.         guard !isFinished else { return }
  49.        
  50.         let result = answers.value
  51.        
  52.         for firstItem in result.first {
  53.             for secondItem in result.second {
  54.                 if matching(firstItem, secondItem) {
  55.                     self.isFinished = true
  56.                     let ok = (firstItem, secondItem)
  57.                     onSignal?(ok)
  58.                 }
  59.             }
  60.         }
  61.     }
  62. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement