Current section

Files

Jump to
sippet lib code_lock.ex
Raw

lib/code_lock.ex

defmodule CodeLock do
def start_link(code) when is_list(code) do
:gen_statem.start_link({:local, :code_lock}, __MODULE__, code, [])
end
def button(digit) when is_integer(digit) do
:gen_statem.cast(:code_lock, {:button, digit})
end
def init(code) do
do_lock()
:erlang.start_timer(10000, self(), :kabum)
{:ok, :locked, %{code: code, remaining: code}}
end
def callback_mode() do
[:state_functions, :state_enter]
end
def locked(:enter, _old_state, _data) do
IO.puts("Entered 'locked' state")
:keep_state_and_data
end
def locked(:info, {:timeout, _timer, _key}, _data) do
IO.puts("Kabum in 'locked' state")
:keep_state_and_data
end
def locked(:cast, {:button, digit}, %{remaining: [digit]} = data) do
do_unlock()
{:next_state, :open, %{data | remaining: []}, [{:state_timeout, 5000, :lock}]}
end
def locked(:cast, {:button, digit}, %{remaining: [digit|rest]} = data) do
{:next_state, :locked, %{data | remaining: rest}, [{:state_timeout, 5000, :lock}]}
end
def locked(:cast, {:button, _digit}, %{code: code} = data) do
{:next_state, :locked, %{data | remaining: code}}
end
def locked(:state_timeout, :lock, %{code: code} = data) do
do_lock()
{:repeat_state, %{data | remaining: code}}
end
def open(:enter, _old_state, _data) do
IO.puts("Entered 'open' state")
:keep_state_and_data
end
def open(:state_timeout, :lock, %{code: code} = data) do
do_lock()
{:next_state, :locked, %{data | remaining: code}}
end
def open(:info, {:timeout, _timer, _key}, _data) do
IO.puts("Kabum in 'open' state")
:keep_state_and_data
end
def do_lock() do
IO.puts("Lock")
end
def do_unlock() do
IO.puts("Unlock")
end
def terminate(_reason, state, _data) do
if(state == :locked, do: do_lock())
:ok
end
def code_change(_vsn, state, data, _extra) do
{:ok, state, data}
end
end