-
Notifications
You must be signed in to change notification settings - Fork 24
Concepts
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.
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 */
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.
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. |
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.
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). |
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 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.
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.
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;
- Home
- Tutorial
-
Concepts
- State Hierarchy
- Entry/Exit Actions
- Transition Actions
- Transition Guards
- Internal Transitions
- Default Transitions
- Event Deferring
- History
- Orthogonal Regions
- Event Priority
- Common Base
- Thread Safety
- Exception Safety Guarantees
- Under the Hood
- Event Processing
- Performance