UNPKG

scenario-maker

Version:
195 lines (151 loc) 5.71 kB
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;