API Docs for:
Show:

File: development/js/utils/fsm.js

import objects from './object';

/**
 * Implementation of a simple finite state machine class
 *
 * @module Utils
 * @class Utils.FSM
 * @static
 */



var isNewState = (xs, x) => xs.every((s) => s.name !== x.name);


/**
 * Creates a Finite State Machine with addState(), removeState(), getState()
 *     and consume() methods
 *
 * @method FSM
 * @for Utils.FSM
 * @return {object} Finite State Machine (FSM)
 *
 * @example
 *     import FSM from './utils/fsm';
 *     
 *     var fsm = FSM().
 *         addState({name: 'first', events: {next: 'second'}}).
 *         addState({name: 'second', events: {next: 'third', previous: 'first'}}).
 *         addState({name: 'third', events: {previous: 'second'}});
 *
 *     fsm.getState();
 *     // -> 'first'
 *
 *     fsm.consume('next').getState();
 *     // -> 'second'
 *
 *     fsm.consume('next').getState();
 *     // -> 'third'
 *
 *     fsm.consume('next').getState();
 *     // -> 'third', since third has no next event
 *
 */
const FSM = function () {
    var states = [],
        cur;

    return {
        addState(state) {
            if (isNewState(states, state)) {
                states.push(state);
                if (cur == null) {
                    cur = state;
                }
            }
            return this;
        },
        removeState(state) {
            if (!isNewState(states, state)) {
                states = states.filter((s) => s.name !== state.name);
                if (cur === state) {
                    cur = null;
                }
                return this;
            }
        },
        consume(eventName) {
            if (cur != null && objects.has(eventName, cur.events)) {
                states.forEach((s) => {
                    if (s.name === cur.events[eventName]) {
                        cur = s;
                    }
                });
            }
            return this;
        },
        getState() {
            return cur ? cur.name : null;
        },
        destroyStates() {
            states = null;
            cur = null;
        }
    };
}



export default FSM;