core: When constructing objects for DisplayObjects, make sure frames are run at the right moment

This commit is contained in:
Nathan Adams 2020-08-31 21:30:17 +02:00 committed by Mike Welsh
parent 2bc70751e2
commit 2178beec87
10 changed files with 37 additions and 16 deletions

View File

@ -2645,7 +2645,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
level.set_depth(self.context.gc_context, level_id as i32);
self.context.levels.insert(level_id, level);
level.post_instantiation(&mut self.context, level, None, false);
level.post_instantiation(&mut self.context, level, None, false, false);
level
}

View File

@ -519,8 +519,7 @@ fn attach_movie<'gc>(
} else {
None
};
new_clip.post_instantiation(&mut activation.context, new_clip, init_object, true);
new_clip.run_frame(&mut activation.context);
new_clip.post_instantiation(&mut activation.context, new_clip, init_object, true, true);
Ok(new_clip.object().coerce_to_object(activation).into())
} else {
@ -557,8 +556,7 @@ fn create_empty_movie_clip<'gc>(
// Set name and attach to parent.
new_clip.set_name(activation.context.gc_context, &new_instance_name);
movie_clip.add_child_from_avm(&mut activation.context, new_clip.into(), depth);
new_clip.post_instantiation(&mut activation.context, new_clip.into(), None, true);
new_clip.run_frame(&mut activation.context);
new_clip.post_instantiation(&mut activation.context, new_clip.into(), None, true, true);
Ok(new_clip.object())
}
@ -607,7 +605,7 @@ fn create_text_field<'gc>(
text_field,
(depth as Depth).wrapping_add(AVM_DEPTH_BIAS),
);
text_field.post_instantiation(&mut activation.context, text_field, None, true);
text_field.post_instantiation(&mut activation.context, text_field, None, true, false);
if activation.current_swf_version() >= 8 {
//SWF8+ returns the `TextField` instance here
@ -682,8 +680,7 @@ pub fn duplicate_movie_clip_with_bias<'gc>(
// Definitely not ScriptObject properties.
let init_object = init_object.map(|v| v.coerce_to_object(activation));
new_clip.post_instantiation(&mut activation.context, new_clip, init_object, true);
new_clip.run_frame(&mut activation.context);
new_clip.post_instantiation(&mut activation.context, new_clip, init_object, true, true);
Ok(new_clip.object().coerce_to_object(activation).into())
} else {

View File

@ -913,7 +913,7 @@ mod tests {
avm2: &mut avm2,
};
root.post_instantiation(&mut context, root, None, false);
root.post_instantiation(&mut context, root, None, false, false);
root.set_name(context.gc_context, "");
let base_clip = *context.levels.get(&0).unwrap();

View File

@ -73,7 +73,7 @@ where
avm1: &mut avm1,
avm2: &mut avm2,
};
root.post_instantiation(&mut context, root, None, false);
root.post_instantiation(&mut context, root, None, false, false);
root.set_name(context.gc_context, "");
fn run_test<'a, 'gc: 'a, F>(

View File

@ -824,11 +824,15 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug + Into<DisplayObject<'gc>>
fn post_instantiation(
&self,
_context: &mut UpdateContext<'_, 'gc, '_>,
context: &mut UpdateContext<'_, 'gc, '_>,
_display_object: DisplayObject<'gc>,
_init_object: Option<Object<'gc>>,
_instantiated_from_avm: bool,
run_frame: bool,
) {
if run_frame {
self.run_frame(context);
}
}
/// Return the version of the SWF that created this movie clip.

View File

@ -165,7 +165,7 @@ impl<'gc> Button<'gc> {
self.set_first_child(context.gc_context, Some(child));
}
// Initialize child.
child.post_instantiation(context, child, None, false);
child.post_instantiation(context, child, None, false, false);
child.run_frame(context);
self.0
.write(context.gc_context)
@ -193,6 +193,7 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
display_object: DisplayObject<'gc>,
_init_object: Option<Object<'gc>>,
_instantiated_from_avm: bool,
run_frame: bool,
) {
self.set_default_instance_name(context);
@ -204,6 +205,10 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
Some(context.system_prototypes.button),
);
mc.object = Some(object.into());
if run_frame {
self.run_frame(context);
}
}
}
@ -248,7 +253,7 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
drop(read);
for (child, depth) in new_children {
child.post_instantiation(context, child, None, false);
child.post_instantiation(context, child, None, false, false);
self.0
.write(context.gc_context)
.hit_area

View File

@ -848,6 +848,7 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
display_object: DisplayObject<'gc>,
_init_object: Option<Object<'gc>>,
_instantiated_from_avm: bool,
run_frame: bool,
) {
self.set_default_instance_name(context);
@ -894,6 +895,10 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
self.bind_text_field_variables(activation);
},
);
if run_frame {
self.run_frame(context);
}
}
fn object(&self) -> Value<'gc> {

View File

@ -781,7 +781,7 @@ impl<'gc> MovieClip<'gc> {
}
// Run first frame.
child.apply_place_object(context.gc_context, place_object);
child.post_instantiation(context, child, None, false);
child.post_instantiation(context, child, None, false, false);
child.run_frame(context);
}
Some(child)
@ -1127,6 +1127,7 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
display_object: DisplayObject<'gc>,
init_object: Option<Object<'gc>>,
instantiated_from_avm: bool,
run_frame: bool,
) {
self.set_default_instance_name(context);
@ -1164,6 +1165,9 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
}
}
self.0.write(activation.context.gc_context).object = Some(object);
if run_frame {
self.run_frame(&mut activation.context);
}
let _ = constructor.construct_on_existing(&mut activation, object, &[]);
}
@ -1213,6 +1217,10 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
);
}
if run_frame {
self.run_frame(context);
}
// If this text field has a variable set, initialize text field binding.
Avm1::run_with_stack_frame_for_display_object(
(*self).into(),

View File

@ -437,6 +437,8 @@ impl<'gc> Loader<'gc> {
.unwrap()
.replace_with_movie(uc.gc_context, None);
dbg!("movie_loader 440");
if let Some(broadcaster) = broadcaster {
Avm1::run_stack_frame_for_method(
clip,
@ -491,7 +493,7 @@ impl<'gc> Loader<'gc> {
.expect("Attempted to load movie into not movie clip");
mc.replace_with_movie(uc.gc_context, Some(movie.clone()));
mc.post_instantiation(uc, clip, None, false);
mc.post_instantiation(uc, clip, None, false, false);
let mut morph_shapes = fnv::FnvHashMap::default();
mc.preload(uc, &mut morph_shapes);

View File

@ -310,7 +310,7 @@ impl Player {
let root: DisplayObject =
MovieClip::from_movie(context.gc_context, context.swf.clone()).into();
root.set_depth(context.gc_context, 0);
root.post_instantiation(context, root, None, false);
root.post_instantiation(context, root, None, false, false);
root.set_name(context.gc_context, "");
context.levels.insert(0, root);