Guest User

Untitled

a guest
Jan 21st, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.23 KB | None | 0 0
  1. // MARK: - Observer
  2.  
  3. final class Observer<Value> {
  4. let update: (Value) -> Void
  5.  
  6. init(update: @escaping (Value) -> Void) {
  7. self.update = update
  8. }
  9. }
  10.  
  11. extension Observer: Hashable {
  12. var hashValue: Int {
  13. return ObjectIdentifier(self).hashValue
  14. }
  15.  
  16. static func == (lhs: Observer, rhs: Observer) -> Bool {
  17. return lhs === rhs
  18. }
  19. }
  20.  
  21. // MARK: - Signal
  22.  
  23. final class Signal<Value> {
  24. private var observers = Set<Observer<Value>>()
  25.  
  26. init(_ startHandler: @escaping (@escaping (Value) -> Void) -> Void) {
  27. startHandler { value in
  28. self.observers.forEach { $0.update(value) }
  29. }
  30. }
  31.  
  32. func subscribe(_ observerAction: @escaping (Value) -> Void) {
  33. let observer = Observer<Value>(update: observerAction)
  34. observers.insert(observer)
  35. }
  36.  
  37. static func pipe() -> (Signal, Observer<Value>) {
  38. var observer: Observer<Value>!
  39. let signal = Signal { action in
  40. observer = Observer(update: action)
  41. }
  42. return (signal, observer)
  43. }
  44. }
  45.  
  46. // MARK: - Producer
  47.  
  48. final class Producer<Value> {
  49. private let startHandler: (Observer<Value>) -> Void
  50.  
  51. init(_ startHandler: @escaping (@escaping (Value) -> Void) -> Void) {
  52. self.startHandler = { startHandler($0.update) }
  53. }
  54.  
  55. func start(_ observerAction: @escaping (Value) -> Void) {
  56. startWithSignal { signal in
  57. signal.subscribe(observerAction)
  58. }
  59. }
  60.  
  61. func startWithSignal(_ setup: (Signal<Value>) -> Void) {
  62. let (signal, observer) = Signal<Value>.pipe()
  63. setup(signal)
  64. startHandler(observer)
  65. }
  66.  
  67. func lift<T>(_ transform: @escaping (Signal<Value>) -> Signal<T>) -> Producer<T> {
  68. return Producer<T> { observerAction in
  69. self.startWithSignal { signal in
  70. transform(signal).subscribe(observerAction)
  71. }
  72. }
  73. }
  74. }
  75.  
  76. extension Signal {
  77. func map<T>(_ transform: @escaping (Value) -> T) -> Signal<T> {
  78. return Signal<T> { action in
  79. self.subscribe { value in
  80. action(transform(value))
  81. }
  82. }
  83. }
  84. }
  85.  
  86. extension Producer {
  87. func map<T>(_ transform: @escaping (Value) -> T) -> Producer<T> {
  88. return lift { $0.map(transform) }
  89. }
  90. }
Add Comment
Please, Sign In to add comment