infinite_state_machine 1.0.0
Infinite State Machine Library
Loading...
Searching...
No Matches
infinite_state_machine.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
5
6#ifndef INFINITE_STATE_MACHINE_HPP_
7#define INFINITE_STATE_MACHINE_HPP_
8
9// for efficient double-ended queue operations
10#include <deque>
11
12// for find algorithms
13#include <algorithm>
14
15// Why infinite state machine? This state machine allows for an arbitrary number
16// of nested states, enabling complex state hierarchies and transitions. No
17// limits on the nesting depth, i.e. the number of active states is only limited
18// by the available memory.
19namespace infinite {
20
24template <typename Topology> struct state {
28 using topology_ptr = Topology *;
37 topology_ptr self() { return static_cast<topology_ptr>(this); }
38};
39
44template <typename Topology> class state_machine {
45public:
48 virtual ~state_machine() {}
49
50 // state_machine (const state_machine &other);
51 // state_machine (state_machine &&other);
52 // state_machine& operator= (state_machine &&other);
53 // state_machine& operator= (const state_machine &other);
54
62 struct transition {
66 std::deque<state<Topology> *> exits;
70 std::deque<state<Topology> *> enters;
71 };
72
87 struct transition go(state<Topology> *to) {
88 std::deque<state<Topology> *> exits, enters;
89 // super, sub --> sub, super (reverse)
90 exits.assign(states.rbegin(), states.rend());
91 states.clear();
92 if (to != nullptr) {
93 // super.super, super, to!
94 //
95 // Avoid duplicating states in the enters deque.
96 // Duplicates correspond to cyclic state topologies.
97 for (;
98 to && std::find(enters.rbegin(), enters.rend(), to) == enters.rend();
99 to = to->super)
100 enters.push_front(to);
101 // Now match up the exits and enters.
102 // Transfer any matching states from exits to states.
103 while (!exits.empty() && !enters.empty() &&
104 exits.back() == enters.front()) {
105 states.push_back(exits.back());
106 exits.pop_back();
107 enters.pop_front();
108 }
109 states.insert(states.end(), enters.begin(), enters.end());
110 }
111 return {exits, enters};
112 }
113
114 // Operation go(to) is the only mutator.
115 // The rest are query methods on the state vector.
116
120 return states.empty() ? nullptr : states.back();
121 }
122
126 bool in(state<Topology> *state) const {
127 return std::find(states.cbegin(), states.cend(), state) != states.cend();
128 }
129
130private:
140 std::deque<state<Topology> *> states;
141};
142
143} /* namespace infinite */
144
145#endif /* INFINITE_STATE_MACHINE_HPP_ */
A state machine topology navigation class.
bool in(state< Topology > *state) const
Check if a state is active.
state< Topology > * at() const
Get the current state.
virtual ~state_machine()
Destructor for the state machine.
struct transition go(state< Topology > *to)
Transition to a new state.
A struct representing the states exited and entered during a transition.
std::deque< state< Topology > * > exits
The states that were exited during the transition.
std::deque< state< Topology > * > enters
The states that were entered during the transition.
A default abstract state representation.
topology_ptr super
Pointer to the super-state.
Topology * topology_ptr
Pointer type for the topology.
topology_ptr self()
Returns a pointer to the current state.