codeworld
codeworld copied to clipboard
Look into integrating reanimate
The reanimate library is pretty exciting, and I'd love to provide an easier environment to experiment with it. Currently, it must be run as a binary, which either renders to a gif or similar format, or serves an interpreted file via HTTP. I want to look into whether it's easy to run reanimate via GHCJS and render into the local document, instead. If that were possible, I would add reanimate to the list of pre-installed dependencies for CodeWorld's native Haskell mode, so it could be used without locally installed tooling.
https://reanimate.github.io/
@Lemmih in case you have thoughts.
This would be great. Is it easy to compile Haskell libraries to Javascript? What are some common pitfalls?
I guess the main open question is this: if you didn't have the filesystem or network at all, could I still use reanimate to build an animation, and then just ask it for the SVG at a given time? I can add SVG to an HTML document without too much difficulty (for example, the diagrams example at https://code.world/haskell#PfSPvyMNOP1r_mU0pY3wnZw -- there may be a better way to do it, but that one works)
Images are definitely a problem. Since you don't have access to the filesystem, you can't really load them that way. Any images would need to be referenced by URL instead of a file path.
I will start by trying to just build reanimate for GHCJS, and see if that succeeds.
Okay, the first problem I ran into is that reanimate depends on chiphunk, which in turn depends on a C library. As long as that's the case, building with GHCJS won't be possible.
I can move chuphunk to a separate package. I'm also using a C library for earclipping. Guess that'll have to be moved to a separate package as well. Then the core 'reanimate' library wouldn't use any C code.
Can I depend on 'hmatrix'? Does blas and lapack run as javascript? What about 'fsnotify'? Is it OK to depend on that library as long as it isn't actually used?
hmatrix will not build with GHCJS. I know that one right off, because it's why I couldn't build the hamilton package. fsnotify is fine, as you say, so long as it isn't actually used.
Ok, so 'chiphunk' and 'hmatrix' dependencies have to be moved to a separate package.
Is it possible to use Javascript libraries from Haskell? I'd like to use LaTeX.js and earcut.js
Hm, maybe MathJax instead of LaTeX.js
It's definitely possible to use GHCJS to build bindings for JavaScript libraries. I guess the completely self-contained way would be to (a) use the ghcjs-dom package to add a script element to the document, referencing the library on a CDN somewhere, (b) use an onload handler to wait for the script load to finish, and then (c) use JavaScriptFFI to call into the JavaScript library once it's loaded.
It sounds like this is becoming a pretty major change for reanimate. If you choose to do it, that's great, but it's way more than I expected.
Is there an easy way of installing ghcjs and testing whether reanimate works with it? Looking at your install script, it seems fairly involved.
Is there an easy way of installing ghcjs
That is the golden question, isn't it? I am not aware of an easy way of installing GHCJS. But assuming you have a relatively recent cabal and ghc installed, you can probably skip most of the steps from my install script, and do this:
- Clone GHCJS and change to that directory.
-
./utils/makePackages.sh
-
cabal v2-install .
-
ghcjs-boot
You may run into https://github.com/ghcjs/ghcjs/issues/740 and need to fix the symlink for ghcjs-boot. But maybe that bug is fixed in HEAD. I don't know. The install will likely take an hour or two.
Sigh, I'm using double-conversion
to pretty-print doubles and that library uses C. This is not gonna be easy.
I couldn't figure out how to install GHCJS but I made Reanimate work with Asterius.
The reanimate-svg package still needs to know whether to use C code or if it should resort to a slower, pure-haskell implementation. Do you know if there's a way to detect if a package is being compiled by GHCJS?
Okay, if it works with Asterius, then I think that's a good sign that GHCJS is likely to work, as well.
To detect if it's being compiled by GHCJS, you can do one of the following:
- In Cabal:
if impl(ghcjs)
. See https://github.com/google/codeworld/blob/e2029cefde1a5982d60fb15ec25bf47264846bf6/codeworld-api/codeworld-api.cabal#L70 for an example. - In Haskell with CPP:
#ifdef ghcjs_HOST_OS
. See https://github.com/google/codeworld/blob/e2029cefde1a5982d60fb15ec25bf47264846bf6/codeworld-api/src/CodeWorld/Driver.hs#L75 for an example.