diff --git a/app/assets/javascripts/workers/worker_world.js b/app/assets/javascripts/workers/worker_world.js index a1a5d455a..97fea2e1d 100644 --- a/app/assets/javascripts/workers/worker_world.js +++ b/app/assets/javascripts/workers/worker_world.js @@ -14,8 +14,8 @@ if (!Function.prototype.bind) { throw new TypeError("Function.prototype.bind (Shim) - target is not callable"); } - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, fNOP = function () {}, fBound = function () { return fToBind.apply(this instanceof fNOP && oThis @@ -223,7 +223,7 @@ self.retrieveValueFromFrame = function retrieveValueFromFrame(args) { var flowStates = self.debugWorld.userCodeMap[currentThangID][currentSpellID].flow.states; //we have to go to the second last flowState as we run the world for one additional frame //to collect the flow - value = _.last(flowStates[flowStates.length - 2].statements).variables[prop]; + value = _.last(flowStates[flowStates.length - 1].statements).variables[prop]; } catch (e) { @@ -260,11 +260,12 @@ self.retrieveValueFromFrame = function retrieveValueFromFrame(args) { }; self.enableFlowOnThangSpell(args.currentThangID, args.currentSpellID, args.userCodeMap); self.setupDebugWorldToRunUntilFrame(args); - self.debugWorld.loadFramesUntilFrame( - args.frame, + self.debugWorld.loadFrames( retrieveProperty.bind({},args.currentThangID, args.currentSpellID, args.variableChain), self.onDebugWorldError, - self.onDebugWorldProgress + self.onDebugWorldProgress, + false, + args.frame ); }; @@ -297,8 +298,8 @@ self.setupDebugWorldToRunUntilFrame = function (args) { var stringifiedUserCodeMap = JSON.stringify(args.userCodeMap); var userCodeMapHasChanged = ! _.isEqual(self.currentUserCodeMapCopy, stringifiedUserCodeMap); self.currentUserCodeMapCopy = stringifiedUserCodeMap; - if (!self.debugWorld || userCodeMapHasChanged || args.frame != self.currentDebugWorldFrame) { - self.invalidateCache(); + if (args.frame != self.currentDebugWorldFrame) self.invalidateCache(); + if (!self.debugWorld || userCodeMapHasChanged || args.frame < self.currentDebugWorldFrame) { try { self.debugWorld = new World(args.worldName, args.userCodeMap); if (args.level) @@ -314,23 +315,18 @@ self.setupDebugWorldToRunUntilFrame = function (args) { return; } Math.random = self.debugWorld.rand.randf; // so user code is predictable - - self.debugWorld.totalFrames = args.frame; //hack to work around error checking - self.currentDebugWorldFrame = args.frame; } + self.debugWorld.totalFrames = args.frame; //hack to work around error checking + self.currentDebugWorldFrame = args.frame; }; -self.runDebugWorldUntilFrame = function (args) { - self.setupDebugWorldToRunUntilFrame(args); - self.debugWorld.loadFramesUntilFrame(args.frame, self.onDebugWorldLoaded, self.onDebugWorldError, self.onDebugWorldProgress); - -}; self.onDebugWorldLoaded = function onDebugWorldLoaded() { console.log("World loaded!"); }; self.onDebugWorldError = function onDebugWorldError(error) { + if(!error.isUserCodeProblem) { console.log("Debug Non-UserCodeError:", error.toString() + "\n" + error.stack || error.stackTrace); } @@ -357,7 +353,7 @@ self.runWorld = function runWorld(args) { self.firstWorld = args.firstWorld; self.postedErrors = false; self.logsLogged = 0; - + try { self.world = new World(args.worldName, args.userCodeMap); if(args.level) diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index 3ead94dd8..04b54a7e4 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -593,8 +593,6 @@ module.exports = Surface = class Surface extends CocoClass @paths.parent.removeChild @paths @paths = null - # Screenshot - screenshot: (scale=0.25, format='image/jpeg', quality=0.8, zoom=2) -> # Quality doesn't work with image/png, just image/jpeg and image/webp [w, h] = [@camera.canvasWidth, @camera.canvasHeight] @@ -604,6 +602,5 @@ module.exports = Surface = class Surface extends CocoClass #console.log "Screenshot with scale", scale, "format", format, "quality", quality, "was", Math.floor(imageData.length / 1024), "kB" screenshot = document.createElement("img") screenshot.src = imageData - #$('body').append(screenshot) @stage.uncache() imageData diff --git a/app/lib/world/world.coffee b/app/lib/world/world.coffee index 76bacd6bf..3da7ae6df 100644 --- a/app/lib/world/world.coffee +++ b/app/lib/world/world.coffee @@ -71,14 +71,18 @@ module.exports = class World (@runtimeErrors ?= []).push error (@unhandledRuntimeErrors ?= []).push error - loadFrames: (loadedCallback, errorCallback, loadProgressCallback, skipDeferredLoading) -> + loadFrames: (loadedCallback, errorCallback, loadProgressCallback, skipDeferredLoading, loadUntilFrame) -> return if @aborted unless @thangs.length console.log "Warning: loadFrames called on empty World (no thangs)." t1 = now() @t0 ?= t1 + if loadUntilFrame + frameToLoadUntil = loadUntilFrame + 1 + else + frameToLoadUntil = @totalFrames i = @frames.length - while i < @totalFrames + while i < frameToLoadUntil try @getFrame(i) ++i # increment this after we have succeeded in getting the frame, otherwise we'll have to do that frame again @@ -95,43 +99,19 @@ module.exports = class World if t2 - @t0 > 1000 console.log(' Loaded', i, 'of', @totalFrames, "(+" + (t2 - @t0).toFixed(0) + "ms)") @t0 = t2 - continueFn = => @loadFrames(loadedCallback, errorCallback, loadProgressCallback, skipDeferredLoading) + continueFn = => + if loadUntilFrame + @loadFrames(loadedCallback,errorCallback,loadProgressCallback, skipDeferredLoading, loadUntilFrame) + else + @loadFrames(loadedCallback, errorCallback, loadProgressCallback, skipDeferredLoading) if skipDeferredLoading continueFn() else setTimeout(continueFn, 0) return - @ended = true - system.finish @thangs for system in @systems - loadProgressCallback? 1 - loadedCallback() - - loadFramesUntilFrame: (frameToLoadUntil, loadedCallback, errorCallback, loadProgressCallback) -> - return if @aborted - unless @thangs.length - console.log "Warning: loadFrames called on empty World" - t1 = now() - @t0 ?= t1 - i = @frames.length - while i <= frameToLoadUntil #state is gathered at next frame - try - @getFrame(i) - ++i # increment this after we have succeeded in getting the frame, otherwise we'll have to do that frame again - catch error - # Not an Aether.errors.UserCodeError; maybe we can't recover - @addError error - for error in (@unhandledRuntimeErrors ? []) - return unless errorCallback error # errorCallback tells us whether the error is recoverable - @unhandledRuntimeErrors = [] - t2 = now() - if t2 - t1 > PROGRESS_UPDATE_INTERVAL - loadProgressCallback? i / @totalFrames - t1 = t2 - if t2 - @t0 > 1000 - console.log(' Loaded', i, 'of', frameToLoadUntil, "(+" + (t2 - @t0).toFixed(0) + "ms)") - @t0 = t2 - setTimeout((=> @loadFrames(loadedCallback, errorCallback, loadProgressCallback)), 0) - return + unless loadUntilFrame + @ended = true + system.finish @thangs for system in @systems loadProgressCallback? 1 loadedCallback() diff --git a/app/views/play/level/tome/spell_debug_view.coffee b/app/views/play/level/tome/spell_debug_view.coffee index 0767b9e88..43e6db210 100644 --- a/app/views/play/level/tome/spell_debug_view.coffee +++ b/app/views/play/level/tome/spell_debug_view.coffee @@ -15,6 +15,7 @@ module.exports = class DebugView extends View 'god:new-world-created': 'onNewWorld' 'god:debug-value-return': 'handleDebugValue' 'tome:spell-shown': 'changeCurrentThangAndSpell' + 'surface:frame-changed': 'onFrameChanged' events: {} @@ -24,7 +25,6 @@ module.exports = class DebugView extends View @thang = options.thang @spell = options.spell @variableStates = {} - @globals = {Math: Math, _: _, String: String, Number: Number, Array: Array, Object: Object} # ... add more as documented for className, serializedClass of serializedClasses @globals[className] = serializedClass @@ -93,13 +93,17 @@ module.exports = class DebugView extends View onNewWorld: (e) -> @thang = @options.thang = e.world.thangMap[@thang.id] if @thang - + + onFrameChanged: (data) -> + @currentFrame = data.frame + update: -> if @variableChain Backbone.Mediator.publish 'tome:spell-debug-value-request', thangID: @thang.id spellID: @spell.name variableChain: @variableChain + frame: @currentFrame @$el.find("code").text "Finding value..." @$el.show().css(@pos) else