diff --git a/core/src/avm2/globals.rs b/core/src/avm2/globals.rs index 2a349aedd..4e3b38ec7 100644 --- a/core/src/avm2/globals.rs +++ b/core/src/avm2/globals.rs @@ -377,6 +377,12 @@ pub fn load_player_globals<'gc>(activation: &mut Activation<'_, 'gc, '_>) -> Res flash::display::movieclip::create_class(activation.context.gc_context), implicit_deriver, )?; + class( + activation, + gs, + flash::display::framelabel::create_class(activation.context.gc_context), + implicit_deriver, + )?; Ok(()) } diff --git a/core/src/avm2/globals/flash/display.rs b/core/src/avm2/globals/flash/display.rs index c0dc34135..74d14eead 100644 --- a/core/src/avm2/globals/flash/display.rs +++ b/core/src/avm2/globals/flash/display.rs @@ -2,6 +2,7 @@ pub mod displayobject; pub mod displayobjectcontainer; +pub mod framelabel; pub mod interactiveobject; pub mod movieclip; pub mod sprite; diff --git a/core/src/avm2/globals/flash/display/framelabel.rs b/core/src/avm2/globals/flash/display/framelabel.rs new file mode 100644 index 000000000..d11c62486 --- /dev/null +++ b/core/src/avm2/globals/flash/display/framelabel.rs @@ -0,0 +1,114 @@ +//! `flash.display.FrameLabel` impl + +use crate::avm2::activation::Activation; +use crate::avm2::class::Class; +use crate::avm2::method::Method; +use crate::avm2::names::{Namespace, QName}; +use crate::avm2::object::{Object, TObject}; +use crate::avm2::traits::Trait; +use crate::avm2::value::Value; +use crate::avm2::Error; +use gc_arena::{GcCell, MutationContext}; + +/// Implements `flash.display.FrameLabel`'s instance constructor. +pub fn instance_init<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + args: &[Value<'gc>], +) -> Result, Error> { + let name = args + .get(0) + .cloned() + .unwrap_or(Value::Undefined) + .coerce_to_string(activation)?; + let frame = args + .get(1) + .cloned() + .unwrap_or(Value::Undefined) + .coerce_to_i32(activation)?; + + if let Some(mut this) = this { + this.set_property( + this, + &QName::new(Namespace::Private("ruffle".into()), "name"), + name.into(), + activation, + )?; + this.set_property( + this, + &QName::new(Namespace::Private("ruffle".into()), "frame"), + frame.into(), + activation, + )?; + } + + Ok(Value::Undefined) +} + +/// Implements `flash.display.FrameLabel`'s class constructor. +pub fn class_init<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + _this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + Ok(Value::Undefined) +} + +/// Implements `FrameLabel.name`. +pub fn name<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(mut this) = this { + return this.get_property( + this, + &QName::new(Namespace::Private("ruffle".into()), "name"), + activation, + ); + } + + Ok(Value::Undefined) +} + +/// Implements `FrameLabel.frame`. +pub fn frame<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(mut this) = this { + return this.get_property( + this, + &QName::new(Namespace::Private("ruffle".into()), "frame"), + activation, + ); + } + + Ok(Value::Undefined) +} + +/// Construct `FrameLabel`'s class. +pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { + let class = Class::new( + QName::new(Namespace::package("flash.display"), "FrameLabel"), + Some(QName::new(Namespace::package("flash.events"), "EventDispatcher").into()), + Method::from_builtin(instance_init), + Method::from_builtin(class_init), + mc, + ); + + let mut write = class.write(mc); + + write.define_instance_trait(Trait::from_getter( + QName::new(Namespace::public_namespace(), "name"), + Method::from_builtin(name), + )); + + write.define_instance_trait(Trait::from_getter( + QName::new(Namespace::public_namespace(), "frame"), + Method::from_builtin(frame), + )); + + class +} diff --git a/core/tests/regression_tests.rs b/core/tests/regression_tests.rs index a1efd6b99..e8a8946e5 100644 --- a/core/tests/regression_tests.rs +++ b/core/tests/regression_tests.rs @@ -393,6 +393,7 @@ swf_tests! { (as3_movieclip_next_frame, "avm2/movieclip_next_frame", 5), (as3_movieclip_prev_scene, "avm2/movieclip_prev_scene", 5), (as3_movieclip_next_scene, "avm2/movieclip_next_scene", 5), + (as3_framelabel_constr, "avm2/framelabel_constr", 5), } // TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough. diff --git a/core/tests/swfs/avm2/framelabel_constr/Test.as b/core/tests/swfs/avm2/framelabel_constr/Test.as new file mode 100644 index 000000000..fb491717a --- /dev/null +++ b/core/tests/swfs/avm2/framelabel_constr/Test.as @@ -0,0 +1,15 @@ +package { + public class Test { + } +} + +import flash.display.FrameLabel; + +trace("//var val = new FrameLabel(\"test\", 123);"); +var val = new FrameLabel("test", 123); + +trace("//val.frame"); +trace(val.frame); + +trace("//val.name"); +trace(val.name); \ No newline at end of file diff --git a/core/tests/swfs/avm2/framelabel_constr/output.txt b/core/tests/swfs/avm2/framelabel_constr/output.txt new file mode 100644 index 000000000..79dfe29c8 --- /dev/null +++ b/core/tests/swfs/avm2/framelabel_constr/output.txt @@ -0,0 +1,5 @@ +//var val = new FrameLabel("test", 123); +//val.frame +123 +//val.name +test diff --git a/core/tests/swfs/avm2/framelabel_constr/test.fla b/core/tests/swfs/avm2/framelabel_constr/test.fla new file mode 100644 index 000000000..b27a5e649 Binary files /dev/null and b/core/tests/swfs/avm2/framelabel_constr/test.fla differ diff --git a/core/tests/swfs/avm2/framelabel_constr/test.swf b/core/tests/swfs/avm2/framelabel_constr/test.swf new file mode 100644 index 000000000..1f77a92f4 Binary files /dev/null and b/core/tests/swfs/avm2/framelabel_constr/test.swf differ