Closing a running Walt sketch when recompilinghttps://beta.observablehq.com/@jobleonard/compiling-walt-in-the-observable-experiment

So it turns out to be ridiculously easy to embed Walt into an Observable notebook, because the compiler itself is fully JS-based! :smile:

However, the demo code I adapted uses this loop to run its animation:

    function run() {
      exports.step();
      imgData.data.set(imageArray);
      ctx.putImageData(imgData, 0, 0);
      requestAnimationFrame(run, 0);
    }

That is problematic, because whenever I re-evaluate that cell, it creates a new bit of WASM code, which means that in the end we have tons of loops trying to paint to the same Canvas.

What I need is something that automatically closes this kind of loop when a cell gets re-evaluated. Is there a good general technique for that?

(this is also the only thing stopping me from just importing a textarea from @jashkenas’ input notebook and recreating the Walt Explorer in a notebook)

1 Like

You could try

invalidation.then(() => {})

in a cell to do an action when the cell invalidates. See https://beta.observablehq.com/@mbostock/synchronized-views

About half way down you’ll see it used to remove an event listener

  invalidation.then(() => viewof y.removeEventListener("input", update));
1 Like

You could store the request ID in order to cancel it on demand: https://beta.observablehq.com/compare/68a39e4424361cdd...8391cfe751bca050

2 Likes

Thank you both for your answers, and mootari for the quick fix! :+1:

Seconding @mootari’s suggestion! (Also bonus points for expressing it as a ready-to-merge comparison!)

Here’s a related notebook:

1 Like

You’re very welcome, and there’s really no need for the attribution. :smiley: And to nitpick my own code: the function should actually be called “stop” or “pause”, because you can always call run() afterwards to resume.

Credit where credit is due: I didn’t even know requestAnimationFrame returns a cancellable ID until I saw it in one of @mbostock’s notebooks. :slight_smile:

You could store the request ID in order to cancel it on demand: https://beta.observablehq.com/compare/68a39e4424361cdd…8391cfe751bca050

I was curious what the fix was, but unfortunately the above link no longer shows the diff between the old version of the notebook and mootari’s version. After fooling around a bit with the version numbers using mootari’s other helpful notebook, I think I found a permalink for the original suggestion. Here it is, for future visitors: https://beta.observablehq.com/compare/68a39e4424361cdd@172...8391cfe751bca050@174

Presumably such version-pinned compare links will be easier to generate as more “history” features are added to Observable…

2 Likes

Yes! And we just had a little conversation about adding the version numbers by default to the “Compare fork” link.

The problem then would be that if @mootari had pushed additional changes to his fork, they wouldn’t be reflected in that original, shared, URL.

We’ll try to come up with something convenient for the default behavior…

1 Like

there’s really no need for the attribution.

Oh come on, you linked to an solution that I could merge with the click of a button, of course you deserve attribution for that. If it makes you feel better: it felt a bit weird without context so I moved it to a code comment above the line showing it. Now you only see the attribution when expanding the cell :wink: