-
Notifications
You must be signed in to change notification settings - Fork 429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Less hops in operator lifting. #140
Conversation
Sources/SignalProducer.swift
Outdated
/// | ||
/// - returns: A signal producer that applies signal's operator to every | ||
/// created signal. | ||
public func lift<U, F>(_ transform: @escaping (Signal<Value, Error>) -> Signal<U, F>) -> SignalProducer<U, F> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These trampolines are made as liftLeft
and liftRight
cannot be included in SignalProducerProtocol
(except the unary lift
). Having said that, these trampolines can be removed when Swift 3.1 lands, should we drop the protocol in favour of concrete same-type requirements.
840259b
to
2ca48ce
Compare
|
381d1ce
to
a6c212c
Compare
The idea here makes sense: why create more signals than are needed? But I find the implementation here to be difficult to follow. I think we need to try to clarify/simplify the code before merging. I'll swing back around to this after we get 1.0 out (or at least until we get 1.0 PRs merged). |
Not in a hurry. Gotta think of a better explanation to all this. ☕ |
I do hope to figure out a way to unify both "modes" to burn down the giant switch in the binary |
Heh, it turns out to be quite straightforward. 🙈 |
3ed5298
to
1a48d8f
Compare
c42b30e
to
d2cc8fc
Compare
1294573
to
ca79c9e
Compare
e17aca5
to
b5e5af7
Compare
acc33d7
to
6c1d164
Compare
a84aab9
to
ecf7dc2
Compare
Trying to get to this. It's on my list 😅 |
Note that this addressed #227, since now downstreams are interrupted by upstreams. IOW |
375869e
to
3036e50
Compare
Sources/SignalProducer.swift
Outdated
/// attached. | ||
/// Even if multiple instances of work from the same `SignalProducer` are executing | ||
/// concurrently, produced `Signal`s would see only events from its own instance of work, | ||
/// but not from the others. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the language was clearer before. Specifically this bit:
where each invocation of
start()
will create a new underlying operation.
Sources/SignalProducer.swift
Outdated
return self.init { _ in return } | ||
return self.init { observer, lifetime in | ||
lifetime.observeEnded { _ = observer } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this needs a merge from master
?
Sources/SignalProducer.swift
Outdated
/// performing any of its own post-creation side effect. | ||
fileprivate struct Builder { | ||
fileprivate let make: () -> (signal: Signal<Value, Error>, didCreate: () -> Void, interruptHandle: Disposable) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be clearer as a typealias.
typealias Builder = () -> (signal: Signal<Value, Error>, didCreate: () -> Void, interruptHandle: Disposable)
Or maybe a struct
instead of a tuple for the return value:
struct Instance {
var signal: Signal<Value, Error>
var didCreate: () -> Void
var interruptHandle: Disposable
}
let builder: () -> Instance
Sources/SignalProducer.swift
Outdated
lifetime.observeEnded(innerDisposable.dispose) | ||
transform(signal).observe(observer) | ||
} | ||
return SignalProducer<U, F>(SignalProducer<U, F>.Builder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically: this could be return SignalProducer<U, F> { ... }
.
Sorry this one took so long! 😅 |
The PR proposes to overhaul how
SignalProducer
produces a new instance ofSignal
.Summary
The public API of
SignalProducer
remains untouched.startWithSignal(_:)
is no longer responsible of creating theSignal
.SignalProducer.Builder
replaces the "start handler" as the internal representation ofSignalProducer
.The builder is responsible of creating an instance of
Signal
on request. It also creates a customised post-creation side effect and an interrupt handle for every producedSignal
.Unlike
startWithSignal(_:)
, the caller is responsible of invoking the post-creation side effect i.e.didCreate
. The swap in responsibility here gives a room of optimisation for liftedSignal
operators. They can now dodge the unnecessary relaySignal
that would otherwise be created by the oldstartWithSignal(_:)
.Condensed the description of
SignalProducer
.Result
For every lifted
Signal
operator applied, one lessSignal
would be produced. So given a producer chainSignalProducer(signal).map.map.map
, it would now produce a graph of fourSignal
s, instead of seven.