Last active
November 9, 2020 18:02
-
-
Save danielt1263/a102153cb29be9c4354e0bbdebf1d5ca to your computer and use it in GitHub Desktop.
A stripped down version of The Elm Architecture for Swift. Great for implementing state machines.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Store.swift | |
// | |
// Created by Daniel Tartaglia on 3/11/17. | |
// Copyright © 2020 Daniel Tartaglia. MIT License | |
// | |
import Foundation | |
import RxSwift | |
final class Store<Action, State, Environment> { | |
let state: Observable<State> | |
init(initial: State, environment: Environment, reducer: @escaping (inout State, Action, Environment) -> Observable<Action>) { | |
state = action | |
.scan(into: initial) { [lock, action, disposeBag] in | |
reducer(&$0, $1, environment) | |
.subscribe(onNext: { | |
lock.lock() | |
action.onNext($0) | |
lock.unlock() | |
}) | |
.disposed(by: disposeBag) | |
} | |
.startWith(initial) | |
.share(replay: 1) | |
} | |
deinit { | |
lock.lock() | |
action.onCompleted() | |
lock.unlock() | |
} | |
private let action = ReplaySubject<Action>.createUnbounded() | |
private let lock = NSRecursiveLock() | |
private let disposeBag = DisposeBag() | |
} | |
extension Store: ObserverType { | |
func on(_ event: Event<Action>) { | |
if let element = event.element { | |
lock.lock() | |
action.onNext(element) | |
lock.unlock() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment