1 2 /** 3 * @requires jQuery.Deferred 4 */ 5 6 //TODO doc 7 8 define(['scion', 'scionUtil', 'jquery'], function( scion, scionUtil, $ ) { 9 10 /** 11 * An array containing all states active. 12 * 13 * @type Array 14 * @private 15 * @memberOf mmir.env.statemachine# 16 */ 17 var statesActive = new Array(); 18 19 /** 20 * Factory function for creating a new (extended) SCION interpreter instance. 21 * 22 * @param {SCION} scion 23 * the SCION module 24 * @param {SCIONUtil} scionUtil 25 * the util/helper for exending the SCION engine 26 * @param {Objcect} instanceContext 27 * 28 * @private 29 * @memberOf mmir.env.statemachine# 30 */ 31 var newInstance = function( scion, scionUtil, instanceContext ) { 32 33 /** 34 * @type SCIONInterpreter 35 * @memberOf mmir.env.statemachine.create# 36 */ 37 var _interpreter = null; 38 39 /** 40 * The load function for <code>instanceContext</code> 41 * 42 * @function 43 * @returns {Deferred} a promise that is resolved when the SCION model is loaded 44 * @memberOf mmir.env.statemachine.create# 45 */ 46 var load = function(){ 47 /** 48 * @type String 49 * @memberOf mmir.env.statemachine.engine# 50 */ 51 var _url = this.arguments || this.doc; 52 /** 53 * @type Deferred 54 * @memberOf mmir.env.statemachine.engine# 55 */ 56 var _defer = $.Deferred(); 57 58 if (typeof _url === 'undefined') { 59 instanceContext._log.error('URL is missing!'); 60 return; 61 } 62 /** 63 * @type SCION 64 * @memberOf mmir.env.statemachine.engine# 65 */ 66 var self = this; 67 68 /** 69 * Loads the SCXML file and creates the SCION model. 70 * 71 * Resolves the {@link #_defer} promise (or fails it, if an error occurred). 72 * 73 * @param {XMLHTTPRequest} err 74 * if <code>falsey</code>, loading was successful. 75 * Otherwise contains the failed request for loading the SCXML file. 76 * @param {SCIONModel} model 77 * if err is <code>falsey</code>, holds the SCIONModel. 78 * Otherwise empty. 79 * 80 * @function 81 * @memberOf mmir.env.statemachine.engine# 82 */ 83 scion.urlToModel(_url, function urlToModel(err, model) { 84 85 if (err) { 86 87 var url = ''; 88 var printError = function(){ 89 console.error('error for SCXML model at ',_url, ': ', 90 (url? 'could not load "' + url + '" ' : ''), 91 (err.statusText? ': ' + err.statusText : ''), 92 err, 93 model 94 ); 95 }; 96 if(err.always) err.always(function(){url = this.url; printError();}); 97 else printError(); 98 99 // alert('SCXML is not valid!'); 100 _defer.fail(err); 101 return; 102 } 103 104 // instantiate the interpreter 105 _interpreter = new scion.SCXML(model); 106 107 // listener for transitions / state-changes: 108 var listener = { 109 /** 110 * Listener for state changes (ENTRY) in the SCXML model. 111 * 112 * @param {String} stateName 113 * the name of the state that was entered 114 * 115 * @function 116 * @memberOf mmir.env.statemachine.engine.listener# 117 * 118 * @requires instanceContext._log {@link Logger} (i.e. the Logger of the DialogEngine/InputEngine) 119 */ 120 onEntry : function(stateName) { 121 statesActive.push(stateName); 122 if (instanceContext._log.isDebug()) instanceContext._log.debug('SCXML State Entry: "' + stateName + '"');// debug 123 }, 124 /** 125 * Listener for state changes (EXIT) in the SCXML model. 126 * 127 * @param {String} stateName 128 * the name of the state that was exited 129 * 130 * @function 131 * @memberOf mmir.env.statemachine.engine.listener# 132 * 133 * @requires instanceContext._log {@link Logger} (i.e. the Logger of the DialogEngine/InputEngine) 134 */ 135 onExit : function(stateName) { 136 statesActive.pop(); 137 138 if (instanceContext._log.isDebug()) instanceContext._log.debug('SCXML State Exit: "' + stateName + '"');// debug 139 }, 140 /** 141 * Listener for state changes (TRANSITIONS) in the SCXML model. 142 * 143 * @param {String} sourceState 144 * the name of the origin state for the state transition 145 * @param {Array<String>} targetStatesArray 146 * the names of the target states for the state transition 147 * 148 * @function 149 * @memberOf mmir.env.statemachine.engine.listener# 150 * 151 * @requires instanceContext._log {@link Logger} (i.e. the Logger of the DialogEngine/InputEngine) 152 */ 153 onTransition : function(sourceState, targetStatesArray) { 154 155 if (instanceContext._log.isDebug()) instanceContext._log.debug('SCXML State Transition: "' + sourceState + '"->"' + targetStatesArray + '"');// debug 156 157 if (targetStatesArray && targetStatesArray.length > 1) { 158 instanceContext._log.warn('SCXML State Transition: multiple target states!'); 159 } 160 } 161 }; 162 163 _interpreter.registerListener(listener); 164 165 if (self.onload) { 166 var _scion = scionUtil( _interpreter ); 167 if(!self.evalScript) self.scion.ignoreScript(); 168 self.onload( _scion, _defer ); 169 } else { 170 deferred.resolve(instanceContext); 171 } 172 173 });//END: scion.urlToModel(... 174 175 176 return _defer.promise(); 177 178 };//END: load = function(){... 179 180 /** 181 * @deprecated instead use the object directly 182 */ 183 instanceContext.getInstance= function () { 184 return this; 185 }; 186 instanceContext.load = load; 187 instanceContext.onload = null; 188 instanceContext.doc = null; 189 instanceContext.raise = null; 190 191 return instanceContext; 192 193 };//END: newInstance(){... 194 195 196 //export: 197 198 /** 199 * Creates a new SCION engine. 200 * 201 * @param {Object} configuration 202 * The configuration object for the SCION engine: 203 * all properties and functions from this object will be attached 204 * to the returned SCION engine (i.e. the <code>context</code> object). 205 * @param {Object} context 206 * The context object: the SCION engine will be attached to this object. 207 * The context object must have a property <code>_log</code> with the 208 * following attributes (may be empty non-function): 209 * <code>_log.isDebug() : Boolean</code> (this SHOULD NOT print / show any message) 210 * <code>_log.debug(String) : void</code> (this SHOULD NOT print / show any message) 211 * <code>_log.warn(String) : void</code> (this MAY print / show a warning message) 212 * <code>_log.error(String) : void</code> (this SHOULD print / show an error message) 213 * or use a Logger instance (see /tools/logger.js) that is setup for the module 214 * that calls this function (see e.g. /manager/dialog/dialogManager::init). 215 * @returns {Object} the created SCION engine object 216 * 217 * @public 218 * @memberOf mmir.env.statemachine# 219 */ 220 function createEngine(configuration , context){ 221 222 var _instance = newInstance( scion, scionUtil , context); 223 224 for (var key in configuration) { 225 _instance[key] = configuration[key]; 226 } 227 228 return _instance; 229 230 }; 231 return createEngine; 232 233 }); 234