From 08fed6aeaa78e8bad3031129bafa87fdf3e8e6ca Mon Sep 17 00:00:00 2001 From: David Wendt Date: Tue, 27 Dec 2022 21:59:03 -0500 Subject: [PATCH] core: Don't attempt to set properties on parents after construction unless the child has an explicit name. This already was implemented, but the prior commits broke it. --- core/src/display_object.rs | 51 +++++++++++++++++++++------ core/src/display_object/movie_clip.rs | 1 + 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 016955f59..941703191 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -481,6 +481,14 @@ impl<'gc> DisplayObjectBase<'gc> { self.flags.set(DisplayObjectFlags::HAS_SCROLL_RECT, value); } + fn has_explicit_name(&self) -> bool { + self.flags.contains(DisplayObjectFlags::HAS_EXPLICIT_NAME) + } + + fn set_has_explicit_name(&mut self, value: bool) { + self.flags.set(DisplayObjectFlags::HAS_EXPLICIT_NAME, value); + } + fn masker(&self) -> Option> { self.masker } @@ -1240,6 +1248,24 @@ pub trait TDisplayObject<'gc>: .set_instantiated_by_timeline(value); } + /// Whether this display object was placed by a SWF tag with an explicit + /// name. + /// + /// When this flag is set, the object will attempt to set a dynamic property + /// on the parent with the same name as itself. + fn has_explicit_name(&self) -> bool { + self.base().has_explicit_name() + } + + /// Sets whether this display object was placed by a SWF tag with an + /// explicit name. + /// + /// When this flag is set, the object will attempt to set a dynamic property + /// on the parent with the same name as itself. + fn set_has_explicit_name(&self, gc_context: MutationContext<'gc, '_>, value: bool) { + self.base_mut(gc_context).set_has_explicit_name(value); + } + /// Run any start-of-frame actions for this display object. /// /// When fired on `Stage`, this also emits the AVM2 `enterFrame` broadcast. @@ -1286,16 +1312,18 @@ pub trait TDisplayObject<'gc>: //TODO: Don't report missing property errors. //TODO: Don't attempt to set properties if object was placed without a name. - if let Some(Avm2Value::Object(mut p)) = self.parent().map(|p| p.object2()) { - if let Avm2Value::Object(c) = self.object2() { - let name = Avm2Multiname::public(self.name()); - let mut activation = Avm2Activation::from_nothing(context.reborrow()); - if let Err(e) = p.init_property(&name, c.into(), &mut activation) { - log::error!( - "Got error when setting AVM2 child named \"{}\": {}", - &self.name(), - e - ); + if self.has_explicit_name() { + if let Some(Avm2Value::Object(mut p)) = self.parent().map(|p| p.object2()) { + if let Avm2Value::Object(c) = self.object2() { + let name = Avm2Multiname::public(self.name()); + let mut activation = Avm2Activation::from_nothing(context.reborrow()); + if let Err(e) = p.init_property(&name, c.into(), &mut activation) { + log::error!( + "Got error when setting AVM2 child named \"{}\": {}", + &self.name(), + e + ); + } } } } @@ -1762,6 +1790,9 @@ bitflags! { /// Whether this object has a scroll rectangle applied. const HAS_SCROLL_RECT = 1 << 9; + + /// Whether this object has an explicit name. + const HAS_EXPLICIT_NAME = 1 << 10; } } diff --git a/core/src/display_object/movie_clip.rs b/core/src/display_object/movie_clip.rs index aa8e39a5f..6fdbafd95 100644 --- a/core/src/display_object/movie_clip.rs +++ b/core/src/display_object/movie_clip.rs @@ -1466,6 +1466,7 @@ impl<'gc> MovieClip<'gc> { context.gc_context, AvmString::new_utf8(context.gc_context, name), ); + child.set_has_explicit_name(context.gc_context, true); } if let Some(clip_depth) = place_object.clip_depth { child.set_clip_depth(context.gc_context, clip_depth.into());