Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // MARK: - Observer
- final class Observer<Value> {
- let update: (Value) -> Void
- init(update: @escaping (Value) -> Void) {
- self.update = update
- }
- }
- extension Observer: Hashable {
- var hashValue: Int {
- return ObjectIdentifier(self).hashValue
- }
- static func == (lhs: Observer, rhs: Observer) -> Bool {
- return lhs === rhs
- }
- }
- // MARK: - Signal
- final class Signal<Value> {
- private var observers = Set<Observer<Value>>()
- init(_ startHandler: @escaping (@escaping (Value) -> Void) -> Void) {
- startHandler { value in
- self.observers.forEach { $0.update(value) }
- }
- }
- func subscribe(_ observerAction: @escaping (Value) -> Void) {
- let observer = Observer<Value>(update: observerAction)
- observers.insert(observer)
- }
- static func pipe() -> (Signal, Observer<Value>) {
- var observer: Observer<Value>!
- let signal = Signal { action in
- observer = Observer(update: action)
- }
- return (signal, observer)
- }
- }
- // MARK: - Producer
- final class Producer<Value> {
- private let startHandler: (Observer<Value>) -> Void
- init(_ startHandler: @escaping (@escaping (Value) -> Void) -> Void) {
- self.startHandler = { startHandler($0.update) }
- }
- func start(_ observerAction: @escaping (Value) -> Void) {
- startWithSignal { signal in
- signal.subscribe(observerAction)
- }
- }
- func startWithSignal(_ setup: (Signal<Value>) -> Void) {
- let (signal, observer) = Signal<Value>.pipe()
- setup(signal)
- startHandler(observer)
- }
- func lift<T>(_ transform: @escaping (Signal<Value>) -> Signal<T>) -> Producer<T> {
- return Producer<T> { observerAction in
- self.startWithSignal { signal in
- transform(signal).subscribe(observerAction)
- }
- }
- }
- }
- extension Signal {
- func map<T>(_ transform: @escaping (Value) -> T) -> Signal<T> {
- return Signal<T> { action in
- self.subscribe { value in
- action(transform(value))
- }
- }
- }
- }
- extension Producer {
- func map<T>(_ transform: @escaping (Value) -> T) -> Producer<T> {
- return lift { $0.map(transform) }
- }
- }
Add Comment
Please, Sign In to add comment