exfsm v0.1.2 ExFSM.Machine

Module to simply use FSMs defined with ExFSM :

Define a structure implementing ExFSM.Machine.State in order to define how to extract handlers and state_name from state, and how to apply state_name change. Then use ExFSM.Machine.event/2 in order to execute transition.

iex> defmodule Elixir.Door1 do
...>   use ExFSM
...>   deftrans closed({:open_door,_},s) do {:next_state,:opened,s} end
...> end
...> defmodule Elixir.Door2 do
...>   use ExFSM
...>   @doc "allow multiple closes"
...>   defbypass close_door(_,s), do: {:keep_state,Map.put(s,:doubleclosed,true)}
...>   @doc "standard door open"
...>   deftrans opened({:close_door,_},s) do {:next_state,:closed,s} end
...> end
...> ExFSM.Machine.fsm([Door1,Door2])
%{
  {:closed,:open_door}=>{Door1,[:opened]},
  {:opened,:close_door}=>{Door2,[:closed]}
}
iex> ExFSM.Machine.event_bypasses([Door1,Door2])
%{close_door: Door2}
iex> defmodule Elixir.DoorState do defstruct(handlers: [Door1,Door2], state: nil, doubleclosed: false) end
...> defimpl ExFSM.Machine.State, for: DoorState do
...>   def handlers(d) do d.handlers end
...>   def state_name(d) do d.state end
...>   def set_state_name(d,name) do %{d|state: name} end
...> end
...> struct(DoorState, state: :closed) |> ExFSM.Machine.event({:open_door,nil})
{:next_state,%{__struct__: DoorState, handlers: [Door1,Door2],state: :opened, doubleclosed: false}}
...> struct(DoorState, state: :closed) |> ExFSM.Machine.event({:close_door,nil})
{:next_state,%{__struct__: DoorState, handlers: [Door1,Door2],state: :closed, doubleclosed: true}}
iex> ExFSM.Machine.find_info(struct(DoorState, state: :opened),:close_door)
{:known_transition,"standard door open"}
iex> ExFSM.Machine.find_info(struct(DoorState, state: :closed),:close_door)
{:bypass,"allow multiple closes"}

Summary

Functions

Meta application of the transition function, using find_handler/2 to find the module implementing it

same as find_handler/2 but using a ‘meta’ state implementing ExFSM.Machine.State

find the ExFSM Module from the list handlers implementing the event action from state_name

return the FSM as a map of transitions %{{state,action}=>{handler,[dest_states]}} based on handlers

Types

meta_event_reply ::
  {:next_state, ExFSM.Machine.State.t} |
  {:next_state, ExFSM.Machine.State.t, timeout :: integer} |
  {:error, :illegal_action}

Functions

action_available?(state, action)

Specs

action_available?(ExFSM.Machine.State.t, action_name :: atom) :: boolean
available_actions(state)

Specs

available_actions(ExFSM.Machine.State.t) :: [action_name :: atom]
event(state, arg)

Specs

event(ExFSM.Machine.State.t, {event_name :: atom, event_params :: any}) :: meta_event_reply

Meta application of the transition function, using find_handler/2 to find the module implementing it.

event_bypasses(handlers)
find_bypass(handlers_or_state, action)
find_handler(arg)

same as find_handler/2 but using a ‘meta’ state implementing ExFSM.Machine.State

find_handler(arg, handlers)

Specs

find_handler({state_name :: atom, event_name :: atom}, [exfsm_module :: atom]) :: exfsm_module :: atom

find the ExFSM Module from the list handlers implementing the event action from state_name

find_info(state, action)
fsm(handlers)

Specs

fsm([exfsm_module :: atom]) :: ExFSM.fsm_spec

return the FSM as a map of transitions %{{state,action}=>{handler,[dest_states]}} based on handlers

infos(handlers, action)