From 6a03163fcb0b7425e30638daa7607235a3239a4c Mon Sep 17 00:00:00 2001 From: Rob Date: Wed, 22 Jun 2016 15:07:43 -0700 Subject: [PATCH] - Use modern esper engine if we detect browser support it. - Change streaming batch size depending on how far into simulation we are. - Hoist try catch out of onWorldLoad so Chrome and JIT it. --- .../javascripts/workers/aether_worker.js | 13 +++++++- .../javascripts/workers/worker_world.js | 31 +++++++++++++++---- app/lib/world/world.coffee | 16 +++++++++- config.coffee | 1 + 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/workers/aether_worker.js b/app/assets/javascripts/workers/aether_worker.js index 810537599..5e45c7eda 100644 --- a/app/assets/javascripts/workers/aether_worker.js +++ b/app/assets/javascripts/workers/aether_worker.js @@ -1,7 +1,18 @@ var window = self; var Global = self; -importScripts("/javascripts/lodash.js", "/javascripts/aether.js", "/javascripts/esper.js"); +importScripts("/javascripts/lodash.js", "/javascripts/aether.js"); + +try { + //Detect very modern javascript support. + (0,eval("'use strict'; let test = (class Test { *gen() { yield yield * () => WeakMap; } });")); + console.log("Modern javascript detected, aw yeah!"); + self.importScripts('/javascripts/esper.modern.js'); +} catch (e) { + console.log("Legacy javascript detected, falling back...", e.message); + self.importScripts('/javascripts/esper.js'); +} + //console.log("Aether Tome worker has finished importing scripts."); var aethers = {}; var languagesImported = {}; diff --git a/app/assets/javascripts/workers/worker_world.js b/app/assets/javascripts/workers/worker_world.js index 26217cb16..f76a07483 100644 --- a/app/assets/javascripts/workers/worker_world.js +++ b/app/assets/javascripts/workers/worker_world.js @@ -63,7 +63,18 @@ var console = { console.error = console.warn = console.info = console.debug = console.log; self.console = console; -self.importScripts('/javascripts/lodash.js', '/javascripts/world.js', '/javascripts/aether.js', '/javascripts/esper.js'); +self.importScripts('/javascripts/lodash.js', '/javascripts/world.js', '/javascripts/aether.js'); +try { + //Detect very modern javascript support. + (0,eval("'use strict'; let test = (class Test { *gen() { yield yield * () => WeakMap; } });")); + console.log("Modern javascript detected, aw yeah!"); + self.importScripts('/javascripts/esper.modern.js'); +} catch (e) { + console.log("Legacy javascript detected, falling back...", e.message); + self.importScripts('/javascripts/esper.js'); +} + + var myImportScripts = importScripts; var languagesImported = {}; @@ -402,6 +413,17 @@ self.serializeFramesSoFar = function serializeFramesSoFar() { self.world.framesSerializedSoFar = self.world.frames.length; }; +function trySerialize() { + try { + var serialized = self.world.serialize(); + } + catch(error) { + console.log("World serialization error:", error.toString() + "\n" + error.stack || error.stackTrace); + return false; + } + return serialized; +} + self.onWorldLoaded = function onWorldLoaded() { if(self.world.framesSerializedSoFar == self.world.frames.length) return; if(self.world.ended) @@ -419,12 +441,9 @@ self.onWorldLoaded = function onWorldLoaded() { return console.log('Headless simulation completed in ' + diff + 'ms.'); var worldEnded = self.world.ended; + var serialized; var transferableSupported = self.transferableSupported(); - try { - var serialized = self.world.serialize(); - } - catch(error) { - console.log("World serialization error:", error.toString() + "\n" + error.stack || error.stackTrace); + if ( !( serialized = trySerialize()) ) { self.destroyWorld(); return; } diff --git a/app/lib/world/world.coffee b/app/lib/world/world.coffee index af7e2b65b..266f4bc1e 100644 --- a/app/lib/world/world.coffee +++ b/app/lib/world/world.coffee @@ -162,11 +162,25 @@ module.exports = class World shouldContinueLoading: (t1, loadProgressCallback, skipDeferredLoading, continueLaterFn) -> t2 = now() + chunkSize = @frames.length - @framesSerializedSoFar + simedTime = @frames.length / @frameRate + + chunkTime = switch + when simedTime > 15 then 7 + when simedTime > 10 then 5 + when simedTime > 5 then 3 + when simedTime > 2 then 1 + else 0.5 + + bailoutTime = Math.max(2000*chunkTime, 10000) + + dt = t2 - t1 + if @realTime shouldUpdateProgress = @shouldUpdateRealTimePlayback t2 shouldDelayRealTimeSimulation = not shouldUpdateProgress and @shouldDelayRealTimeSimulation t2 else - shouldUpdateProgress = t2 - t1 > PROGRESS_UPDATE_INTERVAL# and (@frames.length - @framesSerializedSoFar >= @frameRate or t2 - t1 > 1000) + shouldUpdateProgress = (dt > PROGRESS_UPDATE_INTERVAL and (chunkSize / @frameRate >= chunkTime) or dt > bailoutTime) shouldDelayRealTimeSimulation = false return true unless shouldUpdateProgress or shouldDelayRealTimeSimulation # Stop loading frames for now; continue in a moment. diff --git a/config.coffee b/config.coffee index 6690d8e2e..75e614786 100644 --- a/config.coffee +++ b/config.coffee @@ -207,6 +207,7 @@ exports.config = copyTo: 'lib/ace': ['node_modules/ace-builds/src-min-noconflict/*'] 'fonts': ['bower_components/openSansCondensed/*', 'bower_components/openSans/*'] + 'javascripts': ['bower_components/esper.js/esper.modern.js'] autoReload: delay: 1000