[][src]Crate macro_machines

State machine macros with logging and graphviz DOT file generation.

Repository

An example that shows a number of features of the macro syntax is a Door state machine with:

  • two states: Closed (with state-local variable knock_count and an exit action) and a simple state Open (with no state variables or actions)
  • three events: one internal event Knock (with action on the Closed state) and two external events Open (with associated action) and Close (without any action)
  • an extended state variable open_count -- this variable is initialized once and is independent of the current machine state
def_machine_debug! {
  Door (open_count : u64) @ door {
    STATES [
      state Closed (knock_count : u64) {
        exit {
          println!("knock count: {}", knock_count);
          println!("open count: {}", open_count);
        }
      }
      state Opened ()
    ]
    EVENTS [
      event Knock <Closed> () { knock_count } => { *knock_count += 1; }
      event Open  <Closed> => <Opened> ()  {} => { *open_count += 1; }
      event Close <Opened> => <Closed> ()
    ]
    initial_state:  Closed {
      initial_action: {
        println!("hello");
        println!("open_count: {:?}", door.as_ref().open_count);
      }
    }
    terminal_state: Closed {
      terminate_success: {
        println!("open_count: {:?}", door.as_ref().open_count);
        println!("goodbye")
      }
      terminate_failure: {
        panic!("door was left: {:?}", door.state())
      }
    }
  }
}

Within state entry and exit action blocks all extended state and local state variables are in scope.

In event actions, mutable references to extended state variables will implicitly be brought into scope of the associated action block, however local state variables need to be explicitly listed in the LHS brace of the action construct to be accessible (e.g. the knock_count local state variable in the Knock event action of the current example).

When making a universal or external transition, first state exit actions are performed, followed by event actions, and then after initializing the new state, state entry actions.

To make the state machine accessible in initial and terminal action blocks, the macro implementation requires an identifier be introduced, door, following the @ symbol. This variable is then brought into scope as an alias for a mutable self-reference in initial and terminal action blocks.

Initial and terminal actions are always before and after any state entry and exit actions, respectively.

The Door::dotfile() function will generate a '.dot' file string that can be saved and rendered as a PNG with layout generated by graphviz dot tool:

$ dot -Tpng door.dot > door.png

Re-exports

pub extern crate log;
pub extern crate variant_count;

Macros

def_machine

State machines with a default initial state.

def_machine_debug

State machines with a default initial state and deriving Debug.

def_machine_nodefault

State machine that requires runtime initialization.

def_machine_nodefault_debug

State machine that requires runtime initialization and deriving Debug.

Enums

HandleEventException

Describes an exceptional result when attempting to handle an event.

Traits

MachineDotfile

Methods for DOT file creation