Full Runtime C++ API Reference¶
This document provides the formal, comprehensive reference for all classes, types, traits, combinators, and containers in the fsmc C++ runtime library (include/fsm/backend/cpp/runtime/).
1. Core Engine: fsm::fsm¶
template <
typename Table,
typename InPorts = no_ports,
typename OutPorts = no_ports,
typename Registers = no_registers,
typename Services = no_services,
typename InitialState = typename Table::initial_state,
typename Observer = no_observer,
std::size_t DeferredCapacity = 16
>
class fsm;
Type Aliases¶
table_type: The underlyingfsm::transition_table<Rows...>.in_ports_type: The read-only input snapshot structure.out_ports_type: The single-assignment output structure.registers_type: The internal datapath state structure (\(z^{-1}\) memory).services_type: The abstract injected environment/driver interface.initial_state_type: The root initial state type.observer_type: The transition observer callback type.
Constructors¶
constexpr fsm(): Default constructs state machine in initial state.constexpr explicit fsm(services_type& srv, Table table = Table{}): Initializes with bound external services.constexpr explicit fsm(registers_type reg, Table table = Table{}): Initializes with initial registers.constexpr explicit fsm(registers_type reg, services_type& srv, Table table = Table{}): Initializes with registers and bound services.template <typename InitState> constexpr explicit fsm(InitState&& initial, Table table = Table{}): Initializes with custom initial state.template <typename InitState> constexpr explicit fsm(InitState&& initial, services_type& srv, Table table = Table{}): Initializes with custom initial state and bound services.
Member Functions¶
[!TIP] Which Overload to Call? - Standard (Recommended for 90% of apps): If services were passed at construction (
fsm(reg, srv)), callfsm.dispatch(ev, in, out)andfsm.step(in, out). - Stateless / No-Ports (Events Only): If your model defines no ports, callfsm.dispatch(ev)(step()is only needed if using anonymous transitions). - Dynamic / Call-Site Injection (Production & Testing): If services were not bound at construction (e.g. multi-channel dispatch, hardware failover, or unit testing with mocks), passsrvexplicitly:fsm.dispatch(ev, in, out, srv).
Lifecycle & Execution¶
step_result step(const in_ports_type& in, out_ports_type& out, services_type& srv): Evaluates continuous condition transitions. Automatically invokes active statedo_activity(...)during steady-state residence.template <typename DurationRep> step_result step(DurationRep dt, const in_ports_type& in, out_ports_type& out, services_type& srv): Evaluates continuous transitions with explicit \(\Delta t\). Automatically invokes active statedo_activity(...).step_result step(const in_ports_type& in, out_ports_type& out): Step overload omittingServices(uses constructor-bound services or default).step_result step(): Step overload for stateless state machines.template <typename Event> dispatch_result dispatch(const Event& ev, const in_ports_type& in, out_ports_type& out, services_type& srv): Synchronously evaluates transitions matchingEvent. Automatically invokes active statedo_activity(...)if no transition fired.template <typename Event> dispatch_result dispatch(const Event& ev, const in_ports_type& in, out_ports_type& out): Dispatch overload omittingServices(uses constructor-bound services or default).template <typename Event> dispatch_result dispatch(const Event& ev): Dispatch overload for stateless state machines.template <typename Rep, typename Period> std::size_t tick(std::chrono::duration<Rep, Period> dt): Advances deterministic timer manager bydt. Returns number of expired timers.template <typename Rep, typename Period, typename Callback> std::size_t tick(std::chrono::duration<Rep, Period> dt, Callback on_expired): Advances deterministic timers and invokeson_expired(timer_id)for each expired timer.
State Inspection & Introspection¶
template <typename State> [[nodiscard]] constexpr bool is_in() const noexcept: Returnstrueif active leaf state matchesState, or if the active leaf state is a descendant substate of compositeState(recursive hierarchical state query in \(O(1)\) constexpr time).template <typename State> [[nodiscard]] constexpr bool is_in_state() const noexcept: Alias foris_in<State>().[[nodiscard]] constexpr std::size_t state_index() const noexcept: Returns 0-based variant index of active state.[[nodiscard]] constexpr std::string_view current_state_name() const noexcept: Returns human-readable name of active state.void reset(): Resets the state machine back to its initial state, re-invoking initial stateon_enteractions, restoring default data registers, and clearing active timers, invariants, history cache, and deferred event queues.
History & Deferred Event Queries¶
template <typename ParentState> [[nodiscard]] std::string_view get_history() const noexcept: Returns the recorded history state name for compositeParentState.[[nodiscard]] std::string_view get_history(std::string_view parent) const noexcept: Dynamic string query for recorded history ofparent.void clear_history() noexcept: Clears all recorded shallow and deep history state memories.void clear_deferred() noexcept: Clears all pending deferred event FIFO queues.void clear_deferred_events() noexcept: Alias forclear_deferred().
State Residence Time Invariants¶
[[nodiscard]] constexpr bool is_invariant_satisfied() const noexcept: Returnstrueif current state residence time does not violate anymax_stay_duration_msconstraint.[[nodiscard]] constexpr bool has_invariant_violation() const noexcept: Returnstrueif an invariant violation has been detected.[[nodiscard]] const std::optional<invariant_violation_info>& last_invariant_violation() const noexcept: Returns metadata about the most recent invariant violation (state, elapsed ms, max allowed ms).void on_invariant_violation(std::function<void(const invariant_violation_info&)> handler): Attaches callback invoked immediately when an invariant violation occurs duringtick().void set_invariant_violation_handler(std::function<void(const invariant_violation_info&)> handler): Alias foron_invariant_violation().void clear_invariant_violation() noexcept: Resets invariant violation status and cached info.
Internal Memory¶
[[nodiscard]] constexpr Registers& registers() noexcept: Mutable reference to internal registers.[[nodiscard]] constexpr const Registers& registers() const noexcept: Read-only reference to internal registers.
Telemetry¶
template <typename Callback> void set_observer(Callback observer): Attaches transition observer callback.void clear_observer() noexcept: Detaches active observer.[[nodiscard]] constexpr observer_type& observer() noexcept: Returns reference to active observer (e.g.flight_recorder_observer).
Binary State Snapshot Serialization & Deserialization¶
bool serialize(std::uint8_t* dest, std::size_t capacity, std::size_t& bytes_written) const noexcept: Serializes complete state machine state (active state variant, history, timers, residence duration, registers) into fixed binary buffer.bool serialize(std::uint8_t* dest, std::size_t capacity) const noexcept: Convenience overload for serialization into raw buffer.bool serialize(std::span<std::uint8_t> buffer, std::size_t& bytes_written) const noexcept: (C++20) Span-based serialization.bool serialize(std::span<std::uint8_t> buffer) const noexcept: (C++20) Span-based serialization.bool deserialize(const std::uint8_t* src, std::size_t size, std::size_t& bytes_read) noexcept: Restores state machine from binary snapshot, validating magic word (0x46534D43), schema version, and FNV-1a checksum.bool deserialize(const std::uint8_t* src, std::size_t size) noexcept: Convenience overload for raw buffer deserialization.bool deserialize(std::span<const std::uint8_t> buffer, std::size_t& bytes_read) noexcept: (C++20) Span-based deserialization.bool deserialize(std::span<const std::uint8_t> buffer) noexcept: (C++20) Span-based deserialization.
2. Policy-Based Configuration: fsm::config¶
The policy configuration metaprogramming structure extracts and binds state machine domains in arbitrary order:
Semantic Policy Modifier Tags¶
fsm::with_registers<T>: Specifies internal datapath state type (default:no_registers).fsm::with_ports<In, Out>: Specifies input and output port structures (default:no_ports, no_ports).fsm::with_services<Srv>: Specifies external injected service interface (default:no_services).fsm::with_observer<Obs>: Specifies compile-time observer type (default:no_observer).fsm::with_trace_buffer<Capacity>: Installs zero-allocation circular ring buffer flight recorder (TraceBuffer<Capacity>).fsm::with_timer_capacity<N>: Configures static capacity of deterministic timer manager (default:4).fsm::with_initial_state<State>: Overrides root initial state type (default:Table::initial_state).fsm::with_deferred_capacity<N>: Configures static capacity of deferred event queue (default:16).fsm::with_queue_capacity<N>: Configures ring buffer capacity in SPSC/async wrappers (default:64).
Modern Factory Type Aliases¶
template <typename Table, typename... Policies> using make_fsm: Instantiates synchronous core engine with extracted policies.template <typename Table, typename... Policies> using make_spsc_fsm: Instantiates lock-free SPSC engine with extracted policies.template <typename Table, typename... Policies> using make_thread_safe_fsm: Instantiates active object engine with extracted policies.
3. Transition Table Builders: fsm::transition_table & fsm::row¶
fsm::row<Source, Event, Target, Guard, Action>¶
Declares a single transition edge:
// Format: fsm::row<SourceState, Event, TargetState, GuardPredicate, ActionEffect>
using MyRow = fsm::row<Idle, EvStart, Active, BatteryOkGuard, ArmMotorsAction>;
Source: Originating state struct.Event: Triggering event struct (orfsm::anonymous_eventfor continuous transitions).Target: Target state struct, orfsm::history<ParentState, FallbackState>.Guard: Optional boolean callable (defaults tofsm::always_true).Action: Optional action callable (defaults tofsm::no_action).
fsm::on Fluent Builder¶
using MyTable = fsm::transition_table<
decltype(fsm::on<EvStart>().from<Idle>().to<Active>().guard<BatteryOk>().action<ArmMotors>())
>;
Boolean Guard Combinators¶
#include <fsm/backend/cpp/runtime/transition.hpp>
using CombinedGuard = fsm::and_<GuardA, fsm::or_<GuardB, fsm::not_<GuardC>>>;
State, History & Sampled Trigger Guard Predicates¶
#include <fsm/backend/cpp/runtime/transition.hpp>
// Guard checking if active state matches TargetState (or a descendant substate)
using InActiveMode = fsm::in_state<ActiveMode>;
// Guard checking if recorded history of ParentState matches SubState
using ResumedFromNominal = fsm::history_is<Operational, Nominal>;
// Sampled change trigger: evaluates predicate on a port and fires on value change across cycles
using AltitudeJump = fsm::change_<PortAccessor, Predicate>;
Action Combinators: fsm::seq_¶
#include <fsm/backend/cpp/runtime/transition.hpp>
// Sequential composition: executes Action1, then Action2, ..., then ActionN
using ChainedAction = fsm::seq_<ConditionAction, TransitionAction>;
Sequential action combinator that executes actions sequentially in FIFO order. Ideal for dual action execution ({ condition_action } / { transition_action }) and multi-action pipelines.
4. Execution Status: fsm::dispatch_result & fsm::step_result¶
#include "fsm/backend/cpp/runtime/traits/dispatch_result.hpp"
#include "fsm/backend/cpp/runtime/traits/step_result.hpp"
fsm::transition_trace¶
enum class transition_kind : std::uint8_t { external, internal };
struct transition_trace {
std::string_view source{};
std::string_view target{};
std::string_view event{};
std::string_view guard{};
std::string_view action{};
transition_kind kind{transition_kind::external};
[[nodiscard]] constexpr bool is_internal() const noexcept;
[[nodiscard]] constexpr bool is_external() const noexcept;
};
fsm::dispatch_result¶
enum class dispatch_status : std::uint8_t {
success, // Transition executed successfully
deferred, // Event was deferred in current state
guard_rejected, // Matching transition found, but guard evaluated to false
unhandled // No transition defined for event in active state
};
struct dispatch_result {
dispatch_status status{dispatch_status::unhandled};
std::optional<transition_trace> trace{std::nullopt};
[[nodiscard]] constexpr bool is_success() const noexcept;
[[nodiscard]] constexpr bool is_deferred() const noexcept;
[[nodiscard]] constexpr bool is_guard_rejected() const noexcept;
[[nodiscard]] constexpr bool is_unhandled() const noexcept;
[[nodiscard]] constexpr bool is_ok() const noexcept; // is_success() || is_deferred()
explicit constexpr operator bool() const noexcept { return is_ok(); }
[[nodiscard]] constexpr std::string_view to_string() const noexcept;
};
fsm::step_result¶
enum class step_status : std::uint8_t {
steady, // Machine remains nominally in active state
transitioned // A continuous transition condition fired
};
struct step_result {
step_status status{step_status::steady};
std::optional<transition_trace> trace{std::nullopt};
[[nodiscard]] constexpr bool has_transitioned() const noexcept;
[[nodiscard]] constexpr bool is_transitioned() const noexcept;
[[nodiscard]] constexpr bool is_steady() const noexcept;
explicit constexpr operator bool() const noexcept { return has_transitioned(); }
[[nodiscard]] constexpr std::string_view to_string() const noexcept;
};
5. Zero-Heap Storage: fsm::static_vector<T, Capacity>¶
A fixed-capacity, stack-allocated sequential container with bounded \(O(1)\) operations:
template <typename T, std::size_t Capacity>
class static_vector {
public:
constexpr bool push_back(const T& value) noexcept;
constexpr bool push_back(T&& value) noexcept;
constexpr void pop_back() noexcept;
constexpr void erase(std::size_t index) noexcept;
constexpr void clear() noexcept;
[[nodiscard]] constexpr T& front() noexcept;
[[nodiscard]] constexpr const T& front() const noexcept;
[[nodiscard]] constexpr T& back() noexcept;
[[nodiscard]] constexpr const T& back() const noexcept;
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept;
[[nodiscard]] constexpr const T& operator[](std::size_t index) const noexcept;
[[nodiscard]] constexpr std::size_t size() const noexcept;
[[nodiscard]] constexpr bool empty() const noexcept;
[[nodiscard]] constexpr bool full() const noexcept;
[[nodiscard]] static constexpr std::size_t capacity() noexcept;
};
6. Lock-Free SPSC Engine: fsm::spsc_fsm¶
template <
typename Table,
typename InPorts = no_ports,
typename OutPorts = no_ports,
typename Registers = no_registers,
typename Services = no_services,
std::size_t QueueCapacity = 64,
typename InitialState = typename Table::initial_state
>
class spsc_fsm;
Member Functions¶
Producer Context (Wait-Free O(1), ISR-Safe)¶
template <typename Event> bool post(Event&& ev) noexcept: Enqueues event into the ring buffer. Returnsfalseif the queue is full.
Consumer Context (RTOS Worker Thread)¶
bool process_one(): Pops and executes the single oldest event.bool process_one(const in_ports_type& in, out_ports_type& out): Pops and executes oldest event with I/O snapshot.std::size_t run_until_empty(): Drains and executes all queued events.std::size_t run_until_empty(const in_ports_type& in, out_ports_type& out): Drains and executes all queued events with I/O snapshot.step_result step(): Evaluates continuous condition step.step_result step(const in_ports_type& in, out_ports_type& out): Evaluates continuous condition step with I/O snapshot.template <typename DurationRep> step_result step(DurationRep dt, const in_ports_type& in, out_ports_type& out): Evaluates continuous step with \(\Delta t\).template <typename Rep, typename Period> std::size_t tick(std::chrono::duration<Rep, Period> dt): Advances deterministic timer manager bydt.template <typename Rep, typename Period, typename Callback> std::size_t tick(std::chrono::duration<Rep, Period> dt, Callback on_expired): Advances timers and invokeson_expired(timer_id).void reset() noexcept: Resets internal state machine back to its initial state, restores default registers, and drains pending queues.
Reader Context & Invariant Inspection (Lock-Free)¶
Registers snapshot_registers() const noexcept: Captures consistent register snapshot using atomic sequence lock without blocking worker.std::string_view state_name() const noexcept: Atomic load of active state name.template <typename State> bool is_in_state() const noexcept: Atomic state type query (supports leaf states and composite ancestor states).template <typename State> bool is_in() const noexcept: Alias foris_in_state<State>().bool is_invariant_satisfied() const noexcept: Checks if current state residence satisfies permanence invariant.bool has_invariant_violation() const noexcept: Checks if an invariant violation has occurred.std::optional<invariant_violation_info> last_invariant_violation() const noexcept: Returns last invariant violation info.void on_invariant_violation(std::function<void(const invariant_violation_info&)> handler): Attaches invariant violation callback.void clear_invariant_violation() noexcept: Resets invariant violation status.
7. SPSC Policy-Based Alias: fsm::make_spsc_fsm¶
template <typename Table, typename... Policies>
using make_spsc_fsm = spsc_fsm<config<Table, Policies...>>;
Equivalent to spsc_fsm but uses the policy modifier system (with_registers<T>, with_queue_capacity<N>, etc.) instead of raw positional template arguments:
// Modern policy-based (preferred):
fsm::make_spsc_fsm<SensorTable,
fsm::with_registers<SensorRegisters>,
fsm::with_queue_capacity<256>
> spsc_sm(regs);
8. Thread-Safe MPSC Engine: fsm::thread_safe_fsm¶
template <
typename Table,
typename InPorts = no_ports,
typename OutPorts = no_ports,
typename Registers = no_registers,
typename Services = no_services,
typename InitialState = typename Table::initial_state,
std::size_t MaxQueueSize = 256
>
class thread_safe_fsm;
Member Functions¶
Asynchronous Operations¶
template <typename Event> void post(Event&& ev): Asynchronous, non-blocking fire-and-forget push.template <typename Event, typename Callback> void post(Event&& ev, Callback&& cb): Push with completion callback.template <typename Event> std::future<dispatch_result> post_async(Event&& ev): Push returningstd::future<dispatch_result>.template <typename Event, typename Rep, typename Period> void post_delayed(Event&& ev, std::chrono::duration<Rep, Period> delay, bool cancel_if_state_changes = false): Schedules event to fire after duration.template <typename Event, typename Rep, typename Period> void post_state_timeout(Event&& ev, std::chrono::duration<Rep, Period> delay): Schedules state-bound timeout automatically invalidated on state change.
Synchronous & State Queries (Mutex Guarded)¶
step_result step(const InPorts& in, OutPorts& out, Services& srv): Thread-safe continuous step evaluation under lock.step_result step(const InPorts& in, OutPorts& out): Step overload using constructor-bound services.step_result step(): Step overload for stateless state machines.template <typename DurationRep> step_result step(DurationRep dt, const InPorts& in, OutPorts& out, Services& srv): Step with \(\Delta t\).template <typename DurationRep> step_result step(DurationRep dt, const InPorts& in, OutPorts& out): Step with \(\Delta t\) and constructor-bound services.template <typename Rep, typename Period> std::size_t tick(std::chrono::duration<Rep, Period> dt): Thread-safe timer tick under mutex.template <typename Rep, typename Period, typename Callback> std::size_t tick(std::chrono::duration<Rep, Period> dt, Callback on_expired): Thread-safe timer tick with expiration callback.void reset(): Safely acquires lock, resets state machine to initial state, restores default registers, and clears active timers and pending events.std::string_view current_state_name() const: Returns active state name under mutex lock.template <typename State> bool is_in_state() const: Checks state type under mutex lock (supports leaf states and composite ancestor states).template <typename State> bool is_in() const: Alias foris_in_state<State>().bool is_invariant_satisfied() const: Thread-safe permanence invariant check.bool has_invariant_violation() const: Thread-safe invariant violation check.std::optional<invariant_violation_info> last_invariant_violation() const: Thread-safe retrieval of violation info.void on_invariant_violation(std::function<void(const invariant_violation_info&)> handler): Attaches invariant violation callback.void clear_invariant_violation(): Resets invariant violation status under mutex lock.
Safe-by-Design Datapath Access¶
registers_type snapshot_registers() const: Safely returns an isolated, consistent copy of internal registers under mutex lock.void update_registers(registers_type reg): Atomically updates internal registers under mutex lock.template <typename Func> decltype(auto) with_registers(Func&& fn): Executes callablefn(registers)inside exclusive mutex lock.
[!IMPORTANT] Data Race Prevention: Direct naked references via
registers()andunsafe_registers()were permanently removed to eliminate data races and torn reads. Always usewith_registers(),update_registers(), orsnapshot_registers().
9. Action and Hook Channel Indexes: fsm::channel_index¶
Constants identifying argument positions in compile-time multi-channel hook invocations:
namespace fsm {
inline constexpr std::size_t channel_index_event = 0;
inline constexpr std::size_t channel_index_src_state = 1;
inline constexpr std::size_t channel_index_dst_state = 2;
inline constexpr std::size_t channel_index_in_ports = 3;
inline constexpr std::size_t channel_index_out_ports = 4;
inline constexpr std::size_t channel_index_registers = 5;
inline constexpr std::size_t channel_index_services = 6;
inline constexpr std::size_t channel_index_fsm_inst = 7;
} // namespace fsm
10. C++20 Concepts: fsm::Guard and fsm::Action¶
Under C++20, callable predicates and transition actions are constrained using native concepts:
template <typename GuardType, typename EventType, typename StateType, typename InPorts, typename Registers, typename Services>
concept Guard;
bool, accepting any permutation of (event, state, in, reg, srv) or parameterless ().
template <typename ActionType, typename EventType, typename SrcStateType, typename DstStateType, typename InPorts, typename OutPorts, typename Registers, typename Services>
concept Action;
(event, src_state, dst_state, in, out, reg, srv).
11. Compile-Time Metaprogramming Traits¶
#include "fsm/backend/cpp/runtime/traits/observer_traits.hpp"
#include "fsm/backend/cpp/runtime/traits/reflection.hpp"
fsm::count_parent_states_v<StateList>: Computes exact compile-time count of composite states with substates (bounded history capacity).fsm::is_substate_of_v<Child, Parent>: ReturnstrueifChilddefinesstatic constexpr auto parentmatchingParent.fsm::get_state_name_static<T>(): Returns compile-timestd::string_viewfor state structT.
12. Zero-Heap Binary Snapshot Serialization¶
Provides high-reliability embedded checkpoints, NVRAM retention across reboot cycles, and hot-standby synchronization.
Structures & Constants¶
fsm::SNAPSHOT_MAGIC:0x46534D43('F','S','M','C').fsm::SNAPSHOT_VERSION: Schema revision (1).fsm::snapshot_header: 36-byte packed header storing magic, version, flags, active state index, history count, timer count, residence time ms, registers size, and payload FNV-1a checksum.fsm::snapshot_timer_entry: Packed 21-byte timer record (timer ID, interval ms, elapsed ms, periodic flag).fsm::compute_checksum(data, len): Deterministic 32-bit FNV-1a checksum over memory buffer.
Non-Member Helper Functions¶
template <typename FSM> bool serialize_state(const FSM& machine, std::uint8_t* dest, std::size_t capacity, std::size_t& bytes_written) noexcept: Serializes machine state into raw pointer buffer.template <typename FSM> bool serialize_state(const FSM& machine, std::uint8_t* dest, std::size_t capacity) noexcept: Serializes machine state into raw pointer buffer.template <typename FSM> bool serialize_state(const FSM& machine, std::span<std::uint8_t> buffer, std::size_t& bytes_written) noexcept: (C++20) Serializes machine state into destination span.template <typename FSM> bool serialize_state(const FSM& machine, std::span<std::uint8_t> buffer) noexcept: (C++20) Serializes machine state into destination span.template <typename FSM> bool deserialize_state(FSM& machine, const std::uint8_t* src, std::size_t size, std::size_t& bytes_read) noexcept: Deserializes machine state from raw buffer.template <typename FSM> bool deserialize_state(FSM& machine, const std::uint8_t* src, std::size_t size) noexcept: Deserializes machine state from raw buffer.template <typename FSM> bool deserialize_state(FSM& machine, std::span<const std::uint8_t> buffer, std::size_t& bytes_read) noexcept: (C++20) Deserializes machine state from source span.template <typename FSM> bool deserialize_state(FSM& machine, std::span<const std::uint8_t> buffer) noexcept: (C++20) Deserializes machine state from source span.
13. Zero-Heap Time-Travel Snapshot Recorder: fsm::snapshot_recorder¶
A deterministic, static circular ring buffer designed for real-time safety monitoring, hardware-in-the-loop (HIL) diagnostics, black-box flight recording, and time-travel rollback upon invariant or safety fault detection.
Class Template¶
Capacity: Maximum number of snapshots preserved in the circular ring buffer (must be > 0).MaxSnapshotSize: Maximum buffer size in bytes per snapshot (default256, must accommodatesizeof(snapshot_header)).
Structures: fsm::snapshot_entry<MaxSnapshotSize>¶
template <std::size_t MaxSnapshotSize = 256>
struct snapshot_entry {
std::array<std::uint8_t, MaxSnapshotSize> data{};
std::size_t size{0};
std::uint32_t tag{0};
std::uint64_t timestamp_us{0};
std::uint64_t step_count{0};
std::uint32_t checksum{0};
[[nodiscard]] constexpr bool is_valid() const noexcept;
};
Member Functions¶
| Method | Signature | Description |
|---|---|---|
record |
template <typename FSM> bool record(const FSM& machine, std::uint32_t tag = 0, std::uint64_t timestamp_us = 0) noexcept |
Captures and serializes the FSM state into the next circular slot with FNV-1a checksum. |
rollback |
template <typename FSM> bool rollback(FSM& machine, std::size_t steps = 1) noexcept |
Unwinds the state machine backwards by steps steps, verifying payload integrity and deserializing. |
rewind_to_checkpoint |
template <typename FSM> bool rewind_to_checkpoint(FSM& machine, std::uint32_t tag) noexcept |
Rewinds backwards to the most recent snapshot matching user tag tag. |
latest |
[[nodiscard]] const entry_type* latest() const noexcept |
Returns pointer to the most recently recorded entry, or nullptr if empty. |
size |
[[nodiscard]] constexpr std::size_t size() const noexcept |
Returns current number of valid stored snapshots in the ring buffer. |
capacity |
[[nodiscard]] static constexpr std::size_t capacity() noexcept |
Returns static ring buffer capacity (Capacity). |
empty |
[[nodiscard]] constexpr bool empty() const noexcept |
Returns true if recorder contains no snapshots. |
full |
[[nodiscard]] constexpr bool full() const noexcept |
Returns true if recorder has reached Capacity. |
total_recorded |
[[nodiscard]] constexpr std::uint64_t total_recorded() const noexcept |
Returns lifetime count of record() invocations since initialization. |
clear |
void clear() noexcept |
Resets head pointer and stored count to 0. |
14. Decomposed Runtime Detail Modules¶
For clean separation of concerns and maximum maintainability, internal engine mechanics are decomposed into isolated headers in fsm/backend/cpp/runtime/detail/:
detail/history_manager.hpp: Zero-overhead UML history storage with bounded capacity.detail/deferred_manager.hpp: Event deferral FIFO queue and cascading replay engine.detail/transition_executor.hpp: Unrolled compile-time transition fold dispatcher and 4-phase lifecycle runner.detail/reentrancy_tracker.hpp: Atomic thread ID tracking and depth recursion management.detail/notification_dispatcher.hpp: Snapshotting and out-of-lock observer callback dispatcher.