Skip to content

The StateMachine: A Builder of Complex EventStreams

JordanMartinez edited this page Mar 16, 2016 · 1 revision

The problem

For most use cases, ReactFX's provided EventStreams will work just fine. However, there will be those situations where an EventStream needs to be created based on rules or circumstances that cannot be constructed using the provided EventStreams. For example, let's say we have the following event streams and combo is the combination of them:

EventStream<?> ticks = //
EventStream<?> randomizer = //
EventStream<?> flagEvents = //
EventStream<UserInputEvent> uiEvents = //

EventStream<Integer> combo = //

I want combo to have its own inner state. For example, it holds two values: a randomNumber value (a random integer value) and a allowRandomizing flag (when true, randomNumber can be updated to a new random value; when false, randomNumber cannot be changed). This inner state will affect what events it emits.

Now then, I want combo to emit an event according to a series of rules:

  • When ticks emits an event, combo should emit its randomNumber as an event.
  • When randomizer emits an event, combo should update it's randomNumber to a new value.
  • When flagEvents emits an event, combo's allowRandomizer flag should be inverted (if was true, set it to false; if was false, set it to true);
  • When uiEvents emits an event, combo's allowRandomizer flag should be set to true, regardless of what its value is.

Given the following abbreviations and symbols to indicate when an event is emitted and what value that event represents...

Name [abbreviated name] (data type / current value)
===============================================
Ticks [Ticks] (x)
Randomizer [Random] (x)
FlagEvents [Flag Inv] (x)
UIEvents [Force T] (x)
-------------------------------------------
Combo's randomNumber [Ran Int] (single digit number)
Combo's allowRandomizing [Allow] (T true / F false)
Combo's emitted event [Event] (single digit number)

... let's look at this marble diagram to see what should be expected:

Time: ------>
Ticks:   -------x------------------x--x--------------------x-->
Random:  ------x--------x----x---x-------------x----x--x------>
Flag Inv:----x-------------x---x-------------x------------x--->
Force T: ---------x--x-------------------x-------x------------>
===============================================================
Allow:   TTTTFFFFFTTTTTTTTTFFFFTTTTTTTTTTTTTTFFFFTTTTTTTTTFFF->
Ran Int: 4--------------8--------3------------------6--1------>
Event:   -------4------------------3--3---------3----------1-->

The Solution: StateMachine

This is obviously a use case that cannot be predicted. However, ReactFX does provide an API that can build an EventStream that fulfills the above requirements. It's called a StateMachine. Tomas wrote a blog post that does a good job explaining how it works. Both that blog post and the above example should give a developer a good idea for how it works and how to use it.