Template Class StateMachine
Defined in File state-machine.h
Class Documentation
-
template<typename State, typename Trigger>
class StateMachine Requires:
std::copy_constructible<State> && std::copy_constructible<Trigger> && std::equality_comparable<State> && std::equality_comparable<Trigger>A transition table for one typed state domain.
Rules are tested in insertion order; the first matching rule whose guard succeeds wins. Guards and actions may inspect other machines, allowing a game to compose state domains without requiring a controller or machine hierarchy. The machine is owned by its caller and is not synchronized or reentrant during trigger(). Stored callbacks own their captures; borrowed targets must survive use/removal. state() borrows this machine. Guards may add rules for later consideration in the same trigger; hooks for a chosen transition are copied before calling exit. Order is exit -> state assignment -> action -> enter. Exceptions propagate and stop that sequence: exit failure keeps old state, action/enter failure keeps new state; throwing State assignment follows that type’s guarantee. No rollback.
See also
- Template Parameters:
State – Copyable equality-comparable state identity; transitions assign it.
Trigger – Copyable equality-comparable event identity, distinct from State’s domain.
Public Types
-
using Guard = std::function<bool()>
Owned synchronous predicate; an empty guard always permits its matching rule.
-
using Action = std::function<void()>
Owned synchronous transition/entry/exit callback; empty means no callback.
Public Functions
-
inline explicit StateMachine(State initial)
Creates an empty rule/hook table at the supplied state.
- Parameters:
initial – Initial owned state, moved into the machine. No entry hook runs. State construction failures propagate. The caller controls the machine’s lifetime/thread.
-
inline void add_transition(State from, Trigger trigger, State to, Guard guard = {}, Action action = {})
Appends one rule; earlier matching rules retain priority.
- Parameters:
from – State from which this rule is eligible.
trigger – Trigger value compared for equality at dispatch.
to – State to install if this rule is selected.
guard – Optional owned predicate, invoked only for matching from/trigger; empty means true.
action – Optional owned callback after state assignment and before the entry hook. Copies/moves and allocation can throw. Captured borrowed targets outlive invocation. A guard may append rules considered later in the same trigger; do not reenter trigger().
-
inline void on_enter(State state, Action action)
Registers or replaces the entry hook for a state.
- Parameters:
state – State identity to match, copied/moved into the hook table.
action – Owned synchronous hook; empty disables that state’s hook. Registration does not invoke the hook. Replacement and allocation follow the value/callable guarantees; borrowed captures must survive future use/removal.
-
inline void on_exit(State state, Action action)
Registers or replaces the exit hook for a state.
- Parameters:
state – State identity to match, copied/moved into the hook table.
action – Owned synchronous hook; empty disables that state’s hook. Registration does not invoke the hook. Replacement and allocation follow the value/callable guarantees; borrowed captures must survive future use/removal.
-
inline const State &state() const
Declaration:
[[nodiscard]]Borrows the current state stored by this machine.
- Returns:
Reference valid while the machine lives; later transitions assign this same storage. Copy the value to retain an independent sample. Access must not race mutation.
-
inline bool trigger(const Trigger &event)
Executes the first matching rule whose guard permits it.
- Parameters:
event – Borrowed trigger identity, inspected synchronously.
- Returns:
True when a rule was executed, including self-transitions; false for no eligible rule. The sequence is exit hook, state assignment, action, then entry hook. Hooks for the chosen transition are copied before exit runs. Exceptions propagate without rollback: exit failure retains the old state; action/entry failure retains the new state. A throwing State assignment has its own partial-effect guarantee. No synchronization or recursive trigger support is provided; hook changes affect later selections.