QM  4.0.3
State Machines

QM™ provides extensive support for modern Hierarchical State Machines (HSMs) (UML Statecharts), which are perhaps the most effective and elegant technique of structuring event-driven systems. In fact, QM™ has been specifically designed for ease of diagramming HSMs and for generating efficient, production-quality code from them.

The most important innovation of HSMs over classical finite state machines (FSMs) is the hierarchical state nesting. The value of state nesting lies in avoiding repetitions, which are inevitable in the traditional "flat" FSM formalism and are the main reason for the "state-transition explosion" in FSMs. The semantics of state nesting allow substates to define only the differences of behavior from the superstates, thus promoting sharing and reusing behavior.

Note
The Quantum Leaps Application Note A Crash Course in UML State Machines introduces the main state machine concepts backed up by examples.
Application Note: A Crash Course in UML State Machines

This section focuses primarily on working with state machine diagrams, while the section Generating State Machine Code will cover generating code from state machines. Of course, these two aspects are related, so even while "simply drawing" state machine diagrams, you will need to take code generation into account.

Note
Section Working with Diagrams describes generic operations applicable to any diagram type, such as opening, closing, scrolling, panning, and zooming a diagram.

State Machine Base Classes

In QM™ a State Machine can be associated only with a class that is a direct or indirect subclass of the QP Framework base class QHsm, shown at the top of the class diagram below.

qp_sm.gif
State Machine Classes in QP 5.8+

The QHsm base class provides the basic interface init() and dispatch() for initializing a state machine and for dispatching events to it, respectively. The specific implementations of the state machine interface in the QHsm base class and its subclasses, such as QActive, QMsm, and QMActive, determine the state machine implementation strategy that QM™ will apply to generate code.

Note
QM™ supports classes and inheritance regardless of the target programming language, which currently can be either C or C++. The Application Note "Simple Object-Oriented Programming in C" describes how the QP/C and QP-nano frameworks as well as the QM™ code generator implement classes and inheritance in portable ANSI C.

The QHsm-Style State Machines

The QHsm and QActive classes from the class diagram above implement the The QHsm/QActive-Style Implementation Strategy that was originally designed for manual coding of HSMs, but now can also benefit from automatic code generation by QM™

The screen shot below shows how to select the superclass property of your state-machine/active-object class in the Class Property Sheet, so that it uses the QHsm/QActive-Sytle state machine implementation strategy:

sm_qhsm-style.png
Selecting QHsm/QActive-Style Superclass

The QHsm-style state machine code is highly readable and human-maintainable, but it requires discovering the transition-sequences (sequences of exit/entry/initial actions) at run-time as opposed to code-generation time.

Attention
Apart from changing the superclass property in the class Property Sheet, you also need to call the right superclass' constructor in the constructor of your state machine class. For direct subclasses of QActive , you need to call QActive_ctor() (for the QP/C and QP-nano frameworks) and QActive::QActive() (for the QP/C++ framework).
sm_qhsm-ctor.png
Calling the QActive_ctor() in the subclass' constructor
Note
You should consider QHsm/QActive-style state machines only when you are still interested in manual coding or maintaining your state machines. (But then you will be working against the strictly forward-engineering nature of QM™)

QMsm/QMActive-Style State Machines

The QMsm and QMActive classes from the class diagram above re-implement the state machine interface and thus provide an alternative QMsm/QMActive-Style Implementation Strategy that is more efficient than the QHsm-sylte strategy, but requires the assistance of the QM™ tool (as an advanced "state machine compiler") to generate the complete transition-sequences at code-generation time. The resulting code is still highly human-readable, but is not suitable for manual coding or maintaining.

The screen shot below shows how to select the superclass property of your state-machine/active-object class in the Class Property Sheet, so that it uses the QMsm/QMActive-Sytle state machine implementation strategy:

sm_qmsm-style.png
Selecting QMsm/QMActive-Style Superclass

The lab tests indicate that the QMsm/QMActive-style state machines can be about twice as fast as the QHsm-style state machines (see the next section below). Additionally, the QMsm/QMActive-style state machines require less runtime support (smaller event processor) and use about 70% less of stack space for the dispatch() operation than QHsm/QActive-style state machines.

Attention
Apart from changing the superclass property in the class Property Sheet, you also need to call the right superclass' constructor in the constructor of your state machine class. For direct subclasses of QMActive , you need to call QMActive_ctor() (for the QP/C and QP-nano frameworks) and QMActive::QMActive() (for the QP/C++ framework).
sm_qmsm-ctor.png
Calling the QMActive_ctor() in the subclass' constructor
Note
The QMsm/QMActive-style state machines are highly recommended over the older QHsm/QActive-style state machines described above. You should consider QHsm/QActive-style state machines only when you are still interested in manual coding or maintaining your state machines. (But then you will be working against the strictly forward-engineering nature of QM™)
Attention
The QMsm/QMActive-style implementation strategy requires a commercial license certificate to generate code.

Adding a State Machine

In the Model Explorer right-click on the Class to which you want to add the state machine and select Add State Machine from the popup menu.

blinky_sm_add.gif
Adding a State Machine to a Class
Note
The Add State Machine menu option is only available if a given class directly or indirectly inherits the QP class QMsm. Otherwise the option is "grayed-out".

Resizing a State Machine Diagram

As shown in the screen shot below, you can easily resize the Drawing Canvas of a State Diagram by dragging its right or bottom edges, or by dragging the resize handle in the bottom-right corner of the canvas. In each case the mouse cursor indicates the possible direction of resizing.

bm_diagram-canvas.gif
Resizing the Drawing Canvas

State Machine Toolbox

When a State Machine diagram is active, the State Machine Toolbox displays tools a specific collection of tools for adding new shapes to the active State Machine.

Note
The State Diagram Toolbox is enabled only when a state diagram is the active MDI window and the model is unlocked (). If the Toolbox is invisible, you need to show it with in the View->Draw Toolbar menu.

The usage of the tools in the State Diagram Toolbox is explained in the sections pertaining to the corresponding state machine elements:


Next: Working with States