Allow unloading a movie by sending `None` to `replace_with_movie`.
This also adjusts `MovieClip.unloadMovie` to do just that, instead of removing the clip from the display list. We also have to unload clips when loading new movies into them, since `unloadMovie` desugars to loading `""` as the URL.
This commit is contained in:
parent
8ef4a94672
commit
162b6b70f8
|
@ -228,29 +228,8 @@ pub fn create_proto<'gc>(
|
|||
Ok(Value::Undefined.into())
|
||||
},
|
||||
"unloadMovie" => |mut target: MovieClip<'gc>, _avm: &mut Avm1<'gc>, context: &mut UpdateContext<'_, 'gc, '_>, _args: &[Value<'gc>]| {
|
||||
//TODO: How do we reclaim resources from unloaded movies?
|
||||
if let Some(parent) = target.parent() {
|
||||
parent
|
||||
.as_movie_clip()
|
||||
.unwrap()
|
||||
.remove_child_from_avm(context, DisplayObject::MovieClip(target));
|
||||
} else {
|
||||
//Removing a layer is a little different.
|
||||
let mut layer_depth = None;
|
||||
|
||||
for (depth, layer) in context.layers.iter() {
|
||||
if DisplayObject::ptr_eq(*layer, DisplayObject::MovieClip(target)) {
|
||||
layer_depth = Some(*depth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(depth) = layer_depth {
|
||||
context.layers.remove(&depth);
|
||||
}
|
||||
|
||||
target.unload(context);
|
||||
}
|
||||
target.unload(context);
|
||||
target.replace_with_movie(context.gc_context, None);
|
||||
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ impl<'gc> MovieClip<'gc> {
|
|||
pub fn replace_with_movie(
|
||||
&mut self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
movie: Arc<SwfMovie>,
|
||||
movie: Option<Arc<SwfMovie>>,
|
||||
) {
|
||||
self.0
|
||||
.write(gc_context)
|
||||
|
@ -424,13 +424,17 @@ impl<'gc> MovieClipData<'gc> {
|
|||
/// Replace the current MovieClipData with a completely new SwfMovie.
|
||||
///
|
||||
/// Playback will start at position zero, any existing streamed audio will
|
||||
/// be terminated, and so on. Children and AVM data will be kept across the
|
||||
/// load boundary.
|
||||
/// be terminated, and so on. Children and AVM data will NOT be kept across
|
||||
/// the load boundary.
|
||||
///
|
||||
/// If no movie is provided, then the movie clip will be replaced with an
|
||||
/// empty movie of the same SWF version.
|
||||
pub fn replace_with_movie(
|
||||
&mut self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
movie: Arc<SwfMovie>,
|
||||
movie: Option<Arc<SwfMovie>>,
|
||||
) {
|
||||
let movie = movie.unwrap_or_else(|| Arc::new(SwfMovie::empty(self.movie().version())));
|
||||
let total_frames = movie.header().num_frames;
|
||||
|
||||
self.base = Default::default();
|
||||
|
|
|
@ -211,6 +211,12 @@ impl<'gc> Loader<'gc> {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
clip.as_movie_clip().unwrap().unload(uc);
|
||||
|
||||
clip.as_movie_clip()
|
||||
.unwrap()
|
||||
.replace_with_movie(uc.gc_context, None);
|
||||
|
||||
if let Some(broadcaster) = broadcaster {
|
||||
avm.insert_stack_frame_for_method(
|
||||
clip,
|
||||
|
@ -264,7 +270,7 @@ impl<'gc> Loader<'gc> {
|
|||
.as_movie_clip()
|
||||
.expect("Attempted to load movie into not movie clip");
|
||||
|
||||
mc.replace_with_movie(uc.gc_context, movie.clone());
|
||||
mc.replace_with_movie(uc.gc_context, Some(movie.clone()));
|
||||
mc.post_instantiation(uc.gc_context, clip, avm.prototypes().movie_clip);
|
||||
|
||||
let mut morph_shapes = fnv::FnvHashMap::default();
|
||||
|
|
Loading…
Reference in New Issue