Skip to content

Instantly share code, notes, and snippets.

@IUnknown68
Created November 22, 2014 11:44
Show Gist options
  • Save IUnknown68/182662c6d5bda213b32c to your computer and use it in GitHub Desktop.
Save IUnknown68/182662c6d5bda213b32c to your computer and use it in GitHub Desktop.
InitManager is a simple state machine, that runs an `init` or `shutdown` function for each state. It has methods to walk up or down to a certain state, and makes sure that each `init` (for walking up) or `shutdown` (waliking down) is called exactly once and only if needed.
//==============================================================================
// class InitManager
function InitManager(arStates) {
var _state = 0;
//----------------------------------------------------------------------------
// privates
// return `aState` limited to a valid arStates index
var _sanitizeState = function(aState) {
return Math.min(Math.max(parseInt(aState)||0, 0), arStates.length-1);
}
// sort arguments
// return a valid newState and args
var _getArgs = function(newState, args, defaultState) {
defaultState = _sanitizeState(defaultState);
var t = typeof newState;
var ret = {newState: newState, args: args};
if ('undefined' === t) {
// not set - set default
ret.newState = defaultState;
}
else if ('object' === t) {
// newState is args - set default...
ret.newState = defaultState;
// ...and set args
ret.args = newState;
}
else {
// newState supposed to be a state
ret.newState = _sanitizeState(newState);
}
return ret;
}
// run a certain state: init or shutdown
var _runState = function(aFnName, aState, aArgs) {
var args = ( ('undefined' !== typeof aArgs) && ('undefined' !== typeof aArgs[aState]) ) ?
aArgs[aState] :
undefined;
var state = arStates[aState];
if ('function' === typeof state[aFnName]) {
state[aFnName].apply(state, args);
}
};
//----------------------------------------------------------------------------
// public
// StepUp: Run `init` up to `newState` (including).
this.StepUp = function(newState, initArgs) {
var args = _getArgs(newState, initArgs, arStates.length-1);
for (_state; args.newState > _state; _state++) {
_runState('init', _state + 1, args.args);
}
};
// StepDown: Run `shutdown` down to `newState` (excluding).
this.StepDown = function(newState, shutdownArgs) {
var args = _getArgs(newState, shutdownArgs, 0);
for (_state; args.newState < _state; _state--) {
_runState('shutdown', _state, args.args);
}
};
}
//------------------------------------------------------------------------------
// SAMPLE
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// class implementing `init` and `shutdown` methods
function InitState(name) {
this.name = name;
}
InitState.prototype = {
init: function() {
console.log('init: %s. Args: ', this.name, arguments);
},
shutdown: function() {
console.log('shutdown: %s', this.name);
}
};
// Instance of `InitManager`
// Constructor takes an array of objects, each having an `init` and a `shutdown`
// method.
var manager = new InitManager([
new InitState('None:0'),
new InitState('Base:1'),
new InitState('App:2'),
new InitState('Background:3'),
new InitState('Controls:4'),
new InitState('Events:5')
]);
// enum for readable states
var None = 0,
Base = 1,
App = 2,
Background = 3,
Controls = 4,
Events = 5;
// Arguments for init calls.
// Can be an array or an object - the numeric state is the
// key in any case.
// Each entry contains the arguments to pass to the `init`
// call of the state.
// Each entry has to be an array.
var initArgs = {
};
// some sample args
initArgs[Base] = ['foo', 'bar'];
initArgs[Controls] = [{width: 100, height: 300}];
// Additionally there can also be shutdown arguments - not shown here.
//------------------------------------------------------------------------------
// MAIN
console.log('-------- StepUp(Background)');
manager.StepUp(Background, initArgs);
console.log('----------------------------------------');
console.log('.');
console.log('-------- StepDown(Base)');
manager.StepDown(Base);
console.log('----------------------------------------');
console.log('.');
console.log('-------- StepUp()');
manager.StepUp(initArgs);
console.log('----------------------------------------');
console.log('.');
console.log('-------- StepDown()');
manager.StepDown();
console.log('----------------------------------------');
console.log('.');
@IUnknown68
Copy link
Author

Can run a bunch of init/shutdown functions in a certain order. Has methods for spinning up / down to a certain state and call the init method when spinning up, and the shutdown method on spinning down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment