Open zdimension opened 6 months ago
Interesting!
The fix could be for NeedRepaint::repaint_after
to try to get the current time and on failure set repaint_time
to -INF
to just force a repaint asap. ctx.request_repaint_after(…)
would not work properly from a web-worker though. Not sure how to handle that case.
It's possible to get the time though, chrono::Local::now()
works from the web worker. But eframe is using the Performance api which isn't exposed by js-sys for workers apparently (though the object is useable from workers). Either we could write some kind of wrapper for that that calls the Performance api without using the window object, or when called from a web worker request_repaint could use the low resolution time.
web-sys exposes the Performance API for workers as web_sys::WorkerGlobalScope::performance
. You just need to be using web-sys 0.3.65 or later and have the Performance
and WorkerGlobalScope
features enabled.
web-sys exposes the Performance API for workers as
web_sys::WorkerGlobalScope::performance
. You just need to be using web-sys 0.3.65 or later and have thePerformance
andWorkerGlobalScope
features enabled.
Thanks, that was it! Performance
was already listed by eframe
but not WorkerGlobalScope
, adding it fixed the problem. I think mentioning that in the docs somewhere (for other people who'd like to use egui along with Web Workers) could be good
Thanks for describing the fix! I'll re-open this as a reminder to add docs, or add WorkerGlobalScope
to eframe
Hi @zdimension, I'm curious to know more about the original code you were writing when you encountered this issue. Were you running an egui application inside of a web worker? Or was your egui application running on the main browser thread and you were somehow sharing an egui::Context
between the main thread and the web worker? If it's the latter, how did you do that?
Hi @zdimension, I'm curious to know more about the original code you were writing when you encountered this issue. Were you running an egui application inside of a web worker? Or was your egui application running on the main browser thread and you were somehow sharing an
egui::Context
between the main thread and the web worker? If it's the latter, how did you do that?
Hi, here is the commit where I fixed my issue, you can see a bit how it works: https://github.com/zdimension/graphrust/commit/43913282e5367339857b4c2f4df3e8becb3a3c65
My project is an app that runs egui on the main thread, and offloads data processing to threads (or, on the Web, workers). The workers regularly report their progress to the UI (as percentages or status messages).
Once cloned, an egui Context can be moved to another thread.
My current design uses channels which is not perfect but it's simple and fast enough.
Describe the bug
Using
request_repaint
(or any of its variants) from a Web Worker panics. The panic info points here:https://github.com/emilk/egui/blob/a8501c963dba0f14a8feff28ed91ff245956662c/crates/eframe/src/web/mod.rs#L60-L67
It seems like eframe ends up trying to get the time, but the
now_sec
function uses the JS Window object which isn't available from a Web Worker.Right now, my workaround is to force my app to run at 60fps continuous during the loading time, instead of repainting when needed.
Screenshots
Desktop (please complete the following information):