simple-stopwatch

Demonstration of a simple state machine

by Tracy-Gregory Gilmore

HTML

<main>
  <div class="stateDisplay" id="divState"></div>
  <button id="btnStart">START</button>
  <button id="btnPause">PAUSE</button>
  <button id="btnStop">STOP</button>
  <button id="btnClear">CLEAR</button>
</main>

CSS

.stateDisplay {
  background-color: #DDD;
  text-align: center;
  text-transform: uppercase;

  width: 10em;
  font-size: 1.5rem;
  margin: 5px 2px;

  padding-block: 0.5em;
}

JavaScript

function showState(state) {
	divState.textContent = state;
}

function enableButtons(stateEngine) {
	btnStart.addEventListener('click', () => stateEngine.trigger('START'));
	btnStop.addEventListener('click', () => stateEngine.trigger('STOP'));
	btnPause.addEventListener('click', () => stateEngine.trigger('PAUSE'));
	btnClear.addEventListener('click', () => stateEngine.trigger('CLEAR'));
}

function StateEngine(machine, initial, subject) {
  showState(subject.state = initial);
  
  return {
    trigger(event) {
      const currentState = machine[subject.state];
      
      if (event in currentState) {
        subject.state = currentState[event];        
      }
      showState(subject.state);
    }
  };
}

enableButtons(StateEngine(
  {
    'clear': {
      'START': 'running'
    },
    'running': {
      'STOP': 'stopped',
      'PAUSE': 'paused'
    },
    'paused': {
      'PAUSE': 'running'
    },
    'stopped': {
      'CLEAR': 'clear'
    }
	},
  'clear',
  {
    state: ''
  })
);