nl_tokens: Our Elevator implementation implements 3 states : - open : the elevator doors are opened - closed : the elevator doors are closed - moving : the elevator is moving towards a level
pl_tokens: function ( ) { const self = this ; const TIME_PER_LEVEL = 1 * 1000 ; this . level = 0 ; this . <mask> = [ ] ; this . fsm = new Fsm ( ) ; /**
     * The elevator is in a stationary state
     * and its doors are opened.
     */ const open = new Fsm . State ( { fsm : self . fsm , name : 'open' , onEntry : function ( ) { const state = this ; console . log ( 'Door opened at level' , self . level ) ; setTimeout ( function ( ) { state . transitionTo ( closed ) ; } , 2000 ) ; } , /**
       * As the elevator's doors are currently opened
       * we push any user request to go to
       * a level on the level stack.
       */ onEvent : function ( event ) { if ( event . name === 'goToLevel' && event . level !== self . level ) { self . pushLevel ( event . level ) ; } } } ) ; /**
     * The elevator is in a stationary state
     * and its doors are closed.
     */ const closed = new Fsm . State ( { fsm : self . fsm , name : 'closed' , onEntry : function ( ) { console . log ( 'Door closed' ) ; // If there is a channel in the stack, // we move to that channel. if ( self . stack [ 0 ] ) { this . transitionTo ( moving ) ; } } , /**
       * When the elevator's doors are closed,
       * we wait for a request to move to another
       * level.
       */ onEvent : function ( event ) { if ( event . name === 'goToLevel' ) { if ( event . level === self . level ) { this . transitionTo ( open ) ; } else { self . pushLevel ( event . level ) ; this . transitionTo ( moving ) ; } } } } ) ; /**
     * The elevator is currently moving from a
     * level to another.
     */ const moving = new Fsm . State ( { fsm : self . fsm , name : 'moving' , onEntry : function ( ) { const state = this ; const next = self . stack . shift ( ) ; console . log ( 'Moving to level' , next ) ; setTimeout ( function ( ) { console . log ( 'Reached level' , next ) ; self . level = next ; state . transitionTo ( open ) ; } , TIME_PER_LEVEL * Math . abs ( next - self . level ) ) ; } , /**
       * As the elevator is currently moving and
       * cannot change direction nor open the
       * doors, we push any user request to go to
       * a level on the level stack.
       */ onEvent : function ( event ) { if ( event . name === 'goToLevel' ) { self . pushLevel ( event . level ) ; } } } ) ; // Starting the elevator in the `closed` state. this . fsm . start ( closed ) ; }