ExMachine.Statechart (ex_machine v0.1.2)

View Source

Statechart is the internal struct powering the state machine and provides base function to compile a statechart.

A statechart is builded passing a valid defined State struct to the the build/1 function.

  • states: a map of all the states in the statechart
  • configuration: the active configuration (the current state of the machine) when the statechart is running
  • running: true if the statechart is started
  • macrosteps: a list of Macrostep struct representing the whole history of the state machine, from the start to last transition (the head of the list)

A configuration is a list of lists: each inner list represents an orthogonal region of the statechart. The elements in each list are the active states, from deeper state (the simple or leaf state) up to the root state (always "root"). For example:

[["r11", "r1", "root"], ["s211", "s21", "s2", "root"]]

Summary

Functions

Build and return a Statechart struct that contains the compiled and validated version of the statechart in definition argument, ready to be executed in a Machine.

Return the Least Common Compound Ancestor of states list.

Returns the ancestors of state (parent of state, parent of parent, etc), in form of a list of string, ordered from nearest parent to (and always) the "root" state.

Returns the ancestors of state (parent of state, parent of parent, etc), in form of a list of string, ordered from nearest parent to (and excluded) the until state.

Returns the descendants of state, in form of an unordered MapSet of string, containing all the descendants (children, children of children, etc) of state.

Returns a list of states that must be entered when the machine is entering in the state target, considering the lcca

Return the list of enter actions for each state in list states_list, if defined for the state, in the same exact order of states_list

Return the list of exit actions for each state in list states_list, if defined for the state, in the same exact order of states_list

Returns a list of states that must be exited when the machine is exiting from the state source, considering the lcca

Return list of initial states from argument state deep to a leaf state.

Return a transition map if state have a transition defined to handle event, otherwise nil

Types

t()

@type t() :: %ExMachine.Statechart{states: map()}

Functions

build(definition)

Build and return a Statechart struct that contains the compiled and validated version of the statechart in definition argument, ready to be executed in a Machine.

During compilation, Statechart verifies that the definition is valid and raise an exception if there is a problem.

Examples

iex> eng = Statechart.build(%State{initial: "s1", substates: %{ "s1" => %State{}}})
iex> Enum.count(eng.states)
2

iex> Statechart.build("invalid")
** (ExMachine.Statechart.InvalidDefinition) Definition "invalid" is not valid

iex> defs = %State{initial: "invalid_state", substates: %{ "s1" => %State{}}}
iex> Statechart.build(defs)
** (ExMachine.Statechart.NotValidInitial) Initial state "invalid_state" is not valid or not a descendant of composite state "root"

find_lcca(statechart, states)

Return the Least Common Compound Ancestor of states list.

LCCA of a list states is the lowest (i.e. deepest) state in the state hierarchy that has all state in states as descendants.

In other words LCCA is the state s such that s is a ancestor of all states on states list and no descendants of s has this property.

Return nil if in the states list is present the root state because can't exist a state that is parent of root state.

Note that since we are speaking of ancestor (parent or parent of a parent, etc.) the LCCA is never a member of state list.

get_ancestors(statechart, state_name)

Returns the ancestors of state (parent of state, parent of parent, etc), in form of a list of string, ordered from nearest parent to (and always) the "root" state.

Examples

iex> defs = %State{initial: "s1", substates: %{ "s1" => %State{ initial: "s11", substates: %{ "s11" => %State{}}}}}
iex> eng = Statechart.build(defs)
iex> Statechart.get_ancestors(eng, "s11")
["s1", "root"]

get_ancestors_until(statechart, state_name, until)

Returns the ancestors of state (parent of state, parent of parent, etc), in form of a list of string, ordered from nearest parent to (and excluded) the until state.

Examples

iex> defs = %State{initial: "s1", substates: %{ "s1" => %State{ initial: "s11", substates: %{ "s11" => %State{}}}}}
iex> eng = Statechart.build(defs)
iex> Statechart.get_ancestors_until(eng, "s11", "root")
["s1"]

get_descendants(statechart, state_name)

Returns the descendants of state, in form of an unordered MapSet of string, containing all the descendants (children, children of children, etc) of state.

Examples

iex> defs = %State{initial: "s1", substates: %{ "s1" => %State{ initial: "s11", substates: %{ "s11" => %State{}}}}}
iex> eng = Statechart.build(defs)
iex> Statechart.get_descendants(eng, "root")
MapSet.new(["s1", "s11"])

get_entering_states(statechart, target, lcca)

Returns a list of states that must be entered when the machine is entering in the state target, considering the lcca

get_entry_actions(statechart, states_list)

Return the list of enter actions for each state in list states_list, if defined for the state, in the same exact order of states_list

get_exit_actions(statechart, states_list)

Return the list of exit actions for each state in list states_list, if defined for the state, in the same exact order of states_list

get_exiting_states(statechart, source, lcca)

Returns a list of states that must be exited when the machine is exiting from the state source, considering the lcca

get_initials(statechart, state)

Return list of initial states from argument state deep to a leaf state.

The function uses :initial key in the %State{} definition, unless it encounter a history state (to be implemented)

## Examples

iex> defs = %State{initial: "s1", substates: %{ "s1" => %State{ initial: "s11", substates: %{ "s11" => %State{}}}}}
iex> eng = Statechart.build(defs)
iex> Statechart.get_initials(eng, "root")
["root", "s1", "s11"]
iex> Statechart.get_initials(eng, "s1")
["s1", "s11"]

get_transition_for(statechart, state, event)

Return a transition map if state have a transition defined to handle event, otherwise nil

new()