Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Commit

Permalink
Simplify code
Browse files Browse the repository at this point in the history
  • Loading branch information
inamiy committed Feb 13, 2019
1 parent 069428e commit 522a143
Showing 1 changed file with 12 additions and 27 deletions.
39 changes: 12 additions & 27 deletions Sources/Automaton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,57 +70,42 @@ public final class Automaton<State, Input>

/// Recursive input-producer that sends inputs from `inputSignal`
/// and also additional effects generated by `EffectMapping`.
func recurInputProducer(_ inputProducer: Observable<Input>, strategy: FlattenStrategy) -> Observable<Input>
func recurInputProducer(_ inputProducer: Observable<Input>, strategy: FlattenStrategy) -> Observable<Reply<State, Input>>
{
return Observable<Input>.create { observer in
return Observable.create { observer in
let mappingSignal = inputProducer
.withLatestFrom(stateProperty.asObservable()) { ($0, $1) }
.map { input, fromState in
return (input, fromState, mapping(fromState, input)?.1)
return (input, fromState, mapping(fromState, input))
}
.share(replay: 1, scope: .forever)

let successSignal = mappingSignal
.filterMap { input, fromState, effect in
return effect.map { (input, fromState, $0) }
.filterMap { input, fromState, mapped in
return mapped.map { (input, fromState, $0) }
}
.flatMap(strategy) { input, fromState, effect -> Observable<Input> in
.flatMap(strategy) { input, fromState, mapped -> Observable<Reply<State, Input>> in
let (toState, effect) = mapped
return recurInputProducer(effect, strategy: strategy)
.startWith(input)
.startWith(.success(input, fromState, toState))
}

let failureSignal = mappingSignal
.filterMap { input, fromState, effect -> Input? in
return effect == nil ? input : nil
.filterMap { input, fromState, mapped -> Reply<State, Input>? in
return mapped == nil ? .failure(input, fromState) : nil
}

let mergedProducer = Observable.of(failureSignal, successSignal).merge()
let mergedProducer = Observable.merge(failureSignal, successSignal)

return mergedProducer.subscribe(observer)
}
}

let replySignal = recurInputProducer(inputSignal, strategy: strategy)
.withLatestFrom(stateProperty.asObservable()) { ($0, $1) }
.flatMap(.merge) { input, fromState -> Observable<Reply<State, Input>> in
if let (toState, _) = mapping(fromState, input) {
return .just(.success(input, fromState, toState))
}
else {
return .just(.failure(input, fromState))
}
}
.share(replay: 1, scope: .forever)

replySignal
.flatMap(.merge) { reply -> Observable<State> in
if let toState = reply.toState {
return .just(toState)
}
else {
return .empty()
}
}
.filterMap { $0.toState }
.bindTo(stateProperty)
.disposed(by: _disposeBag)

Expand Down

0 comments on commit 522a143

Please sign in to comment.