In ReactFX, we work with event streams. It provides various operations on event streams such as
reduceSuccessions. Of course these cannot cover all the use cases. In such a case, you can either extend LazilyBoundStream to implement your custom stream combinator, or you can use the state machine combinator.
A state machine has a state and multiple input streams. An event emitted by an input stream causes the state machine to update its state and/or to emit an event. We demonstrate ReactFX’s internal DSL (fluent API) for defining state machines on an example.
We implement a stream combinator that takes a source stream and two control streams. An event from one control stream mutes the source stream, an event from the other control stream unmutes the source stream. The resulting stream emits the same events as the source stream, but only when not muted. We are going to represent the internal state as a boolean indicating whether the source stream is muted.
1 EventStream<T> source = ...; 2 EventStream<?> muteImpulse = ...; 3 EventStream<?> unmuteImpulse = ...; 4 5 EventStream<T> combined = StateMachine.init(false) 6 .on(muteImpulse).transition((wasMuted, i) -> true) 7 .on(unmuteImpulse).transition((wasMuted, i) -> false) 8 .on(source).emit((muted, t) -> muted ? Optional.empty() : Optional.of(t)) 9 .toEventStream();
- On line 5 we set the initial state to
- Line 6 says that when an event arrives from the
muteImpulsestream, we set the internal state to
true(muted), no matter what the previous state or the value of the impulse is.
- Line 7 says that when an event arrives from the
unmuteImpulsestream, we set the internal state to
false(not muted), no matter what the previous state or the value of the impulse is.
- Line 8 states that when an event arrives from the
sourcestream, it is either emitted or not, based on the internal state (muted or not).
- Line 9 completes the creation of the state machine and the associated stream.