1 2 /** 3 * loads the default grammar asynchronously using a WebWorker 4 * 5 * NOTE usage of the grammar is also async: 6 * calls on getASRSemantic(text, callback) are re-directed to the WebWorker 7 * 8 */ 9 define(['constants', 'commonUtils', 'semanticInterpreter', 'jquery'], function(constants, utils, semanticInterpreter, $){ 10 11 // 12 var _pendingCmds = {}; 13 var _cmdIdCounter = 1; 14 15 var _loadedGrammars = {}; 16 17 //web-worker instance: 18 var _asyncGrammarLoader = new Worker(constants.getWorkerPath()+'asyncGrammarWorker.js'); 19 20 //process messages from worker thread: 21 _asyncGrammarLoader.onmessage = function(msg){ 22 23 var data = msg.data; 24 var cmd = data.cmd; 25 if(cmd){ 26 27 if(cmd === 'stopwords'){ 28 29 semanticInterpreter.setStopwords(data.id, data.stopwords); 30 31 //check/trigger init-listener 32 if(typeof _loadedGrammars[data.id] === 'object'){ 33 _loadedGrammars[data.id].isStopwords = true; 34 _loadedGrammars[data.id].checkInit(); 35 } 36 37 } else if(cmd === 'setgrammar'){ 38 39 //replace the default impl. of the grammar execution: 40 // re-direct invocations to the worker thread and 41 // return the results via the callback 42 var execGrammar = function(text, callback){ 43 44 var cmdid = ''+ _cmdIdCounter++; 45 46 this.executeGrammar._pendingCmds[cmdid] = callback; 47 48 var langid = this.executeGrammar._langCode; 49 50 _asyncGrammarLoader.postMessage({cmd: 'parse', id: langid, cmdId: cmdid, text: text}); 51 }; 52 53 execGrammar._pendingCmds = _pendingCmds; 54 execGrammar._langCode = data.id; 55 56 var options = data.options; 57 if(options.execMode != 'async'){ 58 options.execMode = 'async'; 59 } 60 semanticInterpreter.addGrammar(data.id,execGrammar,options); 61 62 //check/trigger init-listener 63 if(typeof _loadedGrammars[data.id] === 'object'){ 64 _loadedGrammars[data.id].isGrammar = true; 65 _loadedGrammars[data.id].checkInit(); 66 } 67 68 } else if(cmd === 'parseresult'){ 69 70 var cmdid = data.cmdId; 71 72 if(!_pendingCmds[cmdid]){ 73 console.error('no callback registered for cmd-ID '+cmdid+', ignoring result '+JSON.stringify(cmd.result)); 74 return;////////////////// EARLY EXIT ///////////////////////////////// 75 } 76 77 _pendingCmds[cmdid].call(semanticInterpreter, data.result); 78 _pendingCmds[cmdid] = void(0); 79 80 } else if(cmd === 'error'){ 81 82 console.error('encountered error: '+JSON.stringify(data)); 83 84 } else { 85 86 console.error('unknown response from loader: '+JSON.stringify(msg.data)); 87 } 88 89 } else { 90 91 console.error('unknown response from loade: '+JSON.stringify(msg.data)); 92 } 93 94 }; 95 96 97 return { 98 99 /** 100 * Initialize a grammar to be loaded & executed asynchronously 101 * 102 * After 103 * 104 * @requires WebWorker 105 */ 106 init: function(langCode, listener, phrase){ 107 108 //use default language, if none is specified 109 if(!langCode){ 110 langCode = semanticInterpreter.getCurrentGrammar(); 111 } 112 113 if(!langCode){ 114 console.error('Inavlid grammar ID: "'+langCode+'"'); 115 return false;//////////////////// EARLY EXIT//////////////////////// 116 } 117 118 //if grammar is already loaded & available: 119 if(_loadedGrammars[langCode] === true){ 120 semanticInterpreter.getASRSemantic(phrase, langCode, listener); 121 return true;//////////////////// EARLY EXIT //////////////////////// 122 } 123 124 utils.init().then(function onSuccess(){ 125 126 var compiledGrammarPath = utils.getCompiledGrammarPath(constants.getGeneratedGrammarsPath(), langCode); 127 if(!compiledGrammarPath){ 128 console.error('No compiled grammar available for ID: "'+langCode+'"'); 129 return;//////////////////// EARLY EXIT//////////////////////// 130 } 131 132 var grammarInit = { 133 id: langCode, 134 initDef: $.Deferred(), 135 isGrammar: false, 136 isStopwords: false, 137 checkInit: function(){ 138 if(this.isStopwords && this.isGrammar){ 139 _loadedGrammars[this.id] = true; 140 this.initDef.resolve(); 141 this.initDef = null; 142 } 143 } 144 }; 145 146 //register invocation of init-phrase as soon as (async-loaded) grammar becomes available 147 grammarInit.initDef.always(function(){ 148 149 if(typeof phrase !== 'undefined'){ 150 semanticInterpreter.getASRSemantic(phrase, langCode, listener); 151 } else {//TODO use grammar's example_phrase for init instead? 152 listener({}); 153 } 154 155 }); 156 _loadedGrammars[langCode] = grammarInit; 157 158 _asyncGrammarLoader.postMessage({cmd: 'load', id: langCode, url: compiledGrammarPath}); 159 }, 160 function onError(){ 161 162 //FIXME impl. real error handling 163 console.error('cannot determine URL for compiled grammar with ID "'+langCode+'": commonUtils is not initialized.'); 164 }); 165 166 return true; 167 } 168 }; 169 170 }); 171