Software Engineering
Home Planning Requirements Writing Hazard Analysis Requirement Analysis Config Control Software Design Software Testing Software Standards Basic Logic

Software Design Case Study - Sky Diving

The Problem

This problem was devised specifically to teach the principles of designing a Mealy state machine. The assignment is to implement a state machine of states that a skydiver goes through. The program is to be a dialog based application. The state machine in this project is implemented using a [State, Event] table. The state diagram is:

For the Scream and Hurl Insult events, a random message would be displayed. The Exit state allows the user to be prompted to exit the program.

The Design

The first task is to identify all the states and events. The second task is to generate the transition table. This gives the next state for each [state, event] pair. The user interface has to display the current state and allow the user to select an event to execute. No state has more that 3 exit transitions, so to be safe I decided on 4 buttons for the dialog box. That should be enough to accommodate any expansion.

The buttons must change their text and event based on the current state, so each button was seen to have these attributes:

  • Style (visible or not used).
  • Text to display if visible.
  • Event to trigger when pressed.

A structure was defined for each button, which would be filled by the state handler upon entering the state. Because this was a small application whose only purpose was to be a learning exercise, I did not take the extra step of isolating the state machine from the user interface. The state handler directly interacts with the user interface objects. In a real application, it would be better to use SendMessage() to instruct the UI to set the buttons.

Each state was then seen to have these attributes:

  • Name.
  • Text to display on screen.
  • Entry function. Method to execute upon entering the state. Optional, can be set to NULL.
  • Four button structures, to define the button attributes for this state.

Finally, the transitions were seen to have these attributes:

  • [State, Event] - a pair of attributes that act as the primary key for the transition table.
  • Next State. The state to set when the given [State, Event] pair occurs.
  • Event function. Method to execute when the transition occurs, prior to setting the new state. Optional, can be set to NULL. This provides each state with an OnExit function for each exiting event.

The information flow is as follows:

Assuming that the state machine is initialized, when the event occurs, the application calls the state machine's DoEvent(...) method. The Event Table (a.k.a. transition table) uses the [CurrentState, Event] as a composite key and finds the appropriate entry in the table. If there is an Event function defined, it calls the function. It then gets the NewState from the table and sets the state. The SetState() method uses the state table to get the button data, set the buttons, and execute the state function (if any).

The pseudo-code for the logic is:

Program Starts (OnInitDialog)
Call SetState(Idle)

User clicks a button
{
    Button handler calls DoEvent( button event for that button )
    IF DoEvent() returned FALSE THEN
        Exit the program  // FALSE would only be returned by the Exit state.
    END IF
}

DoEvent( Event )
{
   FOR each entry in the Event Table DO
      IF this is the [Current State, Event] that occurred THEN
           Execute the event handler function (if one exists)
           Call SetState( NewState)
           Break out of FOR loop
      END IF
   END FOR
}

SetState( New State )
{
   FOR each entry in the State Table DO
      IF this is the New State THEN
         Set this as the Current State
         Set the button data per the array of ButtonDef structs
         Call the State function (if any)   // This function sets the display text
         Break out of FOR loop
      END IF
   END FOR
}

The Implementation

The user interface is rather dry and unexciting - but then, the purpose of the assignment was to make a state machine, not a computer game. The state function could always be modified to show graphics. One other design weakness that I left undone was the fact that, since the state machine's data is static, there can only be one instance of the object. Any other instances will share the same static data. A Singleton design pattern could have been used to ensure only a single instance, but then again, the purpose of the exercise was just to learn how to design a state machine.

Click here to get the C++ source code.

Click here to get the executable program.

Unit Testing

The state diagram was used as the basis for unit testing. For each state, each transition was tested to ensure that the correct events occurred.