Statifier.StateMachine (statifier v1.9.0)
View SourceA GenServer wrapper around Statifier.StateChart for asynchronous state chart processing.
Using the StateMachine Macro
The use Statifier.StateMachine macro provides a convenient way to create
StateMachine modules with callback support:
defmodule MyMachine do
use Statifier.StateMachine, scxml: "my_machine.xml"
def handle_state_enter(state_id, state_chart, _context) do
Logger.info("Entered: #{state_id}")
end
def handle_send_action(target, event, data, _state_chart) do
case target do
"external_api" -> MyAPI.send(event, data)
_ -> :ok
end
end
endMacro Options
:scxml- SCXML file path or XML string (required):name- GenServer registration name:snapshot_interval- Milliseconds between snapshot calls:invoke_handlers- Map of invoke type to handler function for<invoke>elements
Manual Usage (without macro)
You can also use StateMachine directly without the macro:
Provides an OTP-compliant interface for running state charts as processes, with proper supervision support and clean separation from synchronous operations.
Usage
# Start from SCXML file
{:ok, pid} = Statifier.StateMachine.start_link("path/to/machine.xml")
# Start from SCXML string
{:ok, pid} = Statifier.StateMachine.start_link(xml_string)
# Send events asynchronously
Statifier.send(pid, "start_event")
Statifier.send(pid, "data_event", %{key: "value"})
# Query current state
active_states = Statifier.StateMachine.active_states(pid)Comparison with Synchronous API
StateMachine provides asynchronous processing via GenServer:
Statifier.send(pid, event)- Asynchronous, fire-and-forgetStatifier.StateMachine.active_states(pid)- Synchronous query
For synchronous processing, use the existing direct API:
Statifier.send_sync(state_chart, event)- Returns updated state chartStatifier.Configuration.active_leaf_states(config)- Direct access
Summary
Functions
Macro for creating StateMachine modules with callback support.
Get the current active leaf states.
Returns a specification to start this module under a supervisor.
Get the current StateChart (synchronous).
Send an event to the StateMachine asynchronously.
Start a StateMachine process.
Types
@type init_arg() :: String.t() | Statifier.StateChart.t()
@type t() :: %Statifier.StateMachine{ callback_module: module() | nil, snapshot_interval: non_neg_integer() | nil, snapshot_timer: reference() | nil, state_chart: Statifier.StateChart.t() }
Functions
Macro for creating StateMachine modules with callback support.
Options
:scxml- SCXML file path or XML string (required):name- GenServer registration name:snapshot_interval- Milliseconds between snapshot calls
Generated Functions
The macro generates:
start_link/1- Start the StateMachine GenServerchild_spec/1- OTP child specification for supervisors- Default callback implementations from StateMachineBehaviour
@spec active_states(GenServer.server()) :: MapSet.t(String.t())
Get the current active leaf states.
Returns a MapSet of currently active leaf state IDs.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec get_state_chart(GenServer.server()) :: Statifier.StateChart.t()
Get the current StateChart (synchronous).
Useful for debugging or getting the complete state.
@spec send_event(GenServer.server(), String.t(), map()) :: :ok
Send an event to the StateMachine asynchronously.
The event is processed asynchronously and the StateMachine's internal state is updated. No return value is provided.
Examples
Statifier.StateMachine.send_event(pid, "start")
Statifier.StateMachine.send_event(pid, "data_received", %{payload: data})
@spec start_link( init_arg(), keyword() ) :: GenServer.on_start()
Start a StateMachine process.
Arguments
init_arg- Can be:- SCXML file path (string ending in .xml)
- SCXML string content (containing <scxml)
- Pre-initialized
StateChart
Options
:callback_module- Module implementing StateMachineBehaviour callbacks:snapshot_interval- Interval for snapshot callbacks (milliseconds):log_level- Log level for state machine execution (:trace,:debug,:info,:warning,:error):log_adapter- Log adapter to use (defaults to environment-specific adapter)- Standard GenServer options (
:name,:timeout, etc.)
Examples
{:ok, pid} = StateMachine.start_link("machine.xml")
{:ok, pid} = StateMachine.start_link(xml_string, name: :my_machine)