1 
  2 
  3 define(['constants', 'jsccGen', 'asyncGen', 'jquery'],
  4 /**
  5  * Asynchronous generator for executable language-grammars (i.e. converted JSON grammars).
  6  * 
  7  * <p>
  8  * This generator uses JS/CC for compiling the JSON grammar.
  9  * 
 10  * <p>
 11  * Usage of this compile is the same as for synchronously working JsccGenerator.
 12  *  
 13  * @see JsccGenerator
 14  * 
 15  * @class
 16  * @constant
 17  * @public
 18  * @name JsccAsyncGenerator
 19  * @memberOf mmir.env.grammar
 20  * 
 21  * @requires JsccGenerator
 22  * @requires jQuery.extend
 23  * @requires jQuery.deferred
 24  */		
 25 function(constants, jsccGen, asyncGen, $){
 26 
 27 /**
 28  * Counter for generating IDs for compile-jobs that
 29  * are sent to the WebWorker
 30  * 
 31  * @private
 32  * @memberOf JsccAsyncGenerator#
 33  */
 34 var _taskId = 1;
 35 
 36 /**
 37  * WebWorker instance for compiling parser asynchronously
 38  * 
 39  * @private
 40  * @memberOf JsccAsyncGenerator#
 41  */
 42 var asyncCompiler = asyncGen.createWorker(jsccGen.engineId);
 43 
 44 /**
 45  * printError function reference for compile-errors
 46  * 
 47  * @private
 48  * @memberOf JsccAsyncGenerator#
 49  */
 50 var printError = jsccGen.printError;
 51 
 52 /**
 53  * HELPER for applying the compile-results (i.e. parser-code) to the parser-template
 54  * 
 55  * @see JsccGenerator#_getGenerated
 56  * @see JsccGenerator#_applyGenerated
 57  * 
 58  * @private
 59  * @memberOf JsccAsyncGenerator#
 60  */
 61 var _applyGenerated = jsccGen._applyGenerated;
 62 
 63 //////////////////// init async compiler/thread /////////////////////////
 64 
 65 asyncCompiler._onerror = printError;
 66 
 67 //setup async init-signaling:
 68 var initDef = $.Deferred();
 69 var initMsg = asyncCompiler.prepareOnInit(jsccGen, initDef, require);
 70 asyncCompiler.postMessage(initMsg);
 71 
 72 
 73 /**
 74  * Exported (public) functions for the PEG.js grammar-engine.
 75  * @public
 76  * @type GrammarGenerator
 77  * @memberOf JsccAsyncGenerator#
 78  */
 79 var jsccAsyncGen = {
 80 	/** @scope JsccAsyncGenerator.prototype */
 81 		
 82 	/** 
 83 	 * @see JsccAsyncGenerator#init
 84 	 * @memberOf JsccAsyncGenerator.prototype
 85 	 */
 86 	init: function(callback){
 87 		//overwrite with own async "init signal"
 88 		if(callback){
 89 			initDef.always(callback);
 90 		}
 91 		return initDef;
 92 	},
 93 	/** @returns {Boolean} if this engine compilation works asynchronously.
 94 	 * 						The current implementation works asynchronously (returns TRUE)
 95 	 * 
 96 	 * @memberOf JsccAsyncGenerator.prototype
 97 	 */
 98 	isAsyncCompilation: function(){ return true; },
 99 	/**
100 	 * @see JsccAsyncGenerator#_compileParser
101 	 * @protected 
102 	 */
103 	_compileParser: function(grammarDefinition, options, onAfterCompileParserResult){
104 		
105         //start compilation in web-worker:
106         asyncCompiler.postMessage({
107     		cmd: 'parse',
108     		id: onAfterCompileParserResult,
109     		config: options,
110     		text: grammarDefinition
111     	});
112         
113 	},
114 	/**
115 	 * @see JsccAsyncGenerator#_preparePrintError
116 	 * @protected 
117 	 */
118 	_preparePrintError: function(){},//<- overwrite with NOOP
119 	/**
120 	 * @see JsccAsyncGenerator#_afterCompileParser
121 	 * @protected 
122 	 */
123 	_afterCompileParser: function(compileParserModuleFunc){
124 		
125 		//callback-ID:
126         var taskId = '' + _taskId++;
127         
128         //register callback for messages from web-worker:
129         asyncCompiler.addCallback(taskId, function(evtData){
130         	
131         	if(evtData.error){
132         		
133         		//handle error message:
134         		
135         		if(printError){
136             		printError(evtData.error);
137             	}
138             	else {
139             		console.error(evtData.error);
140             	}
141         		
142         		//////////////////// EARLY EXIT /////////////////
143         		//NOTE this is not the final message from the compiler-thread...
144         		return;
145         	}
146 
147         	var hasError = evtData.isError;
148         	var grammarParserData = evtData.def;
149         	
150         	var grammarParser = jsccGen._applyGenerated(grammarParserData, jsccGen.template);
151         
152         	compileParserModuleFunc(grammarParser, hasError);
153         });
154 		
155         return taskId;
156 	}
157 };
158 
159 //extend/overload sync-compiler with async-compiler:
160 return $.extend({}, jsccGen, jsccAsyncGen);
161 
162 });
163