To implement a state machine, use the GenStateMachine behaviour in your module. You can choose between two primary callback modes via the callback_mode option in use GenStateMachine/2:
:handle_event_function (Default): You implement a single handle_event/4 callback that receives the event type, content, current state, and data. This is the standard approach.:state_functions: You implement functions named after your states (e.g., off/3, on/3). When the machine is in a specific state, the corresponding function is called. This is useful for complex state logic.
You can also enable :state_enter by passing it in a list to callback_mode, allowing you to register for :enter events.
Important: Never use a manual receive loop inside your callbacks; instead, handle custom messages using the :info event type.
defmodule Switch do
use GenStateMachine
# Default mode: handle_event/4
def handle_event(:cast, :flip, :off, data) do
{:next_state, :on, data + 1}
end
def handle_event({:call, from}, :get_count, state, data) do
{:next_state, state, data, [{:reply, from, data}]}
end
end