scenario-maker
Version:
controll app process
195 lines (151 loc) • 5.71 kB
JavaScript
var Promise = require('es6-promise').Promise;
var _ = require('underscore');
var SceneType = require('./SceneType');
var _scenes = {};
var _state = null;
var _processHashTable = null;
var _process = null;
var SCENE_TYPES = [
SceneType.START,
SceneType.END,
SceneType.PROCESS,
SceneType.DECISION
];
var helperFunc = {
checkProtoScenes: function(_scenes) {
if (_scenes.constructor !== Array)
throw new Error('new Scenario(...): Invalid scenes.');
return true;
},
checkScene: function(_scene) {
if (typeof _scene.name !== 'string')
throw new Error("new Scenario(...): Scene's name must be String.");
if (!_.contains(SCENE_TYPES, _scene.sceneType))
throw new Error("new Scenario(...): Invalid scene's type. You can use scene types: var SceneType = require('scenario-maker').SceneType");
if (typeof _scene.task !== 'function')
throw new Error("new Scenario(...): Scene's task must be function.");
return true;
},
makeScene: function(_scene) {
return {
name: _scene.name,
sceneType: _scene.type,
task: _scene.task,
nextScene: _scene.nextScene
};
}
};
var _Scenario = (function() {
/**
* Class for making scenario.
*
* @param startScene: Object
* @param scenes: Array
* @param endScene: Object
* @constructor
*/
var Scenario = function (startScene, scenes, endScene) {
this.START_SCENE = '';
this.END_SCENE = '';
helperFunc.checkProtoScenes(scenes);
_scenes[startScene.name] = helperFunc.makeScene(startScene);
_scenes[endScene.name] = helperFunc.makeScene(endScene);
this.START_SCENE = startScene.name;
this.END_SCENE = endScene.name;
for (var idx= 0, len= scenes.length; idx<len; idx++)
_scenes[scenes[idx].name] = helperFunc.makeScene(scenes[idx]);
for (var prop in _scenes)
helperFunc.checkScene(_scenes[prop]);
this._makeProcess();
};
Scenario.prototype._makeProcess = function() {
if (_process !== null) {
console.warn("Scenario._makeProcess(...): Already process is initialized.");
return;
}
this._makeProcessHashTable();
_process = function() {
_processHashTable[this.START_SCENE]();
}.bind(this);
};
Scenario.prototype._makeProcessHashTable = function() {
if (_processHashTable !== null) {
console.warn("Scenario._makeProcessHashTable(...): Already processHashTable is initialized.");
return;
}
_processHashTable = {};
var that = {
getCurrentScene: this.getCurrentScene,
getState: this.getState,
setState: this.setState
};
for (var prop in _scenes) {
var resolveNextScene = null;
var rejectNextScene = null;
switch(_scenes[prop].sceneType) {
case SceneType.START:
case SceneType.PROCESS:
resolveNextScene = _scenes[prop].nextScene;
rejectNextScene = this.END_SCENE;
break;
case SceneType.DECISION:
resolveNextScene = _scenes[prop].nextScene.success;
rejectNextScene = _scenes[prop].nextScene.failed;
break;
}
_processHashTable[_scenes[prop].name] = (function(scene, bindingObj, _resolveNextScene, _rejectNextScene) {
var _promise = function() {
return new Promise(scene.task.bind(this));
}.bind(bindingObj);
return (function() {
_promise().then(function() {
if (_resolveNextScene === null) return;
_processHashTable[_resolveNextScene]();
})['catch'](function() {
if (_rejectNextScene === null) return;
_processHashTable[_rejectNextScene]();
});
});
})(_scenes[prop], that, resolveNextScene, rejectNextScene);
}
};
Scenario.prototype.playScenario = function() {
if (_scenes.length === 0) {
console.warn('Scenario.execute(...): Scenes are not initialized.');
return;
}
if (_process === null) {
console.warn('Scenario.execute(...): Process is not initialized.');
return;
}
_process();
};
Scenario.prototype.addState = function(state) {
if (_state !== null) {
console.warn("Scenario.addState(...): Already states are added.");
return;
}
if (typeof state !== 'object')
throw new Error('Scenario.addState(...): States must be object.');
_state = state;
};
Scenario.prototype.getState = function() {
if (_state === null) {
console.warn("Scenario.getState(...): States are not initialized.");
return;
}
return _.clone(_state);
};
Scenario.prototype.setState = function(state) {
if (typeof state !== 'object')
throw new Error('Scenario.setState(...): States must be object.');
if (_state === null) {
console.warn('Scenario.setState(...): States are not initialized. Do "addState(...)" to initialize.');
return;
}
for (var prop in state)
_state[prop] = state[prop];
};
return Scenario;
})();
module.exports = _Scenario;