Skip to content

Instantly share code, notes, and snippets.

@broomburgo
Last active March 14, 2016 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save broomburgo/851945c4b36aff83b4b9 to your computer and use it in GitHub Desktop.
Save broomburgo/851945c4b36aff83b4b9 to your computer and use it in GitHub Desktop.
import Foundation
public enum Persistence {
case Stop
case Continue
}
public final class Signal<Subtype> {
typealias Observation = Subtype -> Persistence
private var observations: [Observation] = []
public init() {}
public func onReception (observeFunction: Subtype -> Persistence) -> Signal {
observations.append(observeFunction)
return self
}
public func map<OtherSubtype>(transform: Subtype -> OtherSubtype) -> Signal<OtherSubtype> {
let mappedSignal = Signal<OtherSubtype>()
onReception {
mappedSignal.send(transform($0))
return .Continue
}
return mappedSignal
}
public func flatMap<OtherSubtype>(transform: Subtype -> Signal<OtherSubtype>) -> Signal<OtherSubtype> {
let mappedSignal = Signal<OtherSubtype>()
onReception {
transform($0).onReception {
mappedSignal.send($0)
return .Continue
}
return .Continue
}
return mappedSignal
}
public func filter(predicate: Subtype -> Bool) -> Signal {
let filteredSignal = Signal<Subtype>()
onReception {
if predicate($0) {
filteredSignal.send($0)
}
return .Continue
}
return filteredSignal
}
public func unionWith (otherSignal: Signal<Subtype>) -> Signal {
let unifiedSignal = Signal<Subtype>()
let observeFunction = { (value: Subtype) -> Persistence in
unifiedSignal.send(value)
return .Continue
}
onReception(observeFunction)
otherSignal.onReception(observeFunction)
return unifiedSignal
}
}
public func + <Subtype> (left: Signal<Subtype>, right: Signal<Subtype>) -> Signal<Subtype> {
return left.unionWith(right)
}
extension Signal {
private func send (value: Subtype) {
var newObservations: [Observation] = []
while observations.count > 0 {
let observe = observations.removeFirst()
let persistence = observe(value)
switch persistence {
case .Continue:
newObservations.append(observe)
case .Stop: break
}
}
observations = newObservations
}
}
public final class Emitter<Subtype> {
public let signal = Signal<Subtype>()
public func emit(value: Subtype) {
signal.send(value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment