From 0064ec20c393653a6a7c3d89d30f01ce4f615928 Mon Sep 17 00:00:00 2001 From: Vishesh Yadav Date: Tue, 5 May 2015 15:54:16 -0400 Subject: [PATCH] Implement last-picture in world Last picture is used to render world once it has ended. This patch takes last-picture function and creates a ToDraw handler and calls its listener manually when stop-when returns true. --- whalesong/world/js-impl.js | 10 ++++++++-- whalesong/world/kernel.js | 15 +++++++++++---- whalesong/world/racket-impl.rkt | 7 +++++-- whalesong/world/raw-jsworld.js | 17 +++++++++++------ 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/whalesong/world/js-impl.js b/whalesong/world/js-impl.js index b32c3ce..ce0deba 100644 --- a/whalesong/world/js-impl.js +++ b/whalesong/world/js-impl.js @@ -87,10 +87,16 @@ EXPORTS['to-draw'] = EXPORTS['stop-when'] = makePrimitiveProcedure( 'stop-when', - 1, + plt.baselib.lists.makeList(1, 2), function(MACHINE) { var f = checkProcedure1(MACHINE, "on-tick", 0); - return new StopWhen(f); + if (MACHINE.a === 2) { + var lp = checkProcedure1(MACHINE, "to-draw", 1); + } else { + var lp = null; + } + + return new StopWhen(f, lp); }); diff --git a/whalesong/world/kernel.js b/whalesong/world/kernel.js index 9cf716f..8f27a40 100644 --- a/whalesong/world/kernel.js +++ b/whalesong/world/kernel.js @@ -282,8 +282,6 @@ ToDraw.prototype = plt.baselib.heir(OutputConfig.prototype); ToDraw.prototype.toRawHandler = function(MACHINE, toplevelNode) { var that = this; - var reusableCanvas; - var reusableCanvasNode; var adaptedWorldFunction = adaptWorldFunction(this.handler); var worldFunction = function(world, success) { @@ -291,6 +289,12 @@ ToDraw.prototype.toRawHandler = function(MACHINE, toplevelNode) { adaptedWorldFunction( world, function(v) { + var reusableCanvas = toplevelNode.getElementsByTagName('canvas')[0]; + var reusableCanvasNode; + if (reusableCanvas) { + reusableCanvasNode = rawJsworld.node_to_tree(reusableCanvas); + } + // fixme: once jsworld supports fail continuations, use them // to check the status of the scene object and make sure it's an // image. @@ -325,6 +329,7 @@ ToDraw.prototype.toRawHandler = function(MACHINE, toplevelNode) { }; var cssFunction = function(w, k) { + var reusableCanvas = toplevelNode.getElementsByTagName('canvas')[0]; if (reusableCanvas) { k([[reusableCanvas, ["padding", "0px"], @@ -369,9 +374,10 @@ DefaultDrawingOutput.prototype.toRawHandler = function(MACHINE, toplevelNode) { -var StopWhen = function(handler) { +var StopWhen = function(handler, last_picture) { WorldConfigOption.call(this, 'stop-when'); this.handler = handler; + this.last_picture = new ToDraw(last_picture); }; StopWhen.prototype = plt.baselib.heir(WorldConfigOption.prototype); @@ -379,5 +385,6 @@ StopWhen.prototype = plt.baselib.heir(WorldConfigOption.prototype); StopWhen.prototype.toRawHandler = function(MACHINE, toplevelNode) { var that = this; var worldFunction = adaptWorldFunction(that.handler); - return rawJsworld.stop_when(worldFunction); + var lastPictureHandler = that.last_picture.toRawHandler(MACHINE, toplevelNode); + return rawJsworld.stop_when(worldFunction, undefined, lastPictureHandler); }; diff --git a/whalesong/world/racket-impl.rkt b/whalesong/world/racket-impl.rkt index 25ac53e..596b52f 100644 --- a/whalesong/world/racket-impl.rkt +++ b/whalesong/world/racket-impl.rkt @@ -40,5 +40,8 @@ (define (key=? key-1 key-2) (error 'key=? "must be run in JavaScript context")) -(define (stop-when handler) - (error 'stop-when "must be run in JavaScript context")) +(define stop-when + (case-lambda [(handler) + (error 'stop-when "must be run in JavaScript context")] + [(handler last-picture) + (error 'stop-when "must be run in JavaScript context")])) diff --git a/whalesong/world/raw-jsworld.js b/whalesong/world/raw-jsworld.js index 26f801e..4e91d25 100644 --- a/whalesong/world/raw-jsworld.js +++ b/whalesong/world/raw-jsworld.js @@ -663,9 +663,13 @@ var rawJsworld = {}; stopWhen.test(w, function(stop) { if (stop) { - Jsworld.shutdown({cleanShutdown: true}); - } - else { k2(); } + var handler = stopWhen.last_picture_handler(); + handler.onRegister(top); + handler._listener(w, oldW, function(v) { + Jsworld.shutdown({cleanShutdown: true}); + k2(); + }) + } else { k2(); } }); }; add_world_listener(watchForTermination); @@ -863,17 +867,18 @@ var rawJsworld = {}; - StopWhenHandler = function(test, receiver) { + StopWhenHandler = function(test, receiver, last_picture_handler) { this.test = test; this.receiver = receiver; + this.last_picture_handler = last_picture_handler; }; // stop_when: CPS(world -> boolean) CPS(world -> boolean) -> handler - function stop_when(test, receiver) { + function stop_when(test, receiver, last_picture_handler) { return function() { if (receiver === undefined) { receiver = function(w, k) { k(w); }; } - return new StopWhenHandler(test, receiver); + return new StopWhenHandler(test, receiver, last_picture_handler); }; } Jsworld.stop_when = stop_when;