Skip to content

Concepts

Sergei Fedorov edited this page Nov 20, 2016 · 2 revisions

A state machine consists of states, a graph of possible event transitions and a list of events that trigger those transitions. This article covers how those concepts are mapped to C++ code in afsm library.

afsm Code Structure

afsm-classes-concept

State Machine

To define a state machine you need to derive your state machine definition from ::afsm::def::state_machine template class, define initial_state type and define transitions type. Also a state machine can define deferred events, inner transitions and entry/exit actions.

To use the state machine you need to instantiate ::afsm::state_machine template with the definition class as the first template parameter. Other template arguments are optional.

namespace afsm{ 
namespace def {
// State machine definition base
template < typename T, typename ... Tags >
struct state_machine;
} /* namespace def */
// State machine instantiation
template < typename Def, typename Mutex, typename Observer, typename ObserverWrapper >
struct state_machine;
} /* namespace afsm */

::afsm::def::state_machine

The purpose of this class is to provide type aliases for derived classes to easily define inner states and state transitions.

Template parameters:

Parameter Description
T The type of state machine, e.g. struct my_state_machine : ::afsm::def::state_machine<my_state_machine>
Tags State machine tags

Available tags:

Tag Description
::afsm::tags::has_history The state or state machine has history and won't be cleared on exit
::afsm::tags::common_base<> All states in this state machine should derive from common base (TODO)
::afsm::tags::recursive State machine can push state (TODO)

Defined type aliases:

Type Description Alias For
transition_table A variadic template class for defining transitions ::afsm::def::transition_table
tr Transition item ::afsm::def::transition
in Internal transition item afsm::def::internal_transition
type_tuple Variadic template class for a list of types ::psst::meta::type_tuple
none A 'no type' placeholder ::afsm::none
not_ Predicate inverter ::psst::meta::not_
and_ Join several conditions with AND ::psst::meta::and_
or_ Join several conditions with OR ::psst::meta::or_

The class doesn't have any member functions.

::afsm::state_machine

This is the main class that is responsible for event handling, maintaining event queues and deferring events. It is the class describing the outermost state machine and it is the only class that exposes public member function process_event. It unwraps transition tables from definition classes and creates the transition graphs. The wrapper class publicly derives from the definition class.

Template parameters:

Parameter Description Default
T State machine definition type. -
Mutex Mutex type used for locking event queues. Not needed when there is no concurrent access to state machines instances. ::afsm::none
Observer Type for observing state machine's events, transitions, etc. Useful for debugging. ::afsm::none
ObserverWrapper Template template parameter, a class for calling methods of the observer. ::afsm::detail::ObserverWrapper

Public member functions:

Function Description
template < typename Event > result_type process_event(Event&& evt) Process event, trigger state transitions, transition actions, etc.
template < typename State > bool is_in_state() Check if the state machine is in a given state. State definition class should be used for this check. The state definition can be of any level of nesting.
template < ::std::size_t N > StateType& get_state() Get a reference (overloaded by machine const-ness) to an immediate sub-state (TODO Describe numbering).
template < StateDef > StateType& get_state() Get a reference (overloaded by machine const-ness) to an immediate sub state.
::std::size_t current_state() const Get index of current immediate sub-state (TODO Describe numbering).
common_base& current_state_base() Get current state cast to a reference (overloaded by machine const-ness) to common states base (when state machine is defined with common base).
template < typename Event> void state_enter(Event&&) Called internally when the machine is entered. Should not be used in user code.
template < typename Event> void state_exit(Event&&) Called internally when the machine is entered. Should not be used in user code.

Nested State Machine

A nested state machine is defined the same way as the outermost machine. If the outermost machine is defined with a common base, the nested state machine should be defined with the same common base, or calls to current_state_base will fail to compile.

::afsm::inner_state_machine

template < typename Def, typename FSM >
struct inner_state_machine;

Wrapper class for nested state machines. Exposes the same type aliases and member functions as ::afsm::state_machine except for process_event. process_event is declared protected so that it cannot be called due to an error. All events should be processed by the outermost state machine. The inner_state_machine is instantiated by enclosing state machine.

Template parameters:

Parameter Description
Def State machine definition type.
FSM Enclosing state machine type (wrapped).

State

A state is defined by deriving from ::afsm::def::state template. A state can define deferred events, inner transitions and entry/exit actions.

namespace afsm{ 
namespace def {
// State definition base
template < typename T, typename ... Tags >
struct state;
} /* namespace def */
// State instantiation
template < typename Def, typename FSM >
struct state;
} /* namespace afsm */

Template parameters:

Parameter Description
T The type of state machine, e.g. struct my_state_machine : ::afsm::def::state_machine<my_state_machine>
Tags State machine tags

Event

Event is any structure instance. The only requirement is that the event is copy constructible. Event is copied in case when it needs to be queued or deferred. If move constructor is available, and the event is passed by rvalue reference, the event will be moved to the queue. Events passed by rvalue reference can be consumed (moved) by transition actions or state entry actions. If the event is consumed by the transition action, it's data is not guaranteed to be accessible in state entry action, it is dependent on the implementation of event's move constructor.

Transition

A transition is a definition of a reaction to an event that implies state switching. Mandatory parameters of transition description are SourceState, Event and TargetState. Optional parameters are Action and Guard.

template < typename SourceState, typename Event, typename TargetState,
        typename Action = none, typename Guard = none >
struct transition;

Event can be ::afsm::none meaning this is a default transition. Default transitions are checked after each state transition and can impact performance. Default transitions must have a transition guard.

Internal Transition

An internal transition is event handling when no state switching takes place, the event is handled by a state (or a state machine) internally. The only mandatory parameter is event type. Optional parameters are Action and Guard.

template < typename Event, typename Action = none, typename Guard = none >
struct internal_transition;

Transition Actions

See Transition Actions

Entry/Exit Actions

See Entry and Exit Actions

Transition Guards

See Transition Guards