On the implementation of state machines

Relevant projects

Concept summary and lesson

Examples/demo

Today we're going to pair-program our way through a couple of simple state machine implementations, one in typescript and one in c++. We'll see how the two are similar and how they are different, and we'll talk about some tradeoffs for implementing state machines.

There are two main approaches to making a state machine, and they each have strengths and weaknesses:

The Giant Switch Statement

The most straightforward way to make a state machine is to just have a simple switch statement that does something specific for each different state:

switch(state) {
case STATE_1: 
    do_state1_stuff();
    break;
case STATE_2:
    do_state2_stuff();
    break;
//...
default:
    do_default_stuff();
    break;
}

This approach has some nice features! Don't discount it because it's so simple. Here's what it's good for:

This approach is weak when:

The class hierarchy

In this version of the state machine, we make classes for:

The state machine keeps track of the currently-active state, and it has the list of possible states that could be active. The active state is always an instance of the State base class, and it always has functions that you can call to enter, update, and leave. The state machine also has a way to let the active state tell it to switch to a different state. This might be a return value from the update function, or it might be a message sent, or the state machine can just pass a reference to itself into the state's update function so the state can tell it when something has to happen. The third option is the most frequently used, but it has some problems with strict languages like rust.

There is an example of a c++ state machine in the Line Following lesson.

The class hierarchy approach is good for more complex state machines, where having all of the state code in a single file is just not practical. In this case, splitting it up into state classes makes the code a lot easier to understand, and it gives you some extra powers:

How do you choose?

When you're comfortable with the class hierarchy version of this, it's probably best to just default to that one. Most of the time, the number of states in your state machine will be way larger than you expected at the start!

Media resources

Homework