Skip to content
Franklin Yu edited this page May 9, 2018 · 4 revisions

You can easily emit your own custom events anywhere inside your FSM by using the emit method:

var fsm = new machina.Fsm({
    states: {
        started: {
            doStuff: function() {
                emit('doingStuff', { foo: 'bar' });
            }
        }
        // more states & handlers, etc.
    }
});

However, there are several events built into machina which you can take advantage of:

Transition

The transition event is emitted just before the _onEnter of the new state is invoked. The event listener callbacks receive a single argument: an object containing toState and fromState properties. Transition event's payload structure:

{
    fromState: "previousStateName",
    action: "previousStateName.actionName",
    toState: "newStateName",
    namespace: "fsmNamespace"
}

Handling

The handling event is emitted just before an input handler is invoked. Event listener callbacks receive a single argument: an object containing inputType (the name of the handler), whether or not it has been delegated (to a child FSM), the ticket if it has been delegated and the FSM's namespace. Handling event's payload structure:

{
    inputType: "inputHandlerName",
    delegated: false,  // only applicable in hierarchical scenarios
    ticket: undefined, // only applicable in hierarchical scenarios
    namespace: "fsmNamespace"
}

Handled

The handled event is emitted just after an input handler completes execution. Event listener callbacks receive a single argument: an object containing inputType (the name of the handler), whether or not it has been delegated (to a child FSM), the ticket if it has been delegated and the FSM's namespace. Handled event's payload structure:

{
    inputType: "inputHandlerName",
    delegated: false,  // only applicable in hierarchical scenarios
    ticket: undefined, // only applicable in hierarchical scenarios
    namespace: "fsmNamespace"
}

Nohandler

The nohandler event is emitted when the FSM is asked to handle input, but no input handler for the current state matches the input. Event listener callbacks receive a single argument: an object containing inputType (the name of the handler), whether or not it has been delegated (to a child FSM), the ticket if it has been delegated, the FSM's namespace and the arguments provided when handle was invoked on the FSM. Nohandler event's payload structure:

{ 
    inputType: "inputHandlerName", 
    delegated: false,  // only applicable in hierarchical scenarios
    ticket: undefined, // only applicable in hierarchical scenarios
    namespace: "fsmNamespace",
    args: [ "args", "provided", 2, "the handle call" ]
}

Invalidstate

The invalidstate event is emitted when someone tries to transition the FSM into a state which does not exist. Event listener callbacks receive a single argument: an object containing state (current state), attemptedState (the state that doesn't exist on the FSM) and the FSM's namespace. Invalidstate event's payload structure:

{
    namespace: "fsmNamespace",
    state: "priorState",
    attemptedState: "stateThatDoesntExist"
}

Deferred

The deferred event is emitted when deferUntilTransition is used to queue up input for later replay. Event listener callbacks receive a single argument: an object containing state (the current state of the FSM), the FSM's namespace and queuedArgs. The queuedArgs member is an object which contains the type of deferral (which is currently always transition), as well as the args (arguments as an array) that were passed to the input. The queuedArgs member will also contain an untilState member, which will be the string value of the state passed to deferUntilTransition if one was provided. Deferred event's payload structure:

{
    state: "fsmState",
    namespace: "fsmNamespace",
    queuedArgs: {
        "args": [
            {
                inputType: "inputHandlerName",
                delegated: false, // only applicable in hierarchical scenarios
                ticket: undefined // only applicable in hierarchical scenarios
            }
        ],
        "type": "transition", // currently this is the only possible value
        "untilState": "ready"
    }
}

Note: There is a key difference between BevaioralFsm and Fsm events. Events emitted by BehavioralFsm instances also contain a client property, which is the state/client which was passed to the BehavioralFsm API as the first arg.