Hah yup quick css change I will have a branch up tomorrow, thanks!
Got a PR up to address this
This is a good sticking point with ergonomics with multifile. We already save state relevant to the most recent changes via compressed local storage, we can include the files open and cursor position as well and if requested through config or URL param, we can always rehydrate that (this will be specific to snippet ID, so we can cycle through snippets and have that state saved/hydrated whenever loading). I will try to get a working proof of concept soon!
Another one I noticed today: when we rename a file, the corresponding import from "..." is/are not renamed accordingly.
I haven’t pinpointed the cause yet, but some Playground IDs don’t open for me.
With WebGPU query param, the page gets stuck on the Babylon.js loading logo and never proceeds:
https://playground.babylonjs.com/?webgpu#Y2UGQ5#3
Without the WebGPU query param, the source loads but the program can’t run in WebGPU mode:
https://playground.babylonjs.com/#Y2UGQ5#3
Is anyone else seeing this? Any known issues or workarounds?
There’s a workaround here but there might be a better root-level fix for waiting until the scene is ready before executing the code, the code in that PG ends up in a deadlock because it awaits reading a value from the GPU buffer before the scene is returned and started rendering. I remember running into similar issues on the old PG. Do you know for sure this used to be working? It’s a bit of chicken and egg scenario but I might be able to find a root fix.
In the meantime, here’s a fixed PG that uses scene.onReadyObservable.addOnce
So I have an initial pass on the hydrating state from a snippet which is just tied to local storage. For every snippet, it also stores off the open file list, active file and last cursor position and rehydrates those upon entry (refreshing page). I feel like this is an unobtrusive and useful for everyone feature that might not need a config toggle for it, and on top of this we can add things like URL param overrides, or even another checkbox while saving a snippet to also include this data in the saved version and have all users load in that state when they open the snippet for the first time. Let me know what you think.
To your second comment, yeah unfortunately there isn’t anything out of the box with Monaco for renaming imports when file names change, that’s a more involved change that would involve some scrubbing and regex replacing and hopefully getting things right. Can put it on the nice-to-have list, does make sense and would benefit everybody (option to rename imports while committing rename dialog)
The new v2 version behaves differently when setting global properties:
The global code (window.toto = 1; in the PG above) was previously executed every time we clicked “Play,” so we always restarted with toto=1. Now, toto is no longer reset and continues to increase every time we start the PG.
Roger will get this fix up tomorrow morning thanks for the catch. How are things working out generally? Any annoyances that can be addressed or things that need improvement? Still need to finish my docs PR, been swamped with work lately but able to get fixes in meanwhile
It works very well!
Another minor annoyance is that sometimes, when saving the PG, the id changes completely instead of the revision number being incremented. I can’t provide a reproduction because I don’t know when/why this happens.
Hey sorry for the late follow-up, have been traveling for work and family visits recently. Here is what’s happening in this case:
- Every time you click “Run” (or automatically on page load), all the files in the PG are compiled as ES modules. Every subsequent run will reuse these cached modules (to avoid overhead of recompiling everything every run) in the PG entrypoint (createScene or the corresponding function depending on environment)
- Editing any of the modules automatically breaks this cache
- The outer “module scope” code only gets run anytime a cache miss happens on run, i.e.
window.toto = 1will only be called in that case.
Some ideas off the top of my head are:
- Any “initialization code” can happen inside the entrypoint function (createScene) and will be deterministic. Caveat here is obviously we share global window state and any code in the PG can modify any code in the PG so side effects break idempotency.
- Never cache the entrypoint and force re-compilation of all modules on every run.
What do you think could be best practice here? I put the caching in as a sort of gold-plating layer for optimization thinking people’s use case there would be running a PG from the start and watching a time sequence of something happening and doing that over and over without modifying code. The second they modify code, that cached entrypoint will be recompiled.
I don’t know what the best solution is in this case… It’s a breaking change from how it worked before version 2, but I don’t know if that’s a big problem or if we can just say that’s how it works, and if someone wants to run the global code again, they have to refresh the page…
One suggestion: add a setting such as “Always execute global code when PG is started” to the list of settings. That way, users can decide whether they want to enable it or not.
cc @Deltakosh and @sebavan for their inputs.
I like the settings idea!
I like the idea of an optional teardown method - it does create an extra convention, but the PG already works on conventions. In the past I have added Scene observables to work around it, but adding DOM click event handlers or such would create double events on re-run PGs. This is similar to how testing frameworks work.
const createScene = () => { ... }
// optional
const onSceneDestroy = () => window.toto = 1