Skip to content

Instantly share code, notes, and snippets.

@Ben-G
Created June 11, 2016 23:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Ben-G/b3af4bb7edd9a56b2d5ed790f3c61cf3 to your computer and use it in GitHub Desktop.
Save Ben-G/b3af4bb7edd9a56b2d5ed790f3c61cf3 to your computer and use it in GitHub Desktop.
ReSwift Allow For Effects - Experiment
//: Playground - noun: a place where people can play
import Cocoa
protocol Action {}
final class Store<State> {
typealias Reducer = (Action, State) -> (State, [Any])
var state: State
var reducer: Reducer
var handlers: [Handler]
var subscribers: [(State)->()] = []
init(state: State, reducer: Reducer, handlers: [Handler]) {
self.state = state
self.reducer = reducer
self.handlers = handlers
}
func subscribe(subscriber: (State)->()) {
self.subscribers.append(subscriber)
}
func dispatch(action: Action) {
var other: [Any]
(self.state, other) = reducer(action, self.state)
self.subscribers.forEach {
$0(self.state)
}
handlers.forEach { $0.handle(other) }
}
}
protocol Handler {
func handle(other: [Any])
}
struct State {
var counter: Int
}
struct IncreaseCounter: Action {
var value: Int
}
struct DoubleCounter: Action {}
func rootReducer(action: Action, state: State) -> State {
switch action {
case let action as IncreaseCounter:
var state = state
state.counter += action.value
return state
default:
return state
}
}
func effectsRootReducer(action: Action, state: State) -> (State, [Any]) {
switch action {
case let action as IncreaseCounter:
var state = state
state.counter += action.value
return (state, [{ print("Another Effect") }, DoubleCounter()])
case let action as DoubleCounter:
var state = state
state.counter *= 2
return (state, [])
default:
return (state, [])
}
}
struct EffectHandler: Handler {
func handle(other: [Any]) {
for o in other {
if let o = o as? ()->() {
o()
}
}
}
}
struct EffectDispatchHandler: Handler {
func handle(other: [Any]) {
for o in other {
if let o = o as? Action {
store.dispatch(o)
}
}
}
}
let store = Store<State>(
state: State(counter: 0),
reducer: effectsRootReducer,
handlers: [EffectHandler(), EffectDispatchHandler()]
)
store.subscribe { state in
print(state)
}
store.dispatch(IncreaseCounter(value: 3))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment