Maki
Loading...
Searching...
No Matches
maki::machine< Conf > Class Template Reference

The state machine implementation template. More...

#include <maki/machine.hpp>

Public Types

using context_type = IMPLEMENTATION_DETAIL
 The context type given to maki::machine_conf::context_a() or its variants.
 

Public Member Functions

 machine (const machine &)=delete
 
template<class... ContextArgs>
 machine (ContextArgs &&... ctx_args)
 The constructor.
 
 machine (machine &&)=delete
 
template<class Event>
bool check_event (const Event &event) const
 Checks whether calling process_event(event) would cause a state transition or a call to any action.
 
context_typecontext ()
 Returns the context instantiated at construction.
 
const context_typecontext () const
 Returns the context instantiated at construction.
 
template<const auto & StateBuilder>
bool is () const
 Returns whether the state created by StateBuilder is active in the region of the state machine. Only valid if machine is only made of one region.
 
machineoperator= (const machine &)=delete
 
machineoperator= (machine &&)=delete
 
template<class Event>
void process_event (const Event &event)
 Processes the given event.
 
template<class Event>
void process_event_no_catch (const Event &event)
 Like process_event(), but doesn't catch exceptions, even if maki::machine_conf::catch_mx() is set.
 
template<class Event>
void process_event_now (const Event &event)
 Like maki::machine::process_event(), but doesn't check if an event is being processed.
 
template<class Event>
MAKI_NOINLINE void push_event (const Event &event)
 Enqueues event for later processing.
 
template<int Index>
const auto & region () const
 Returns the maki::region object at index Index.
 
bool running () const
 Returns whether the region of the state machine is running. This function can only be called if the state machine contains only one region.
 
template<class Event = events::start>
void start (const Event &event={})
 Starts the state machine.
 
template<const auto & StateBuilder>
const auto & state () const
 Returns the maki::state object created by StateBuilder (of type maki::state_builder). Only valid if machine is only made of one region.
 
template<class Event = events::stop>
void stop (const Event &event={})
 Stops the state machine.
 

Static Public Attributes

static constexpr const auto & conf = Conf
 The state machine configuration.
 

Detailed Description

template<const auto & Conf>
class maki::machine< Conf >

The state machine implementation template.

Template Parameters
Confthe state machine configuration, with defined transition_tables and context options

Here is an example of valid state machine definition, where:

constexpr auto machine_conf = maki::machine_conf{}
.transition_tables(transition_table)
.context_a<context>()
;

The state machine type itself can then be defined like so:

using machine_t = maki::machine<machine_conf>;

Constructor & Destructor Documentation

◆ machine()

template<const auto & Conf>
template<class... ContextArgs>
maki::machine< Conf >::machine ( ContextArgs &&... ctx_args)
explicit

The constructor.

Parameters
ctx_argsthe arguments to be forwarded to the constructor of the root context

The constructor first instantiates all the contexts defined in the state machine, starting with the root context (i.e. the context specified in the maki::machine_conf object).

Finally, unless maki::machine_conf::auto_start() is set to false, maki::machine::start() is called.

Member Function Documentation

◆ check_event()

template<const auto & Conf>
template<class Event>
bool maki::machine< Conf >::check_event ( const Event & event) const

Checks whether calling process_event(event) would cause a state transition or a call to any action.

Parameters
eventthe event to be checked

This function is useful for checking whether an event is valid or not, given the current state of the state machine and guard checks against the event itself.

Note: Run-to-completion mechanism is bypassed and exceptions are not caught.

◆ process_event()

template<const auto & Conf>
template<class Event>
void maki::machine< Conf >::process_event ( const Event & event)

Processes the given event.

Parameters
eventthe event to be processed

It's hard to describe all the things this function does, as it is the point of the whole library, but let's try to list the basic stuff with the following pseudocode:

//Run-to-completion: Don't let potential recursive calls interrupt the
//current processing
if(processing_event)
{
push_event(event);
}
//Process the event
FOR_EACH_REGION()
{
//Process event in active state
const bool processed = CALL_ACTIVE_STATE_INTERNAL_ACTION();
if(!processed)
{
//Process event in transition table
FOR_EACH_TRANSITION_IN_REGION_TRANSITION_TABLE()
{
if
(
IS_ACTIVE_STATE(source_state) &&
SAME_TYPE(Event, event_type) &&
GUARD() == true
)
{
SET_ACTIVE_STATE(undefined);
CALL_EXIT_ACTION(source_state);
CALL_TRANSITION_ACTION();
CALL_ENTRY_ACTION(target_state);
SET_ACTIVE_STATE(target_state);
break;
}
}
}
}
//Run-to-completion: Process pending events the same way
process_pending_events();
MAKI_NOINLINE void push_event(const Event &event)
Enqueues event for later processing.
Definition machine.hpp:310
constexpr auto undefined
The state builder of the undefined state.
Definition states.hpp:28

◆ process_event_now()

template<const auto & Conf>
template<class Event>
void maki::machine< Conf >::process_event_now ( const Event & event)

Like maki::machine::process_event(), but doesn't check if an event is being processed.

Parameters
eventthe event to be processed

USE WITH CAUTION!

You can call this function if you're absolutely sure that you're not calling this function while maki::machine::process_event() is being called. Otherwise, run-to-completion will be broken.

Compared to maki::machine::process_event(), this function is:

  • faster to build, because the maki::machine::push_event() function template won't be instantiated;
  • faster to run, because an if statement is skipped.

maki::machine_conf::process_event_now_enabled() must be set to true for this function to be available.

◆ push_event()

template<const auto & Conf>
template<class Event>
MAKI_NOINLINE void maki::machine< Conf >::push_event ( const Event & event)

Enqueues event for later processing.

Parameters
eventthe event to be processed

You can call this function instead of doing a recursive call to process_event().

This function is slightly faster than process_event(), but if you're not sure what you're doing, just call process_event() instead.

◆ start()

template<const auto & Conf>
template<class Event = events::start>
void maki::machine< Conf >::start ( const Event & event = {})

Starts the state machine.

Parameters
eventthe event to be passed to the invoked actions, mainly the entry action of the initial state(s)

Concretely, if the machine is not already running, exits the internal stopped state and enters the initial state.

Reminder: There's no need to call this function after the construction, unless maki::machine_conf::auto_start is set to false.

◆ stop()

template<const auto & Conf>
template<class Event = events::stop>
void maki::machine< Conf >::stop ( const Event & event = {})

Stops the state machine.

Parameters
eventthe event to be passed to the invoked actions, mainly the exit action of the active state(s)

Concretely, if the machine is running, exits the active state and enters the internal stopped state.