mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 22:00:03 -04:00
eframe web: detect and report panics during startup (#2992)
* Detect panics during initialization and show them to the user * PanicHandler now also logs the panics * Add example of how to call into your app from JS * Refactor: break out AppRunner and AppRunnerRef to own files * Hide AppRunner * Simplify user code * AppRunnerRef -> WebRunner * Better docs * Don't paint until first animation frame * Update multiple_apps.html * Update web demo * Cleanup and fixes * left-align panic message in html
This commit is contained in:
@@ -1,30 +1,11 @@
|
||||
use super::*;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/// Calls `request_animation_frame` to schedule repaint.
|
||||
///
|
||||
/// It will only paint if needed, but will always call `request_animation_frame` immediately.
|
||||
pub fn paint_and_schedule(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
fn paint_if_needed(runner: &mut AppRunner) -> Result<(), JsValue> {
|
||||
if runner.needs_repaint.when_to_repaint() <= now_sec() {
|
||||
runner.needs_repaint.clear();
|
||||
let (repaint_after, clipped_primitives) = runner.logic()?;
|
||||
runner.paint(&clipped_primitives)?;
|
||||
runner
|
||||
.needs_repaint
|
||||
.repaint_after(repaint_after.as_secs_f64());
|
||||
runner.auto_save_if_needed();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn request_animation_frame(runner_ref: AppRunnerRef) -> Result<(), JsValue> {
|
||||
let window = web_sys::window().unwrap();
|
||||
let closure = Closure::once(move || paint_and_schedule(&runner_ref));
|
||||
window.request_animation_frame(closure.as_ref().unchecked_ref())?;
|
||||
closure.forget(); // We must forget it, or else the callback is canceled on drop
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn paint_and_schedule(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
||||
// Only paint and schedule if there has been no panic
|
||||
if let Some(mut runner_lock) = runner_ref.try_lock() {
|
||||
paint_if_needed(&mut runner_lock)?;
|
||||
@@ -35,7 +16,30 @@ pub fn paint_and_schedule(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install_document_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
fn paint_if_needed(runner: &mut AppRunner) -> Result<(), JsValue> {
|
||||
if runner.needs_repaint.when_to_repaint() <= now_sec() {
|
||||
runner.needs_repaint.clear();
|
||||
let (repaint_after, clipped_primitives) = runner.logic();
|
||||
runner.paint(&clipped_primitives)?;
|
||||
runner
|
||||
.needs_repaint
|
||||
.repaint_after(repaint_after.as_secs_f64());
|
||||
runner.auto_save_if_needed();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn request_animation_frame(runner_ref: WebRunner) -> Result<(), JsValue> {
|
||||
let window = web_sys::window().unwrap();
|
||||
let closure = Closure::once(move || paint_and_schedule(&runner_ref));
|
||||
window.request_animation_frame(closure.as_ref().unchecked_ref())?;
|
||||
closure.forget(); // We must forget it, or else the callback is canceled on drop
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
pub fn install_document_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
|
||||
{
|
||||
@@ -185,7 +189,7 @@ pub fn install_document_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install_window_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
pub fn install_window_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
||||
let window = web_sys::window().unwrap();
|
||||
|
||||
// Save-on-close
|
||||
@@ -207,7 +211,7 @@ pub fn install_window_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install_color_scheme_change_event(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
pub fn install_color_scheme_change_event(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
||||
let window = web_sys::window().unwrap();
|
||||
|
||||
if let Some(media_query_list) = prefers_color_scheme_dark(&window)? {
|
||||
@@ -226,7 +230,7 @@ pub fn install_color_scheme_change_event(runner_ref: &AppRunnerRef) -> Result<()
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
pub fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
||||
let canvas = canvas_element(runner_ref.try_lock().unwrap().canvas_id()).unwrap();
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user