Renamed ColdSignal to Source. Remains to be seen if this is a good idea.
This commit is contained in:
parent
09e270d688
commit
cb9f2411c5
|
@ -9,7 +9,7 @@
|
|||
/* Begin PBXBuildFile section */
|
||||
DC30FA8A1DDAFFED00C2CC7F /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC30FA891DDAFFED00C2CC7F /* Error.swift */; };
|
||||
OBJ_26 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* Bag.swift */; };
|
||||
OBJ_27 /* ColdSignal.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* ColdSignal.swift */; };
|
||||
OBJ_27 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* Source.swift */; };
|
||||
OBJ_28 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* Disposable.swift */; };
|
||||
OBJ_29 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* Event.swift */; };
|
||||
OBJ_30 /* Observer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Observer.swift */; };
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
DC30FA891DDAFFED00C2CC7F /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = "<group>"; };
|
||||
OBJ_10 /* ColdSignal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColdSignal.swift; sourceTree = "<group>"; };
|
||||
OBJ_10 /* Source.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Source.swift; sourceTree = "<group>"; };
|
||||
OBJ_11 /* Disposable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disposable.swift; sourceTree = "<group>"; };
|
||||
OBJ_12 /* Event.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = "<group>"; };
|
||||
OBJ_13 /* Observer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Observer.swift; sourceTree = "<group>"; };
|
||||
|
@ -87,7 +87,7 @@
|
|||
name = Products;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
OBJ_5 /* */ = {
|
||||
OBJ_5 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_6 /* Package.swift */,
|
||||
|
@ -95,7 +95,6 @@
|
|||
OBJ_15 /* Tests */,
|
||||
OBJ_18 /* Products */,
|
||||
);
|
||||
name = "";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
OBJ_7 /* Sources */ = {
|
||||
|
@ -110,11 +109,11 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_9 /* Bag.swift */,
|
||||
OBJ_10 /* ColdSignal.swift */,
|
||||
OBJ_11 /* Disposable.swift */,
|
||||
OBJ_12 /* Event.swift */,
|
||||
OBJ_13 /* Observer.swift */,
|
||||
OBJ_14 /* Signal.swift */,
|
||||
OBJ_10 /* Source.swift */,
|
||||
DC30FA891DDAFFED00C2CC7F /* Error.swift */,
|
||||
);
|
||||
name = Reflex;
|
||||
|
@ -172,7 +171,7 @@
|
|||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = OBJ_5 /* */;
|
||||
mainGroup = OBJ_5;
|
||||
productRefGroup = OBJ_18 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
|
@ -189,7 +188,7 @@
|
|||
buildActionMask = 0;
|
||||
files = (
|
||||
OBJ_26 /* Bag.swift in Sources */,
|
||||
OBJ_27 /* ColdSignal.swift in Sources */,
|
||||
OBJ_27 /* Source.swift in Sources */,
|
||||
OBJ_28 /* Disposable.swift in Sources */,
|
||||
OBJ_29 /* Event.swift in Sources */,
|
||||
OBJ_30 /* Observer.swift in Sources */,
|
||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
|||
|
||||
|
||||
/// A CiruitBreaker optionally holds a strong reference to either a
|
||||
/// `Signal` or a `ColdSignal` until a terminating event is
|
||||
/// `Signal` or a `Source` until a terminating event is
|
||||
/// received. At such time, it delivers the event and then
|
||||
/// removes its reference. In so doing, it "breaks the circuit"
|
||||
/// between the signal, the handler, and the input observer.
|
||||
|
@ -18,7 +18,7 @@ import Foundation
|
|||
class CircuitBreaker<Value, Error: Swift.Error> {
|
||||
|
||||
private var signal: Signal<Value, Error>? = nil
|
||||
private var coldSignal: ColdSignal<Value, Error>? = nil
|
||||
private var source: Source<Value, Error>? = nil
|
||||
fileprivate var action: Observer<Value, Error>.Action! = nil
|
||||
|
||||
/// Holds a strong reference to a `Signal` until a
|
||||
|
@ -37,18 +37,18 @@ class CircuitBreaker<Value, Error: Swift.Error> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Holds a strong reference to a `ColdSignal` until a
|
||||
/// Holds a strong reference to a `Source` until a
|
||||
/// terminating event is received.
|
||||
init(holding coldSignal: ColdSignal<Value, Error>?) {
|
||||
self.coldSignal = coldSignal
|
||||
init(holding source: Source<Value, Error>?) {
|
||||
self.source = source
|
||||
self.action = { [weak self] event in
|
||||
// If event is terminating dispose of the handlerDisposable.
|
||||
self?.coldSignal?.observers.forEach { observer in
|
||||
self?.source?.observers.forEach { observer in
|
||||
observer.send(event)
|
||||
}
|
||||
|
||||
if event.isTerminating {
|
||||
self?.coldSignal = nil
|
||||
self?.source = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ public protocol SignalType {
|
|||
/// then `NoError` can be used.
|
||||
associatedtype Error: Swift.Error
|
||||
|
||||
/// The exposed raw signal that underlies the ColdSignalType
|
||||
/// The exposed raw signal that underlies the `SignalType`.
|
||||
var signal: Signal<Value, Error> { get }
|
||||
|
||||
}
|
||||
|
@ -160,12 +160,12 @@ internal protocol InternalSignalType: SignalType {
|
|||
|
||||
public extension SignalType {
|
||||
|
||||
/// Adds an observer to the Signal which observes any future events from the Signal.
|
||||
/// If the Signal has already terminated, the observer will immediately receive an
|
||||
/// Adds an observer to the `Signal` which observes any future events from the `Signal`.
|
||||
/// If the `Signal` has already terminated, the observer will immediately receive an
|
||||
/// `Interrupted` event.
|
||||
///
|
||||
/// Returns a Disposable which can be used to disconnect the observer. Disposing
|
||||
/// of the Disposable will have no effect on the Signal itself.
|
||||
/// of the Disposable will have no effect on the `Signal` itself.
|
||||
@discardableResult
|
||||
public func add(observer: Observer<Value, Error>) -> Disposable? {
|
||||
let token = signal.observers.insert(value: observer)
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
public final class ColdSignal<V, E: Swift.Error>: ColdSignalType, InternalSignalType, SpecialSignalGenerator {
|
||||
public final class Source<V, E: Swift.Error>: SourceType, InternalSignalType, SpecialSignalGenerator {
|
||||
|
||||
public typealias Value = V
|
||||
public typealias Error = E
|
||||
|
||||
internal var observers = Bag<Observer<Value, Error>>()
|
||||
|
||||
public var coldSignal: ColdSignal {
|
||||
|
||||
public var source: Source {
|
||||
return self
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,11 @@ public final class ColdSignal<V, E: Swift.Error>: ColdSignalType, InternalSignal
|
|||
|
||||
private var started = false
|
||||
|
||||
/// Initializes a ColdSignal that will invoke the given closure at the
|
||||
/// Initializes a Source that will invoke the given closure at the
|
||||
/// invocation of `start()`.
|
||||
///
|
||||
/// The events that the closure puts into the given observer will become
|
||||
/// the events sent to this ColdSignal.
|
||||
/// the events sent to this `Source`.
|
||||
///
|
||||
/// In order to stop or dispose of the signal, invoke `stop()`. Calling this method
|
||||
/// will dispose of the disposable returned by the given closure.
|
||||
|
@ -69,83 +69,83 @@ public final class ColdSignal<V, E: Swift.Error>: ColdSignalType, InternalSignal
|
|||
|
||||
}
|
||||
|
||||
extension ColdSignal: CustomDebugStringConvertible {
|
||||
extension Source: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
let obs = Array(self.observers.map { String(describing: $0) })
|
||||
return "ColdSignal[\(obs.joined(separator: ", "))]"
|
||||
return "Source[\(obs.joined(separator: ", "))]"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public protocol ColdSignalType: SignalType {
|
||||
public protocol SourceType: SignalType {
|
||||
|
||||
/// The exposed raw signal that underlies the ColdSignalType
|
||||
var coldSignal: ColdSignal<Value, Error> { get }
|
||||
/// The exposed raw signal that underlies the SourceType
|
||||
var source: Source<Value, Error> { get }
|
||||
|
||||
/// Invokes the closure provided upon initialization, and passes in a newly
|
||||
/// created observer to which events can be sent.
|
||||
func start()
|
||||
|
||||
/// Stops the ColdSignal by sending an interrupt to all of it's
|
||||
/// Stops the `Source` by sending an interrupt to all of it's
|
||||
/// observers and then invoking the disposable returned by the closure
|
||||
/// that was provided upon initialization.
|
||||
func stop()
|
||||
|
||||
}
|
||||
|
||||
public extension ColdSignalType {
|
||||
public extension SourceType {
|
||||
|
||||
public var signal: Signal<Value, Error> {
|
||||
return Signal { observer in
|
||||
self.coldSignal.add(observer: observer)
|
||||
self.source.add(observer: observer)
|
||||
}
|
||||
}
|
||||
|
||||
/// Invokes the closure provided upon initialization, and passes in a newly
|
||||
/// created observer to which events can be sent.
|
||||
func start() {
|
||||
coldSignal.start()
|
||||
source.start()
|
||||
}
|
||||
|
||||
/// Stops the ColdSignal by sending an interrupt to all of it's
|
||||
/// Stops the `Source` by sending an interrupt to all of it's
|
||||
/// observers and then invoking the disposable returned by the closure
|
||||
/// that was provided upon initialization.
|
||||
func stop() {
|
||||
coldSignal.stop()
|
||||
source.stop()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public extension ColdSignalType {
|
||||
public extension SourceType {
|
||||
|
||||
/// Adds an observer to the ColdSignal which observes any future events from the
|
||||
/// ColdSignal. If the Signal has already terminated, the observer will immediately
|
||||
/// Adds an observer to the `Source` which observes any future events from the
|
||||
/// `Source`. If the `Signal` has already terminated, the observer will immediately
|
||||
/// receive an `Interrupted` event.
|
||||
///
|
||||
/// Returns a Disposable which can be used to disconnect the observer. Disposing
|
||||
/// of the Disposable will have no effect on the Signal itself.
|
||||
@discardableResult
|
||||
public func add(observer: Observer<Value, Error>) -> Disposable? {
|
||||
let token = coldSignal.observers.insert(value: observer)
|
||||
return ActionDisposable {
|
||||
self.coldSignal.observers.removeValueForToken(token: token)
|
||||
let token = source.observers.insert(value: observer)
|
||||
return ActionDisposable { [weak source = source] in
|
||||
source?.observers.removeValueForToken(token: token)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a ColdSignal, adds exactly one observer, and then immediately
|
||||
/// invokes start on the ColdSignal.
|
||||
/// Creates a `Source`, adds exactly one observer, and then immediately
|
||||
/// invokes start on the `Source`.
|
||||
///
|
||||
/// Returns a Disposable which can be used to dispose of the added observer.
|
||||
@discardableResult
|
||||
public func start(with observer: Observer<Value, Error>) -> Disposable? {
|
||||
let disposable = coldSignal.add(observer: observer)
|
||||
self.coldSignal.start()
|
||||
let disposable = source.add(observer: observer)
|
||||
source.start()
|
||||
return disposable
|
||||
}
|
||||
|
||||
/// Creates a ColdSignal, adds exactly one observer, and then immediately
|
||||
/// invokes start on the ColdSignal.
|
||||
/// Creates a `Source`, adds exactly one observer, and then immediately
|
||||
/// invokes start on the `Source`.
|
||||
///
|
||||
/// Returns a Disposable which can be used to dispose of the added observer.
|
||||
@discardableResult
|
||||
|
@ -153,8 +153,8 @@ public extension ColdSignalType {
|
|||
return start(with: Observer(observerAction))
|
||||
}
|
||||
|
||||
/// Creates a ColdSignal, adds exactly one observer for next, and then immediately
|
||||
/// invokes start on the ColdSignal.
|
||||
/// Creates a `Source`, adds exactly one observer for next, and then immediately
|
||||
/// invokes start on the `Source`.
|
||||
///
|
||||
/// Returns a Disposable which can be used to dispose of the added observer.
|
||||
@discardableResult
|
||||
|
@ -162,8 +162,8 @@ public extension ColdSignalType {
|
|||
return start(with: Observer(next: next))
|
||||
}
|
||||
|
||||
/// Creates a ColdSignal, adds exactly one observer for completed events, and then
|
||||
/// immediately invokes start on the ColdSignal.
|
||||
/// Creates a `Source`, adds exactly one observer for completed events, and then
|
||||
/// immediately invokes start on the `Source`.
|
||||
///
|
||||
/// Returns a Disposable which can be used to dispose of the added observer.
|
||||
@discardableResult
|
||||
|
@ -171,8 +171,8 @@ public extension ColdSignalType {
|
|||
return start(with: Observer(completed: completed))
|
||||
}
|
||||
|
||||
/// Creates a ColdSignal, adds exactly one observer for errors, and then
|
||||
/// immediately invokes start on the ColdSignal.
|
||||
/// Creates a `Source`, adds exactly one observer for errors, and then
|
||||
/// immediately invokes start on the `Source`.
|
||||
///
|
||||
/// Returns a Disposable which can be used to dispose of the added observer.
|
||||
@discardableResult
|
||||
|
@ -180,8 +180,8 @@ public extension ColdSignalType {
|
|||
return start(with: Observer(failed: failed))
|
||||
}
|
||||
|
||||
/// Creates a ColdSignal, adds exactly one observer for interrupts, and then
|
||||
/// immediately invokes start on the ColdSignal.
|
||||
/// Creates a `Source`, adds exactly one observer for interrupts, and then
|
||||
/// immediately invokes start on the `Source`.
|
||||
///
|
||||
/// Returns a Disposable which can be used to dispose of the added observer.
|
||||
@discardableResult
|
||||
|
@ -191,65 +191,65 @@ public extension ColdSignalType {
|
|||
|
||||
}
|
||||
|
||||
public extension ColdSignalType {
|
||||
public extension SourceType {
|
||||
|
||||
/// Creates a new `ColdSignal` which will apply a unary operator directly to events
|
||||
/// Creates a new `Source` which will apply a unary operator directly to events
|
||||
/// produced by the `startHandler`.
|
||||
///
|
||||
/// The new `ColdSignal` is in no way related to the source `ColdSignal` except
|
||||
/// The new `Source` is in no way related to the source `Source` except
|
||||
/// that they share a reference to the same `startHandler`.
|
||||
public func lift<U, F>(_ transform: @escaping (Signal<Value, Error>) -> Signal<U, F>) -> ColdSignal<U, F> {
|
||||
return ColdSignal { observer in
|
||||
public func lift<U, F>(_ transform: @escaping (Signal<Value, Error>) -> Signal<U, F>) -> Source<U, F> {
|
||||
return Source { observer in
|
||||
let (pipeSignal, pipeObserver) = Signal<Value, Error>.pipe()
|
||||
transform(pipeSignal).add(observer: observer)
|
||||
return self.coldSignal.startHandler(pipeObserver)
|
||||
return self.source.startHandler(pipeObserver)
|
||||
}
|
||||
}
|
||||
|
||||
public func lift<U, F>(_ transform: @escaping (Signal<Value, Error>) -> (Signal<U, F>, Signal<U, F>))
|
||||
-> (ColdSignal<U, F>, ColdSignal<U, F>)
|
||||
-> (Source<U, F>, Source<U, F>)
|
||||
{
|
||||
let (pipeSignal, pipeObserver) = Signal<Value, Error>.pipe()
|
||||
let (left, right) = transform(pipeSignal)
|
||||
let coldLeft = ColdSignal<U, F> { observer in
|
||||
let sourceLeft = Source<U, F> { observer in
|
||||
left.add(observer: observer)
|
||||
return self.coldSignal.startHandler(pipeObserver)
|
||||
return self.source.startHandler(pipeObserver)
|
||||
}
|
||||
let coldRight = ColdSignal<U, F> { observer in
|
||||
let sourceRight = Source<U, F> { observer in
|
||||
right.add(observer: observer)
|
||||
return self.coldSignal.startHandler(pipeObserver)
|
||||
return self.source.startHandler(pipeObserver)
|
||||
}
|
||||
return (coldLeft, coldRight)
|
||||
return (sourceLeft, sourceRight)
|
||||
}
|
||||
|
||||
/// Maps each value in the signal to a new value.
|
||||
public func map<U>(_ transform: @escaping (Value) -> U) -> ColdSignal<U, Error> {
|
||||
public func map<U>(_ transform: @escaping (Value) -> U) -> Source<U, Error> {
|
||||
return lift { $0.map(transform) }
|
||||
}
|
||||
|
||||
/// Maps errors in the signal to a new error.
|
||||
public func mapError<F>(_ transform: @escaping (Error) -> F) -> ColdSignal<Value, F> {
|
||||
public func mapError<F>(_ transform: @escaping (Error) -> F) -> Source<Value, F> {
|
||||
return lift { $0.mapError(transform) }
|
||||
}
|
||||
|
||||
/// Preserves only the values of the signal that pass the given predicate.
|
||||
public func filter(_ predicate: @escaping (Value) -> Bool) -> ColdSignal<Value, Error> {
|
||||
public func filter(_ predicate: @escaping (Value) -> Bool) -> Source<Value, Error> {
|
||||
return lift { $0.filter(predicate) }
|
||||
}
|
||||
|
||||
/// Splits the signal into two signals. The first signal in the tuple matches the
|
||||
/// predicate, the second signal does not match the predicate
|
||||
public func partition(_ predicate: @escaping (Value) -> Bool)
|
||||
-> (ColdSignal<Value, Error>, ColdSignal<Value, Error>) {
|
||||
-> (Source<Value, Error>, Source<Value, Error>) {
|
||||
return lift { $0.partition(predicate) }
|
||||
}
|
||||
|
||||
/// Aggregate values into a single combined value. Mirrors the Swift Collection
|
||||
public func reduce<T>(initial: T, _ combine: @escaping (T, Value) -> T) -> ColdSignal<T, Error> {
|
||||
public func reduce<T>(initial: T, _ combine: @escaping (T, Value) -> T) -> Source<T, Error> {
|
||||
return lift { $0.reduce(initial: initial, combine) }
|
||||
}
|
||||
|
||||
public func flatMap<U>(_ transform: @escaping (Value) -> U?) -> ColdSignal<U, Error> {
|
||||
public func flatMap<U>(_ transform: @escaping (Value) -> U?) -> Source<U, Error> {
|
||||
return lift { $0.flatMap(transform) }
|
||||
}
|
||||
|
Loading…
Reference in New Issue