From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- js/preloader/Preloader.js | 287 ++++++++++++++++++++++++++++++++++++++++ js/preloader/PreloaderWorker.js | 95 +++++++++++++ 2 files changed, 382 insertions(+) create mode 100755 js/preloader/Preloader.js create mode 100644 js/preloader/PreloaderWorker.js (limited to 'js/preloader') diff --git a/js/preloader/Preloader.js b/js/preloader/Preloader.js new file mode 100755 index 00000000..f137f4b6 --- /dev/null +++ b/js/preloader/Preloader.js @@ -0,0 +1,287 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + +var Montage = require("montage/core/core").Montage, + Component = require("montage/ui/component").Component, + defaultEventManager = require("montage/core/event/event-manager").defaultEventManager; + +exports.Preloader = Montage.create(Component, { + + + ninjaJsRequire: { + value: + [ + {"type":"js", "url":"js/helper-classes/3D/GLMatrix/gl-matrix.js"}, + {"type":"js", "url":"js/codemirror/lib/codemirror.js"}, + + //{"type":"js", "url":"js/helper-classes/RDGE/rdge-compiled.js"}, + + // source RDGE + /* */ + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/math/vec2.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/math/vec3.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/math/vec4.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/math/mat4.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/math/quat.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/util/statTracker.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/util/fpsTracker.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/objectManager.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/precompiled.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/renderer.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/renderUtils.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/jshader.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/jpass.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/RenderProcs.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/RenderInitProcs.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/MeshManager.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/TextureManager.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/ShaderManager.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/fx/blur.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/fx/ssao.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/ScreenQuad.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/box.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/camera.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/shadowLight.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/utilities.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/input.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/engine.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/scenegraphNodes.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/scenegraph.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/lightmanager.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/rendercontext.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/animation.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/particle.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/run_state.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/init_state.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/runtime.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/src/core/script/util/dbgpanel.js"}, + /* */ + + {"type":"js", "url":"js/helper-classes/RDGE/GLLine.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLLight.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/FlatMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/BrickMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/UberMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/PlasmaMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/RadialGradientMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/RadialBlurMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/PulseMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/TunnelMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/TwistMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/KeleidoscopeMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/JuliaMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/MandelMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/IridescentScalesMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/PlasmaMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/LinearGradientMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/Materials/BumpMetalMaterial.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLWorld.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLGeomObj.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLCircle.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLRectangle.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLLine.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/GLPath.js"}, + {"type":"js", "url": "js/helper-classes/RDGE/GLAnchorPoint.js" }, + {"type":"js", "url": "js/helper-classes/RDGE/GLSubpath.js" }, + {"type":"js", "url": "js/helper-classes/RDGE/GLBrushStroke.js" }, + {"type":"js", "url":"js/helper-classes/RDGE/precompiled.js"}, + {"type":"js", "url":"js/helper-classes/RDGE/MaterialsLibrary.js"}, + {"type":"js", "url":"js/helper-classes/3D/glUtils.js"}, + {"type":"js", "url":"js/codemirror/mode/htmlmixed/htmlmixed.js"}, + {"type":"js", "url":"js/codemirror/mode/xml/xml.js"}, + {"type":"js", "url":"js/codemirror/mode/javascript/javascript.js"}, + {"type":"js", "url":"js/codemirror/mode/css/css.js"} + ] + }, + + ninjaCssRequire: { + value: + [ + {"type":"css", "url":"js/codemirror/lib/codemirror.css"}, + {"type":"css", "url":"js/codemirror/theme/default.css"} + ] + }, + + filesTotal: { + value: 0 + }, + + filesLoaded: { + value: 0 + }, + + executionHash: { + value: {} + }, + + lastExecutedJsIndex: { + value: -1 + }, + + lastExecutedCssIndex: { + value: -1 + }, + + executionInProgress: { + value: false + }, + + worker: { + value: null + }, + + deserializedFromTemplate: { + value: function() { + console.log("Start Preloading"); + + this.filesTotal = this.ninjaJsRequire.length + this.ninjaCssRequire.length; + + this.loadFilesWithWorker(); + //this.loadFilesWithWorker(this.jsFiles, this.cssFiles.reverse(), this.publishLoadingStatus); + } + }, + + loadFilesWithWorker: { + value: function() { + this.worker = new Worker('js/preloader/PreloaderWorker.js'); + this.worker.addEventListener("message", this, false); + this.worker.addEventListener("error", this, false); + var filesExecuted = 0; + + var baseUrl = location.href; + if(baseUrl.charAt(baseUrl.length-1) !== "/"){ + baseUrl = baseUrl.substring(0, (baseUrl.lastIndexOf("/")+1)); + } + +// console.log("baseUrl="+baseUrl); + //prepare the json command + var startJson = {"command":"start", "jsFiles":this.ninjaJsRequire, "cssFiles":this.ninjaCssRequire.reverse(), "baseUrl":baseUrl};//will load ninjaInitJsDependencies and ninjaInitCssDependencies + //start the worker thread + this.worker.postMessage(startJson); + } + }, + + handleEvent: { + value: function(e) { + e.type === "message"? this.workerOnMessage(e) : this.workerOnError(e); + } + }, + + workerOnMessage: { + value: function(e) { + var msgJson; + msgJson = e.data; + + switch(msgJson.command){ + case "newFile": + //console.log("**worker downloaded file: "+msgJson.url); + this.executionHash[""+msgJson.fileType+msgJson.fileIndex]={"url":msgJson.url, "fileContent":msgJson.fileContent}; + this.triggerExecution(msgJson.fileIndex, msgJson.fileType); + break; + case "log": + console.log(""+ msgJson.logMsg); + break; + case "stop": + this.worker.terminate(); + break; + default: + break; + } + + } + }, + + workerOnError: { + value: function(e) { + console.log("error from worker: "+ e.message); + this.worker.terminate(); + } + }, + + triggerExecution: { + value: function(originIndex, fileType) { + var sourceURLComment = "", + url = "", + fileContent = ""; + + if(this.executionInProgress === false) { + this.executionInProgress = true; + while((this.executionHash != null) && (typeof this.executionHash[""+fileType+originIndex] != 'undefined')){ + if(fileType === "js"){ + if((originIndex -1)!== this.lastExecutedJsIndex) { //don't execute if previous file is not yet executed + break; + } + url = this.executionHash[""+fileType+originIndex].url; + fileContent = this.executionHash[""+fileType+originIndex].fileContent; + + sourceURLComment = "\n//@ sourceURL="+this.extractFileName(url); + window.eval(""+fileContent+sourceURLComment); + + this.lastExecutedJsIndex++; + + this.pusblishLoadingStatus(url, fileType, originIndex); + //console.log("Executed: "+this.executionHash[""+fileType+originIndex].url+ " :: index="+originIndex); + }else if(fileType === "css"){ + if((originIndex -1)!== this.lastExecutedCssIndex){//don't execute if previous file is not yet executed + break; + } + url = this.executionHash[""+fileType+originIndex].url; + this.insertCssNode(url); + this.lastExecutedCssIndex++; + + this.pusblishLoadingStatus(url, fileType, originIndex); + //console.log("Executed: "+this.executionHash[""+fileType+originIndex].url+ " :: index="+originIndex); + } + originIndex++; + } + this.executionInProgress = false; + } + } + }, + + extractFileName: { + value: function(url) { + var fileName = "aFile"; + var arr; + + if(url && url !== null) { + arr = url.split("/"); + fileName = arr[arr.length -1]; + } + + return fileName; + } + }, + + insertCssNode: { + value: function(url) { + var headID = document.getElementsByTagName("head")[0]; + var cssNode = document.createElement('link'); + cssNode.type = 'text/css'; + cssNode.rel = 'stylesheet'; + cssNode.href = url; + cssNode.media = 'screen'; + headID.insertBefore(cssNode, headID.firstChild); //append at the beginning of + } + }, + + pusblishLoadingStatus: { + value: function(url, type, indexLoaded) { + this.filesLoaded++; + //this.percentageLoaded = Math.floor((this.filesloaded/this.filestotal)*100); + + //console.log("Preloader:loaded "+ type + " file: " + url + " :: done " + this.filesLoaded+"/"+this.filesTotal); + + if (this.filesLoaded === this.filesTotal) { + var newEvent = document.createEvent( "CustomEvent" ); + newEvent.initCustomEvent( "preloadFinish", false, true ); + defaultEventManager.dispatchEvent( newEvent ); + } + } + } + +}); \ No newline at end of file diff --git a/js/preloader/PreloaderWorker.js b/js/preloader/PreloaderWorker.js new file mode 100644 index 00000000..1b5b58ed --- /dev/null +++ b/js/preloader/PreloaderWorker.js @@ -0,0 +1,95 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + +//PreloaderWorker makes the file downloading asynchronous. Preloader will continue to do script execution synchronously. PreloaderWorker allows script execution to start soon after the first download. +//Note: File importing is probably not CPU intensive enough to run on a separate thread. But worth a test. +// Multi-threading will be more useful for math-intensive webGL or canvas calculations. + +self.onmessage = function(e){ + var msgJson; + if(e && e.data){ + msgJson = e.data; + } + //workerLog("worker received this: "+JSON.stringify(msgJson)); + if(msgJson){ + switch(msgJson.command){ + case "start": + //workerLog('WORKER STARTED'); + + downloadFiles(msgJson.jsFiles, msgJson.cssFiles, msgJson.baseUrl); + break; + case 'stop': + workerLog('WORKER STOPPED'); + self.close(); // Terminates the worker. + break; + default: + workerLog('Unknown command'); + } + } +}; + + self.onerror = function(e){ + workerLog("worker error: "+ e.message+" @file "+e.filename+" @line# "+e.lineno); + self.close(); // Terminates the worker. + } + + var fileCounter = 0; + var fileArrayLength = 0; + + var xhrDownload = function(fileUrl, fileType, i){ + var that = self, + req = new XMLHttpRequest(); + + if(fileType === "js"){ + //workerLog("Worker will download: fileUrl="+fileUrl+" :: fileType="+fileType+" :: fileIndex="+i); + req.overrideMimeType && req.overrideMimeType("application/javascript"); + }else if(fileType === "css"){ + //workerLog("Worker will download: fileUrl="+fileUrl+" :: fileType="+fileType+" :: fileIndex="+i); + req.overrideMimeType && req.overrideMimeType("text/css"); + } + req.onreadystatechange = function() { + if (req.readyState === 4) { + if ((req.status === 200 || (req.status === 0 && req.responseText))) { + fileCounter++; + //workerLog("Status:"+req.status+" : fileUrl="+fileUrl+" :: fileIndex="+i); + that.postMessage({command:"newFile", url:fileUrl, fileType:fileType, fileIndex:i, fileContent:req.responseText}); + + //trying to clear some memory after last file is processed + req.responseText = null; + req = null; + + if(fileCounter === fileArrayLength){ + //workerLog("done downloading...shutting down this worker"); + that.close(); + } + + } else { + workerLog("Status:"+req.status+" :: Unable to load "+fileUrl); + } + } + } + req.open("GET", fileUrl, true); + req.send(); +} + +var downloadFiles = function(jsFiles, cssFiles, baseUrl){ + var fileType, fileUrl; + fileArrayLength = jsFiles.concat(cssFiles).length; + for(var i=0;i