web: Flush shared objects on page unload

This commit is contained in:
Mike Welsh 2020-12-21 20:26:15 -08:00
parent d2ed3dbc81
commit 739af3f8d7
1 changed files with 31 additions and 3 deletions

View File

@ -35,8 +35,8 @@ use std::sync::{Arc, Mutex};
use std::{cell::RefCell, error::Error, num::NonZeroI32}; use std::{cell::RefCell, error::Error, num::NonZeroI32};
use wasm_bindgen::{prelude::*, JsCast, JsValue}; use wasm_bindgen::{prelude::*, JsCast, JsValue};
use web_sys::{ use web_sys::{
AddEventListenerOptions, Element, EventTarget, HtmlCanvasElement, HtmlElement, KeyboardEvent, AddEventListenerOptions, Element, Event, EventTarget, HtmlCanvasElement, HtmlElement,
PointerEvent, WheelEvent, KeyboardEvent, PointerEvent, WheelEvent,
}; };
static RUFFLE_GLOBAL_PANIC: Once = Once::new(); static RUFFLE_GLOBAL_PANIC: Once = Once::new();
@ -71,6 +71,7 @@ struct RuffleInstance {
mouse_wheel_callback: Option<Closure<dyn FnMut(WheelEvent)>>, mouse_wheel_callback: Option<Closure<dyn FnMut(WheelEvent)>>,
key_down_callback: Option<Closure<dyn FnMut(KeyboardEvent)>>, key_down_callback: Option<Closure<dyn FnMut(KeyboardEvent)>>,
key_up_callback: Option<Closure<dyn FnMut(KeyboardEvent)>>, key_up_callback: Option<Closure<dyn FnMut(KeyboardEvent)>>,
before_unload_callback: Option<Closure<dyn FnMut(Event)>>,
has_focus: bool, has_focus: bool,
trace_observer: Arc<RefCell<JsValue>>, trace_observer: Arc<RefCell<JsValue>>,
} }
@ -201,7 +202,10 @@ impl Ruffle {
instance.canvas.remove(); instance.canvas.remove();
// Stop all audio playing from the instance // Stop all audio playing from the instance
instance.core.lock().unwrap().audio_mut().stop_all_sounds(); let mut player = instance.core.lock().unwrap();
player.audio_mut().stop_all_sounds();
player.flush_shared_objects();
drop(player);
// Clean up all event listeners. // Clean up all event listeners.
instance.key_down_callback = None; instance.key_down_callback = None;
@ -211,6 +215,7 @@ impl Ruffle {
instance.mouse_up_callback = None; instance.mouse_up_callback = None;
instance.player_mouse_down_callback = None; instance.player_mouse_down_callback = None;
instance.window_mouse_down_callback = None; instance.window_mouse_down_callback = None;
instance.before_unload_callback = None;
// Cancel the animation handler, if it's still active. // Cancel the animation handler, if it's still active.
if let Some(id) = instance.animation_handler_id { if let Some(id) = instance.animation_handler_id {
@ -345,6 +350,7 @@ impl Ruffle {
mouse_wheel_callback: None, mouse_wheel_callback: None,
key_down_callback: None, key_down_callback: None,
key_up_callback: None, key_up_callback: None,
before_unload_callback: None,
timestamp: None, timestamp: None,
has_focus: false, has_focus: false,
trace_observer, trace_observer,
@ -657,6 +663,28 @@ impl Ruffle {
instance.key_up_callback = Some(key_up_callback); instance.key_up_callback = Some(key_up_callback);
} }
{
let before_unload_callback = Closure::wrap(Box::new(move |_| {
INSTANCES.with(|instances| {
if let Some(instance) = instances.borrow().get(index) {
let instance = instance.borrow();
let mut player = instance.core.lock().unwrap();
player.flush_shared_objects();
}
});
})
as Box<dyn FnMut(Event)>);
window
.add_event_listener_with_callback(
"beforeunload",
before_unload_callback.as_ref().unchecked_ref(),
)
.unwrap();
let mut instance = instances.get(index).unwrap().borrow_mut();
instance.before_unload_callback = Some(before_unload_callback);
}
ruffle ruffle
}); });