StateMachine.DSL (state_machine v0.1.6)

These macros help generating State Machine definition in a given Module.

Link to this section Summary

Functions

Experimental macro to generate GenStatem definition. See source...

Creates a main block for a State Machine definition. Compile time checks and validations help ensuring correct usage of this and other macros.

Creates an Event record which encapsulates one or more Transitions. Conceptually an Event is an external signal to change the state. Events can be accompanied by Guards — additional conditions, allowing for implementing more complex logic than supported by theoretical state machines.

Creates a State record with any atom as a name. Supports defining callbacks for before/after leaving/entering given state. For detailed description of Callbacks, see the module documentation, but currently only fully qualified function capture is supported: &Module.fun/arity

Defines a Transition, a path from one or more states to a single state. The same Event can contain all crazy combinations of transitions, but the resolution happens from top to bottom, from left to right. First matching transition will run.

Link to this section Functions

Link to this macro

define_gen_statem()

(macro)

Experimental macro to generate GenStatem definition. See source...

Link to this macro

defmachine(opts \\ [], block)

(macro)

Creates a main block for a State Machine definition. Compile time checks and validations help ensuring correct usage of this and other macros.

use StateMachine

defmachine field: :custom do
  # ... states, events, transitions
end

Options

  • :field - what field in the model structure holds the state value. Default: :state.
  • :repo - the Ecto Repo module. If provider, the support for Ecto is activated, including state getter/setters, Ecto.Type generation and custom trigger function.
  • :state_type - name for Ecto.Type implementation for State type. Generated inside of the module namespace. If you state machine is App.StateMachine, then Ecto.Type implementation will be accessible on App.StateMachine.(state_type). Default: StateType.
  • :event_type - name for Ecto.Type implementation for Event type. Default: EventType.
Link to this macro

event(name, opts \\ [], block)

(macro)

Creates an Event record which encapsulates one or more Transitions. Conceptually an Event is an external signal to change the state. Events can be accompanied by Guards — additional conditions, allowing for implementing more complex logic than supported by theoretical state machines.

Using guards allow for transitions from one to the multiple states, based on condition.

defmachine do
  # for state defs, see `state`

  event :wake_up, if: &Bedroom.slept_eight_hours?/1 do
    # for transition defs, see `transition`
  end
end

Options

  • :before - run the callback before the event.
  • :after - run the callback after the event.
  • :if - positive guard, must return true to proceed.
  • :unless - negative guard, must return false to proceed.
Link to this macro

state(name, opts \\ [])

(macro)

Creates a State record with any atom as a name. Supports defining callbacks for before/after leaving/entering given state. For detailed description of Callbacks, see the module documentation, but currently only fully qualified function capture is supported: &Module.fun/arity

defmachine do
  state :sleeping, after_leave: &Kitchen.brew_coffee/1
  state :working, before_enter: [&Commute.drive/1, &Commute.grab_a_newspaper/1]
end

Options

  • :before_leave - run the callback before leaving this state.
  • :after_leave - run the callback after leaving this state.
  • :before_enter - run the callback before entering this state.
  • :after_enter - run the callback after entering this state.
Link to this macro

transition(opts)

(macro)

Defines a Transition, a path from one or more states to a single state. The same Event can contain all crazy combinations of transitions, but the resolution happens from top to bottom, from left to right. First matching transition will run.

defmachine do
  # for state defs, see `state`

  event :wake_up do
    transition from: :sleeping, to: :sleeping,
      if: &Calendar.weekend?/0,
      unless: &Bedroom.slept_ten_hours?/1
    transition from: :sleeping, to: :awake
  end
end

Options

  • :before - run the callback before the transition.
  • :after - run the callback after the transition.
  • :if - positive guard, must return true to proceed.
  • :unless - negative guard, must return false to proceed.