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)]
|
||||
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)]
|
||||
#[collect(no_drop)]
|
||||
pub struct DomainWeak<'gc>(GcWeakCell<'gc, DomainData<'gc>>);
|
||||
|
|
|
@ -614,7 +614,7 @@ pub enum LoaderStatus {
|
|||
Failed,
|
||||
}
|
||||
|
||||
#[derive(Collect, Clone, Copy)]
|
||||
#[derive(Collect, Clone, Copy, Debug)]
|
||||
#[collect(no_drop)]
|
||||
pub enum MovieLoaderVMData<'gc> {
|
||||
Avm1 {
|
||||
|
@ -632,7 +632,7 @@ pub enum MovieLoaderVMData<'gc> {
|
|||
}
|
||||
|
||||
/// A struct that holds garbage-collected pointers for asynchronous code.
|
||||
#[derive(Collect)]
|
||||
#[derive(Collect, Debug)]
|
||||
#[collect(no_drop)]
|
||||
pub enum Loader<'gc> {
|
||||
/// Loader that is loading the root movie of a player.
|
||||
|
@ -886,7 +886,7 @@ impl<'gc> Loader<'gc> {
|
|||
parameters: Vec<(String, String)>,
|
||||
on_metadata: Box<dyn FnOnce(&swf::HeaderExt)>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let _handle = match self {
|
||||
let handle = match self {
|
||||
Loader::RootMovie { self_handle, .. } => {
|
||||
self_handle.expect("Loader not self-introduced")
|
||||
}
|
||||
|
@ -943,6 +943,7 @@ impl<'gc> Loader<'gc> {
|
|||
movie.append_parameters(parameters);
|
||||
player.lock().unwrap().mutate_with_update_context(|uc| {
|
||||
uc.set_root_movie(movie);
|
||||
uc.load_manager.remove_loader(handle);
|
||||
});
|
||||
Ok(())
|
||||
})
|
||||
|
@ -1154,6 +1155,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
activation.context.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
@ -1254,6 +1257,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
activation.context.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
@ -1443,6 +1448,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
uc.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
@ -1507,6 +1514,8 @@ impl<'gc> Loader<'gc> {
|
|||
crate::avm1::start_sound(&mut activation, sound_object.into(), &[])?;
|
||||
}
|
||||
|
||||
activation.context.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
@ -1607,6 +1616,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
uc.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
@ -1674,6 +1685,10 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
player.lock().unwrap().update(|uc| {
|
||||
uc.load_manager.remove_loader(handle);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Err(response) => player.lock().unwrap().update(|uc| {
|
||||
|
@ -1685,6 +1700,7 @@ impl<'gc> Loader<'gc> {
|
|||
};
|
||||
|
||||
stream.report_error(response.error);
|
||||
uc.load_manager.remove_loader(handle);
|
||||
Ok(())
|
||||
}),
|
||||
}
|
||||
|
@ -2283,6 +2299,12 @@ impl<'gc> Loader<'gc> {
|
|||
&["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,
|
||||
// in `MovieClip.on_exit_frame`
|
||||
|
@ -2299,14 +2321,10 @@ impl<'gc> Loader<'gc> {
|
|||
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(())
|
||||
}
|
||||
|
||||
|
@ -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, .. } => {
|
||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||
|
@ -2396,14 +2419,11 @@ impl<'gc> Loader<'gc> {
|
|||
.map_err(|e| Error::Avm2Error(e.to_string()))?;
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
|
@ -2584,6 +2604,8 @@ impl<'gc> Loader<'gc> {
|
|||
tracing::warn!("Error on file dialog: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
activation.context.load_manager.remove_loader(handle);
|
||||
Ok(())
|
||||
}
|
||||
Some(&Loader::FileDialogAvm2 { target_object, .. }) => {
|
||||
|
@ -2622,6 +2644,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
uc.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => Err(Error::Cancelled),
|
||||
|
@ -2735,6 +2759,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
uc.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
@ -2940,6 +2966,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
activation.context.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
@ -3110,6 +3138,8 @@ impl<'gc> Loader<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
activation.context.load_manager.remove_loader(handle);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue