There are two observables: the first named activator emits booleans. The second named signaler emits void events. There's a function f() which must be called under the next conditions:
If the last event from activator is true, and event from signaler comes, call f(). Otherwise (the last activator's event is false, or activator has not yet emitted anything), "remember" that signaler sent the event. As soon as activator emits true, call f() and clear "remembered" flag.
Example:
let activator = PublishRelay<Bool>()
let signaler = PublishRelay<Void>()
signaler.accept(()) // activator not emitted yet, just remember that signal came
activator.accept(true) // go to active state. signal is waiting. call f()
signaler.accept(()) // already activated. call f()
activator.accept(false)// go to inactive state
activator.accept(true) // go to active state.
signaler.accept(()) // call f()
activator.accept(false)// go to inactive state
signaler.accept(()) // inactive state, remember that signal came
signaler.accept(()) // still inactive state, remember that signal came
activator.accept(true) // go to active state. there is signal waiting. call f().
signaler.accept(()) // active state. call f().
I can achieve the desired behaviour using two state variables _isActive and _waiting:
var _isActive = false
var _waiting = false
activator.bind { isActive in
self._isActive = isActive
if isActive && self._waiting {
f()
self._waiting = false
}
}.disposed(by: _bag)
signaler.bind {
if self._isActive {
f()
} else {
self._waiting = true
}
}.disposed(by: _bag)
The question is: can I implement it without state variables, only by means of reactive operators?