Skip to content

Instantly share code, notes, and snippets.

@justinobney
Created April 14, 2016 20:58
Show Gist options
  • Save justinobney/1e1738056f281a2adb7b66904b89f1f5 to your computer and use it in GitHub Desktop.
Save justinobney/1e1738056f281a2adb7b66904b89f1f5 to your computer and use it in GitHub Desktop.
playing with a simple state machine
function createState(props){
if(!props.name){
throw new Error('state name required');
}
const defaults = {
canEnter(toState, fromState, appState){ return true; },
onEnter(toState, fromState, appState){ console.log(`entering ${toState.name}`) },
canExit(fromState, toState, appState){ return true; },
onExit(fromState, toState, appState){ console.log(`exiting ${fromState.name}`) }
};
return {...defaults, ...props};
}
const appState = {
count: 0
};
const stateMap = {
init: createState({
name: 'init',
canEnter(toState, fromState, appState){ return appState > 0;}
}),
one: createState({
name: 'one',
onEnter(toState, fromState, appState){ appState.count++; }
}),
two: createState({
name: 'two',
canExit(fromState, toState, appState){ return appState.count >= 2; },
onEnter(toState, fromState, appState){
setTimeout(() => appState.count++, 3000);
}
}),
three: createState({
name: 'three',
canEnter(toState, fromState, appState){ return fromState.name != 'one'; }
})
}
let current = stateMap.init;
const stateHistory = [current.name];
function transitionTo(stateName){
console.log('appState', appState);
const nextState = {...stateMap[stateName]};
if(nextState.name === current.name){
console.log('prevent transition: same state');
return;
}
if(!current.canExit(current, nextState, appState)){
console.log('prevent transition: cant exit');
return;
}
if(nextState.canEnter(nextState, current, appState)){
current.onExit(current, nextState, appState);
current = nextState;
stateHistory.push(current.name);
current.onEnter(nextState, current, appState)
} else {
console.log('prevent transition: cant enter');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment