Skip to content

Commit 4d360f6

Browse files
committed
eframe web: rememeber to unsubscribe from events on destroy
1 parent ac50fa0 commit 4d360f6

File tree

1 file changed

+24
-25
lines changed

1 file changed

+24
-25
lines changed

crates/eframe/src/web/backend.rs

+24-25
Original file line numberDiff line numberDiff line change
@@ -517,17 +517,19 @@ impl AppRunnerRef {
517517
if self.panic_handler.lock().has_panicked() {
518518
// Unsubscribe from all events so that we don't get any more callbacks
519519
// that will try to access the poisoned runner.
520-
let events_to_unsubscribe: Vec<_> =
521-
std::mem::take(&mut *self.events_to_unsubscribe.borrow_mut());
522-
if !events_to_unsubscribe.is_empty() {
523-
log::debug!(
524-
"Unsubscribing from {} events due to panic",
525-
events_to_unsubscribe.len()
526-
);
527-
for x in events_to_unsubscribe {
528-
if let Err(err) = x.unsubscribe() {
529-
log::error!("Failed to unsubscribe from event: {err:?}");
530-
}
520+
self.unsubscribe_from_all_events();
521+
}
522+
}
523+
524+
fn unsubscribe_from_all_events(&self) {
525+
let events_to_unsubscribe: Vec<_> =
526+
std::mem::take(&mut *self.events_to_unsubscribe.borrow_mut());
527+
528+
if !events_to_unsubscribe.is_empty() {
529+
log::debug!("Unsubscribing from {} events", events_to_unsubscribe.len());
530+
for x in events_to_unsubscribe {
531+
if let Err(err) = x.unsubscribe() {
532+
log::error!("Failed to unsubscribe from event: {err:?}");
531533
}
532534
}
533535
}
@@ -546,6 +548,7 @@ impl AppRunnerRef {
546548
}
547549

548550
pub fn destroy(&self) {
551+
self.unsubscribe_from_all_events();
549552
if let Some(mut runner) = self.try_lock() {
550553
runner.destroy();
551554
}
@@ -574,21 +577,17 @@ impl AppRunnerRef {
574577
event_name: &'static str,
575578
mut closure: impl FnMut(E, &mut AppRunner) + 'static,
576579
) -> Result<(), JsValue> {
577-
// Create a JS closure based on the FnMut provided
578-
let closure = Closure::wrap({
579-
// Clone atomics
580-
let runner_ref = self.clone();
580+
let runner_ref = self.clone();
581581

582-
Box::new(move |event: web_sys::Event| {
583-
// Only call the wrapped closure if the egui code has not panicked
584-
if let Some(mut runner_lock) = runner_ref.try_lock() {
585-
// Cast the event to the expected event type
586-
let event = event.unchecked_into::<E>();
587-
588-
closure(event, &mut runner_lock);
589-
}
590-
}) as Box<dyn FnMut(web_sys::Event)>
591-
});
582+
// Create a JS closure based on the FnMut provided
583+
let closure = Closure::wrap(Box::new(move |event: web_sys::Event| {
584+
// Only call the wrapped closure if the egui code has not panicked
585+
if let Some(mut runner_lock) = runner_ref.try_lock() {
586+
// Cast the event to the expected event type
587+
let event = event.unchecked_into::<E>();
588+
closure(event, &mut runner_lock);
589+
}
590+
}) as Box<dyn FnMut(web_sys::Event)>);
592591

593592
// Add the event listener to the target
594593
target.add_event_listener_with_callback(event_name, closure.as_ref().unchecked_ref())?;

0 commit comments

Comments
 (0)