core: Remove LoaderHandle when load is done
In almost all cases, we were letting completed LoaderHandles accumulate, leaking memory and wasting time in `preload_tick`
This commit is contained in:
parent
0df6bafdaf
commit
c8f4cb6fb2
|
@ -24,6 +24,12 @@ use super::Avm2;
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
pub struct Domain<'gc>(GcCell<'gc, DomainData<'gc>>);
|
pub struct Domain<'gc>(GcCell<'gc, DomainData<'gc>>);
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Domain<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "Domain({:p})", self.0.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Collect)]
|
#[derive(Copy, Clone, Collect)]
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
pub struct DomainWeak<'gc>(GcWeakCell<'gc, DomainData<'gc>>);
|
pub struct DomainWeak<'gc>(GcWeakCell<'gc, DomainData<'gc>>);
|
||||||
|
|
|
@ -614,7 +614,7 @@ pub enum LoaderStatus {
|
||||||
Failed,
|
Failed,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Collect, Clone, Copy)]
|
#[derive(Collect, Clone, Copy, Debug)]
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
pub enum MovieLoaderVMData<'gc> {
|
pub enum MovieLoaderVMData<'gc> {
|
||||||
Avm1 {
|
Avm1 {
|
||||||
|
@ -632,7 +632,7 @@ pub enum MovieLoaderVMData<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct that holds garbage-collected pointers for asynchronous code.
|
/// A struct that holds garbage-collected pointers for asynchronous code.
|
||||||
#[derive(Collect)]
|
#[derive(Collect, Debug)]
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
pub enum Loader<'gc> {
|
pub enum Loader<'gc> {
|
||||||
/// Loader that is loading the root movie of a player.
|
/// Loader that is loading the root movie of a player.
|
||||||
|
@ -886,7 +886,7 @@ impl<'gc> Loader<'gc> {
|
||||||
parameters: Vec<(String, String)>,
|
parameters: Vec<(String, String)>,
|
||||||
on_metadata: Box<dyn FnOnce(&swf::HeaderExt)>,
|
on_metadata: Box<dyn FnOnce(&swf::HeaderExt)>,
|
||||||
) -> OwnedFuture<(), Error> {
|
) -> OwnedFuture<(), Error> {
|
||||||
let _handle = match self {
|
let handle = match self {
|
||||||
Loader::RootMovie { self_handle, .. } => {
|
Loader::RootMovie { self_handle, .. } => {
|
||||||
self_handle.expect("Loader not self-introduced")
|
self_handle.expect("Loader not self-introduced")
|
||||||
}
|
}
|
||||||
|
@ -943,6 +943,7 @@ impl<'gc> Loader<'gc> {
|
||||||
movie.append_parameters(parameters);
|
movie.append_parameters(parameters);
|
||||||
player.lock().unwrap().mutate_with_update_context(|uc| {
|
player.lock().unwrap().mutate_with_update_context(|uc| {
|
||||||
uc.set_root_movie(movie);
|
uc.set_root_movie(movie);
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -1154,6 +1155,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activation.context.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1254,6 +1257,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activation.context.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1443,6 +1448,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1507,6 +1514,8 @@ impl<'gc> Loader<'gc> {
|
||||||
crate::avm1::start_sound(&mut activation, sound_object.into(), &[])?;
|
crate::avm1::start_sound(&mut activation, sound_object.into(), &[])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activation.context.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1607,6 +1616,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1674,6 +1685,10 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.lock().unwrap().update(|uc| {
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(response) => player.lock().unwrap().update(|uc| {
|
Err(response) => player.lock().unwrap().update(|uc| {
|
||||||
|
@ -1685,6 +1700,7 @@ impl<'gc> Loader<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
stream.report_error(response.error);
|
stream.report_error(response.error);
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
Ok(())
|
Ok(())
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -2283,6 +2299,12 @@ impl<'gc> Loader<'gc> {
|
||||||
&["onLoadComplete".into(), target_clip.object(), status.into()],
|
&["onLoadComplete".into(), target_clip.object(), status.into()],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Loader::Movie { loader_status, .. } =
|
||||||
|
uc.load_manager.get_loader_mut(handle).unwrap()
|
||||||
|
{
|
||||||
|
*loader_status = LoaderStatus::Succeeded;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// This is fired after we process the movie's first frame,
|
// This is fired after we process the movie's first frame,
|
||||||
// in `MovieClip.on_exit_frame`
|
// in `MovieClip.on_exit_frame`
|
||||||
|
@ -2299,14 +2321,10 @@ impl<'gc> Loader<'gc> {
|
||||||
loader_info_obj.fire_init_and_complete_events(uc, status, redirected);
|
loader_info_obj.fire_init_and_complete_events(uc, status, redirected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// We only remove this in the AVM2 case - in AVM1, this is handled by 'movie_clip_on_load'
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Loader::Movie { loader_status, .. } = uc.load_manager.get_loader_mut(handle).unwrap()
|
|
||||||
{
|
|
||||||
*loader_status = LoaderStatus::Succeeded;
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2357,6 +2375,11 @@ impl<'gc> Loader<'gc> {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if let Loader::Movie { loader_status, .. } =
|
||||||
|
uc.load_manager.get_loader_mut(handle).unwrap()
|
||||||
|
{
|
||||||
|
*loader_status = LoaderStatus::Failed;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
MovieLoaderVMData::Avm2 { loader_info, .. } => {
|
MovieLoaderVMData::Avm2 { loader_info, .. } => {
|
||||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||||
|
@ -2396,14 +2419,11 @@ impl<'gc> Loader<'gc> {
|
||||||
.map_err(|e| Error::Avm2Error(e.to_string()))?;
|
.map_err(|e| Error::Avm2Error(e.to_string()))?;
|
||||||
|
|
||||||
Avm2::dispatch_event(uc, io_error_evt, loader_info);
|
Avm2::dispatch_event(uc, io_error_evt, loader_info);
|
||||||
|
// We only remove this in the AVM2 case - in AVM1, this is handled by 'movie_clip_on_load'
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Loader::Movie { loader_status, .. } = uc.load_manager.get_loader_mut(handle).unwrap()
|
|
||||||
{
|
|
||||||
*loader_status = LoaderStatus::Failed;
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2584,6 +2604,8 @@ impl<'gc> Loader<'gc> {
|
||||||
tracing::warn!("Error on file dialog: {:?}", err);
|
tracing::warn!("Error on file dialog: {:?}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activation.context.load_manager.remove_loader(handle);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Some(&Loader::FileDialogAvm2 { target_object, .. }) => {
|
Some(&Loader::FileDialogAvm2 { target_object, .. }) => {
|
||||||
|
@ -2622,6 +2644,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => Err(Error::Cancelled),
|
None => Err(Error::Cancelled),
|
||||||
|
@ -2735,6 +2759,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uc.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -2940,6 +2966,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activation.context.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -3110,6 +3138,8 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activation.context.load_manager.remove_loader(handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue