Skip to content

Commit

Permalink
[egui_web] Prevent event handlers from running if code has panicked (#…
Browse files Browse the repository at this point in the history
…1306)

Closes: #1290

Fix panic reported by @Titaniumtown
See #1306 (comment)
  • Loading branch information
DusterTheFirst authored Mar 10, 2022
1 parent 30399bf commit 5d950e1
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 256 deletions.
10 changes: 5 additions & 5 deletions egui/src/widgets/plot/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Simple plotting library.

use std::{cell::RefCell, ops::RangeInclusive, rc::Rc};
use std::{cell::Cell, ops::RangeInclusive, rc::Rc};

use crate::*;
use epaint::ahash::AHashSet;
Expand Down Expand Up @@ -92,15 +92,15 @@ impl PlotMemory {
pub struct LinkedAxisGroup {
pub(crate) link_x: bool,
pub(crate) link_y: bool,
pub(crate) bounds: Rc<RefCell<Option<PlotBounds>>>,
pub(crate) bounds: Rc<Cell<Option<PlotBounds>>>,
}

impl LinkedAxisGroup {
pub fn new(link_x: bool, link_y: bool) -> Self {
Self {
link_x,
link_y,
bounds: Rc::new(RefCell::new(None)),
bounds: Rc::new(Cell::new(None)),
}
}

Expand Down Expand Up @@ -132,11 +132,11 @@ impl LinkedAxisGroup {
}

fn get(&self) -> Option<PlotBounds> {
*self.bounds.borrow()
self.bounds.get()
}

fn set(&self, bounds: PlotBounds) {
*self.bounds.borrow_mut() = Some(bounds);
self.bounds.set(Some(bounds));
}
}

Expand Down
1 change: 1 addition & 0 deletions egui_web/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ All notable changes to the `egui_web` integration will be noted in this file.


## Unreleased
* egui code will no longer be called after panic ([#1306](https://github.com/emilk/egui/pull/1306))


## 0.17.0 - 2022-02-22
Expand Down
40 changes: 33 additions & 7 deletions egui_web/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,37 @@ pub fn start(canvas_id: &str, app: Box<dyn epi::App>) -> Result<AppRunnerRef, Js
/// Install event listeners to register different input events
/// and starts running the given `AppRunner`.
fn start_runner(app_runner: AppRunner) -> Result<AppRunnerRef, JsValue> {
let runner_ref = AppRunnerRef(Arc::new(Mutex::new(app_runner)));
install_canvas_events(&runner_ref)?;
install_document_events(&runner_ref)?;
text_agent::install_text_agent(&runner_ref)?;
repaint_every_ms(&runner_ref, 1000)?; // just in case. TODO: make it a parameter
paint_and_schedule(runner_ref.clone())?;
Ok(runner_ref)
let runner_container = AppRunnerContainer {
runner: Arc::new(Mutex::new(app_runner)),
panicked: Arc::new(AtomicBool::new(false)),
};

install_canvas_events(&runner_container)?;
install_document_events(&runner_container)?;
text_agent::install_text_agent(&runner_container)?;
repaint_every_ms(&runner_container, 1000)?; // just in case. TODO: make it a parameter

paint_and_schedule(&runner_container.runner, runner_container.panicked.clone())?;

// Disable all event handlers on panic
std::panic::set_hook(Box::new({
let previous_hook = std::panic::take_hook();

let panicked = runner_container.panicked;

move |panic_info| {
tracing::info_span!("egui_panic_handler").in_scope(|| {
tracing::trace!("setting panicked flag");

panicked.store(true, SeqCst);

tracing::info!("egui disabled all event handlers due to panic");
});

// Propagate panic info to the previously registered panic hook
previous_hook(panic_info);
}
}));

Ok(runner_container.runner)
}
Loading

0 comments on commit 5d950e1

Please sign in to comment.