spin-example-reactiveswift.swift
March 15, 2020 ยท View on GitHub
// the State of the feedback loop struct Levels { let left: Int let right: Int }
// the transition requests of the feedback loop enum Event { case increaseLeft case decreaseLeft case increaseRight case decreaseRight }
// the side effects of the feedback loop func leftEffect(inputLevels: Levels) -> SignalProducer<Event, Never> { // this is the stop condition to our Spin guard inputLevels.left != inputLevels.right else { return .empty }
// this is the regulation for the left level
if inputLevels.left < inputLevels.right {
return SignalProducer(value: .increaseLeft)
} else {
return SignalProducer(value: .decreaseLeft)
}
}
func rightEffect(inputLevels: Levels) -> SignalProducer<Event, Never> { // this is the stop condition to our Spin guard inputLevels.left != inputLevels.right else { return .empty }
// this is the regulation for the right level
if inputLevels.right < inputLevels.left {
return SignalProducer(value: .increaseRight)
} else {
return SignalProducer(value: .decreaseRight)
}
}
// the reducer of the feedback loop func levelsReducer(currentLevels: Levels, event: Event) -> Levels {
guard currentLevels.left != currentLevels.right else { return currentLevels }
switch event {
case .decreaseLeft:
return Levels(left: currentLevels.left-1, right: currentLevels.right)
case .increaseLeft:
return Levels(left: currentLevels.left+1, right: currentLevels.right)
case .decreaseRight:
return Levels(left: currentLevels.left, right: currentLevels.right-1)
case .increaseRight:
return Levels(left: currentLevels.left, right: currentLevels.right+1)
}
}
// The builder way to build the Spin let levelsSpin = Spinner .initialState(Levels(left: 10, right: 20)) .feedback(Feedback(effect: leftEffect)) .feedback(Feedback(effect: rightEffect)) .reducer(Reducer(levelsReducer))
// The declarative way to build the Spin let levelsSpin = ReactiveSpin(initialState: Levels(left: 10, right: 20), reducer: Reducer(levelsReducer)) { Feedback(effect: leftEffect) Feedback(effect: rightEffect) }
// to make a reactive stream from the Spin SignalProducer.stream(from: levelsSpin)