eframe web: rememeber to unsubscribe from events on destroy
This commit is contained in:
parent
ac50fa0d94
commit
4d360f67a4
|
|
@ -517,17 +517,19 @@ impl AppRunnerRef {
|
||||||
if self.panic_handler.lock().has_panicked() {
|
if self.panic_handler.lock().has_panicked() {
|
||||||
// Unsubscribe from all events so that we don't get any more callbacks
|
// Unsubscribe from all events so that we don't get any more callbacks
|
||||||
// that will try to access the poisoned runner.
|
// that will try to access the poisoned runner.
|
||||||
let events_to_unsubscribe: Vec<_> =
|
self.unsubscribe_from_all_events();
|
||||||
std::mem::take(&mut *self.events_to_unsubscribe.borrow_mut());
|
}
|
||||||
if !events_to_unsubscribe.is_empty() {
|
}
|
||||||
log::debug!(
|
|
||||||
"Unsubscribing from {} events due to panic",
|
fn unsubscribe_from_all_events(&self) {
|
||||||
events_to_unsubscribe.len()
|
let events_to_unsubscribe: Vec<_> =
|
||||||
);
|
std::mem::take(&mut *self.events_to_unsubscribe.borrow_mut());
|
||||||
for x in events_to_unsubscribe {
|
|
||||||
if let Err(err) = x.unsubscribe() {
|
if !events_to_unsubscribe.is_empty() {
|
||||||
log::error!("Failed to unsubscribe from event: {err:?}");
|
log::debug!("Unsubscribing from {} events", events_to_unsubscribe.len());
|
||||||
}
|
for x in events_to_unsubscribe {
|
||||||
|
if let Err(err) = x.unsubscribe() {
|
||||||
|
log::error!("Failed to unsubscribe from event: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -546,6 +548,7 @@ impl AppRunnerRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(&self) {
|
pub fn destroy(&self) {
|
||||||
|
self.unsubscribe_from_all_events();
|
||||||
if let Some(mut runner) = self.try_lock() {
|
if let Some(mut runner) = self.try_lock() {
|
||||||
runner.destroy();
|
runner.destroy();
|
||||||
}
|
}
|
||||||
|
|
@ -574,21 +577,17 @@ impl AppRunnerRef {
|
||||||
event_name: &'static str,
|
event_name: &'static str,
|
||||||
mut closure: impl FnMut(E, &mut AppRunner) + 'static,
|
mut closure: impl FnMut(E, &mut AppRunner) + 'static,
|
||||||
) -> Result<(), JsValue> {
|
) -> Result<(), JsValue> {
|
||||||
|
let runner_ref = self.clone();
|
||||||
|
|
||||||
// Create a JS closure based on the FnMut provided
|
// Create a JS closure based on the FnMut provided
|
||||||
let closure = Closure::wrap({
|
let closure = Closure::wrap(Box::new(move |event: web_sys::Event| {
|
||||||
// Clone atomics
|
// Only call the wrapped closure if the egui code has not panicked
|
||||||
let runner_ref = self.clone();
|
if let Some(mut runner_lock) = runner_ref.try_lock() {
|
||||||
|
// Cast the event to the expected event type
|
||||||
Box::new(move |event: web_sys::Event| {
|
let event = event.unchecked_into::<E>();
|
||||||
// Only call the wrapped closure if the egui code has not panicked
|
closure(event, &mut runner_lock);
|
||||||
if let Some(mut runner_lock) = runner_ref.try_lock() {
|
}
|
||||||
// Cast the event to the expected event type
|
}) as Box<dyn FnMut(web_sys::Event)>);
|
||||||
let event = event.unchecked_into::<E>();
|
|
||||||
|
|
||||||
closure(event, &mut runner_lock);
|
|
||||||
}
|
|
||||||
}) as Box<dyn FnMut(web_sys::Event)>
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add the event listener to the target
|
// Add the event listener to the target
|
||||||
target.add_event_listener_with_callback(event_name, closure.as_ref().unchecked_ref())?;
|
target.add_event_listener_with_callback(event_name, closure.as_ref().unchecked_ref())?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue