avm2: Implement `getChildByName`

This commit is contained in:
David Wendt 2020-10-18 00:25:07 -04:00 committed by Mike Welsh
parent 827567bb58
commit f748576927
5 changed files with 34 additions and 0 deletions

View File

@ -54,6 +54,31 @@ pub fn get_child_at<'gc>(
Ok(Value::Undefined)
}
/// Implements `DisplayObjectContainer.getChildByName`
pub fn get_child_by_name<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(dobj) = this.and_then(|this| this.as_display_object()) {
let name = args
.get(0)
.cloned()
.unwrap_or(Value::Undefined)
.coerce_to_string(activation)?;
let child = dobj.get_child_by_name(&name, false).ok_or_else(|| {
format!(
"RangeError: Display object container has no child with name {}",
name
)
})?;
return Ok(child.object2());
}
Ok(Value::Undefined)
}
/// Construct `DisplayObjectContainer`'s class.
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
let class = Class::new(
@ -73,6 +98,10 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
QName::new(Namespace::public_namespace(), "getChildAt"),
Method::from_builtin(get_child_at),
));
write.define_instance_trait(Trait::from_method(
QName::new(Namespace::public_namespace(), "getChildByName"),
Method::from_builtin(get_child_by_name),
));
class
}

View File

@ -412,6 +412,7 @@ swf_tests! {
(as3_lazyinit, "avm2/lazyinit", 1),
(as3_trace, "avm2/trace", 1),
(as3_displayobjectcontainer_getchildat, "avm2/displayobjectcontainer_getchildat", 1),
(as3_displayobjectcontainer_getchildbyname, "avm2/displayobjectcontainer_getchildbyname", 1),
}
// TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough.

View File

@ -0,0 +1,4 @@
//this.getChildByName("child_clip")
[object ChildClip_1]
//this.getChildByName("child_clip").child_method()
//Child method called