Skip to content

Instantly share code, notes, and snippets.

@danielt1263
Last active November 9, 2020 18:02
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielt1263/a102153cb29be9c4354e0bbdebf1d5ca to your computer and use it in GitHub Desktop.
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.
//
// 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