Overview

In this section, we explicit the Kingly’s API for standard state machines and hierarchical state machines; and cover in detail the API semantics. For those with interest in software architecture, we also detail the principles at the core of Kingly design.

To start defining a state machine with Kingly, it is necessary to get acquainted with:

While that may seem like a lot, it is actually fairly simple to get started and progressively build up skills. Readers may find a gradual step-by-step introduction to the concepts may refer to the tutorials. You may want to go back and forth between the present reference and the tutorials, as one complements the other. The reader can also refer to the examples section for full-fledged additional examples.

This section aim to serve as a reference documentation and should contain the entire description of the public Kingly API. We also provide a glossary of terms that you can refer to anytime you doubt the meaning of a word.

If there is anything you would like to add or any feedback on the current API, let us know! We love to hear from you.

General concepts

In this section, we will use the example of a reasonably complex CD player application, whose behavior is modeled by a hierarchical state machine. For this example, we will show a run of the machine, and by doing so, illustrate advanced concepts such as compound states, and history states. This example will be focused on the modeling rather than the implementation.

CD drawer modeling

This example is taken from Ian Horrock’s seminal book on statecharts and is the specification of a CD player. The behavior of the CD player should be understandable from the visualization, or if not, from your previous experience with a CD player. From a didactic point of view, the example features advanced characteristics of hierarchical state machines, including history states, composite states, transient states, automatic transitions, and entry points. For a deeper understanding of how the transitions work in the case of a hierarchical machine, you can have a look at the terminology and sample run for the CD player machine.

cd player state chart

The salient facts are:

Example run

To illustrate the previously described machine semantics, let’s run the CD player example. The machine processes internal and external events. External events comes from the user or external systems. Internal events are generated by the machine itself. For instance, the INIT event is an internal event that the machine triggers to go to its initial control state (No Cd loaded here), or every time it transitions to a compound state (for instance CD Loaded) — in order to go to the initial control control state of the compound state.

Control state Internal event External event
INIT_STATE INIT
No Cd Loaded INIT
CD Drawer Closed
CD Drawer Closed Eject
CD Drawer Open Eject (put a CD)
Closing CD Drawer (eventless)
CD Loaded INIT
CD Loaded subgroup INIT
CD Stopped
CD stopped Play
CD playing Forward down
Stepping forwards Forward up
CD playing .

The previous table illustrates the semantics of the visualization. At start, the machine will transition to the No Cd Loaded control state. As this is a compound state, it will transition again to the initial control state of that compound state and end up in the CD Drawer Closed state. That compound state is not a compound state, so the machine will remain there. When the user triggers the Eject event, the graph tells us that the machine will transition to the CD Drawer Open control state. Triggering Eject again will have the machine transition to the Closing CD Drawer control state. That control state is eventless. That means that there are no events that causes it to change its control state. Instead the machine immediately takes any transition that is possible. We have two here, according to whether there is a CD in the drawer or not. You can try to do the run in your head by looking at the graph and compare your results with the previous table.

This is how a graph is used to model the behavior of an application. The control state (graph node) in which the machine is has transitions (graph edges) that define what events are reacted to, and what those reactions are (edge labels).

Note:

The full syntax for the visual language used to model state machines with graphs can be found in the Graph editor section.

From here, you can go to explore the createStateMachine API that allows you creating state machines. The parameters passed to the function will include a JavaScript encoding of graphs like the one we just presented.

Kingly machine semantics

The following is fairly technical. The objective is to provide you with a thorough understanding of how a Kingly machine processes inputs. You may not need to reach this level of details if you are just starting with the Kingly library. You may want to review the tutorials and additional examples.

We give here a quick summary of the behavior of a Kingly state machine:

Preconditions

Event processing

A few interesting points:

The aforedescribed behavior is loosely summarized here:

event processing

History states semantics

A history state relates to the past configuration of a compound state. There are two kinds of history states: shallow history states (H); and deep history states (H*). A picture being worth more than words, thereafter follows an illustration of both history states:

deep and shallow history

Assuming the corresponding machine has had the following run [INIT, EVENT1, EVENT3, EVENT5, EVENT4]:

In short, the history state allows short-circuiting the default fixed entry behavior for a compound state, which is to follow the transition triggered by the INIT event. When transitioning to the history state, the transition has as a target the last seen state for the entered compound state.

Contracts

Format

Initial event and initial state

By initial transition, we mean the transition with origin the machine’s default initial state.

Additionally the following applies:

Coherence

Semantic contracts

Those contracts ensure the good behavior of the state machine. and we recommend that they all be observed. However, some of them are not easily enforceable:

Contracts enforcement can be parameterized with settings.debug.checkContracts.

Design goals

The key objectives for the API were:

As a result of this, the following choices were made:

Concretely, our state machine will be created by the factory function createStateMachine, which returns a state machine which:

Let us insist again on the fact that the state machine is not, in general, a pure function of its inputs. However, a given output of the machine depends exclusively on the sequence of inputs it has received so far (causality property). This means that it is possible to associate to a state machine another function that takes a sequence of inputs into a sequence of outputs, in a way that that function is pure. This is what enables simple and automated testing.