template<std:: size_t states, std:: size_t inputs, class State, class Input>
StateMachine class
State machine.
Exploits the Interconnect library for a simple state machine. Information about state transitions is broadcasted through signals. The machine is meant to be defined and connected at compile time.
Basic usage
Define two enums for states and inputs. The enums should have consecutive values starting from 0
.
enum class State: std::uint8_t { Ready, Printing, Finished }; enum class Input: std::uint8_t { Operate, TakeDocument };
Then typedef
the state machine consisting of these two enums, count of all states and count of all inputs:
typedef Interconnect::StateMachine<3, 2, State, Input> Printer;
Now add your state transitions, for each transition first original state, then input, and then state after transition. Everything else is implicitly a no-op.
Printer p; p.addTransitions({ {State::Ready, Input::Operate, State::Printing}, {State::Printing, Input::Operate, State::Finished}, {State::Finished, Input::TakeDocument, State::Ready} });
Lastly connect transition signals to desired slots, so you can react to state changes:
Interconnect::connect(p, &Printer::entered<State::Ready>, [](State) { Utility::Debug() << "Printer is ready."; }); Interconnect::connect(p, &Printer::entered<State::Finished>, [](State) { Utility::Debug() << "Finished. Please take the document."; }); Interconnect::connect(p, &Printer::entered<State::Printing>, [](State) { Utility::Debug() << "Starting the print..."; }); Interconnect::connect(p, &Printer::exited<State::Printing>, [](State) { Utility::Debug() << "Finishing the print..."; });
Now, stepping the machine:
p.step(Input::Operate); p.step(Input::Operate); p.step(Input::TakeDocument);
will print the following output:
Starting the print... Finishing the print... Finished. Please take the document. Printer is ready.
Public types
-
enum (anonymous): std::
size_t { StateCount = states, InputCount = inputs }
Constructors, destructors, conversion operators
- StateMachine() explicit
- Constructor.
Public functions
- auto current() const -> State
- Current state.
-
void addTransitions(std::
initializer_list<StateTransition<State, Input>> transitions) - Add transitions to the list.
- auto step(Input input) -> StateMachine<states, inputs, State, Input>&
- Step the machine.
-
template<State previous, State next>auto stepped() -> Signal
- The machine is switching states.
-
template<State state>auto entered(State previous) -> Signal
- The machine entered given state.
-
template<State state>auto exited(State next) -> Signal
- The machine exited given state.
Enum documentation
template<std:: size_t states, std:: size_t inputs, class State, class Input>
enum Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: (anonymous): std:: size_t
Enumerators | |
---|---|
StateCount |
Count of states in the machine |
InputCount |
Count of inputs for the machine |
Function documentation
template<std:: size_t states, std:: size_t inputs, class State, class Input>
Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: StateMachine() explicit
Constructor.
All states are initially no-op (i.e., given state will not be changed to anything else for any input).
template<std:: size_t states, std:: size_t inputs, class State, class Input>
State Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: current() const
Current state.
Initial state is the one corresponding to 0
(i.e., usually the first).
template<std:: size_t states, std:: size_t inputs, class State, class Input>
void Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: addTransitions(std:: initializer_list<StateTransition<State, Input>> transitions)
Add transitions to the list.
Expects that all states have a value less than StateCount and inputs a value less than InputCount.
template<std:: size_t states, std:: size_t inputs, class State, class Input>
StateMachine<states, inputs, State, Input>& Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: step(Input input)
Step the machine.
Returns | Reference to self (for method chaining) |
---|
Switches current state based on the input
. If the new state is different from previous one, emits exited() with the old state and then entered() with the new one.
template<std:: size_t states, std:: size_t inputs, class State, class Input>
template<State previous, State next>
Signal Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: stepped()
The machine is switching states.
Emitted when machine goes from previous
state to next
state and they are different ones. Emitted after corresponding exited() signal and before corresponding entered() one.
template<std:: size_t states, std:: size_t inputs, class State, class Input>
template<State state>
Signal Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: entered(State previous)
The machine entered given state.
Parameters | |
---|---|
previous | State which was exited |
Emitted when machine goes to given state
from different one, right after corresponding stepped() signal.
template<std:: size_t states, std:: size_t inputs, class State, class Input>
template<State state>
Signal Corrade:: Interconnect:: StateMachine<states, inputs, State, Input>:: exited(State next)
The machine exited given state.
Parameters | |
---|---|
next | State which will be entered |
Emitted when machine leaves given state
for different one. The corresponding stepped() signal is emitted after this one.