|
defmodule Pushbutton do |
|
@behaviour :gen_statem |
|
|
|
@moduledoc """ |
|
A simple pushbutton FSM. |
|
""" |
|
|
|
# Client API |
|
|
|
@doc """ |
|
Start the pushbutton, registering it locally under its module name.. |
|
""" |
|
def start(), do: :gen_statem.start({:local, __MODULE__}, __MODULE__, [], []) |
|
|
|
@doc """ |
|
Stop the pushbutton. |
|
""" |
|
def stop(), do: :gen_statem.stop(__MODULE__) |
|
|
|
@doc """ |
|
Push it. |
|
""" |
|
def push(), do: :gen_statem.call(__MODULE__, :push) |
|
|
|
@doc """ |
|
The number of times the button has been pushed to `on`. |
|
""" |
|
def get_count(), do: :gen_statem.call(__MODULE__, :get_count) |
|
|
|
# Server callbacks |
|
|
|
@doc """ |
|
Initialise the pushbutton; initial state `off`, number of pushes zero. |
|
""" |
|
def init(_arg), do: {:ok, :off, 0} |
|
|
|
@doc """ |
|
Terminate the pushbutton. |
|
""" |
|
def terminate(), do: :ok |
|
|
|
@doc """ |
|
The callback mode. |
|
""" |
|
def callback_mode(), do: :state_functions |
|
|
|
@doc """ |
|
Receive an event in the `off` state. |
|
""" |
|
def off({:call, from}, :push, data), do: {:next_state, :on, data + 1, [{:reply, from, :on}]} |
|
def off(event_type, event_content, data), do: handle_event(event_type, event_content, data) |
|
|
|
@doc """ |
|
Receive an event in the `on` state. |
|
""" |
|
def on({:call, from}, :push, data), do: {:next_state, :off, data, [{:reply, from, :off}]} |
|
def on(event_type, event_content, data), do: handle_event(event_type, event_content, data) |
|
|
|
@doc """ |
|
Receive an event not handled above, in any state. |
|
""" |
|
def handle_event({:call, from}, :get_count, data), do: {:keep_state, data, [{:reply, from, data}]} |
|
def handle_event(_event_type, _event_content, data), do: {:keep_state, data} |
|
end |