diff --git a/core/src/avm2/globals.rs b/core/src/avm2/globals.rs index 23162d103..753c0ea1c 100644 --- a/core/src/avm2/globals.rs +++ b/core/src/avm2/globals.rs @@ -122,6 +122,7 @@ pub struct SystemPrototypes<'gc> { pub bitmapdata: Object<'gc>, pub date: Object<'gc>, pub qname: Object<'gc>, + pub sharedobject: Object<'gc>, } impl<'gc> SystemPrototypes<'gc> { @@ -178,6 +179,7 @@ impl<'gc> SystemPrototypes<'gc> { bitmapdata: empty, date: empty, qname: empty, + sharedobject: empty, } } } @@ -225,6 +227,7 @@ pub struct SystemClasses<'gc> { pub bitmapdata: ClassObject<'gc>, pub date: ClassObject<'gc>, pub qname: ClassObject<'gc>, + pub sharedobject: ClassObject<'gc>, } impl<'gc> SystemClasses<'gc> { @@ -277,6 +280,7 @@ impl<'gc> SystemClasses<'gc> { bitmapdata: object, date: object, qname: object, + sharedobject: object, } } } @@ -804,6 +808,14 @@ pub fn load_player_globals<'gc>( script ); + // package `flash.net` + avm2_system_class!( + sharedobject, + activation, + flash::net::sharedobject::create_class(mc), + script + ); + // package `flash.text` avm2_system_class!( textfield, diff --git a/core/src/avm2/globals/flash.rs b/core/src/avm2/globals/flash.rs index c2f8b2715..0e80447ba 100644 --- a/core/src/avm2/globals/flash.rs +++ b/core/src/avm2/globals/flash.rs @@ -5,6 +5,7 @@ pub mod display; pub mod events; pub mod geom; pub mod media; +pub mod net; pub mod system; pub mod text; pub mod utils; diff --git a/core/src/avm2/globals/flash/net.rs b/core/src/avm2/globals/flash/net.rs new file mode 100644 index 000000000..c4f3790a9 --- /dev/null +++ b/core/src/avm2/globals/flash/net.rs @@ -0,0 +1,3 @@ +//! `flash.net` namespace + +pub mod sharedobject; diff --git a/core/src/avm2/globals/flash/net/sharedobject.rs b/core/src/avm2/globals/flash/net/sharedobject.rs new file mode 100644 index 000000000..f06f0289e --- /dev/null +++ b/core/src/avm2/globals/flash/net/sharedobject.rs @@ -0,0 +1,89 @@ +//! `flash.net.SharedObject` builtin/prototype + +use crate::avm2::class::{Class, ClassAttributes}; +use crate::avm2::method::{Method, NativeMethodImpl}; +use crate::avm2::object::TObject; +use crate::avm2::traits::Trait; +use crate::avm2::{Activation, Error, Namespace, Object, QName, Value}; +use gc_arena::{GcCell, MutationContext}; + +fn instance_init<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(mut this) = this { + activation.super_init(this, &[])?; + + let data = activation + .context + .avm2 + .classes() + .object + .construct(activation, &[])?; + this.set_property( + this, + &QName::new(Namespace::public(), "data").into(), + data.into(), + activation, + )?; + } + + Ok(Value::Undefined) +} + +fn class_init<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + _this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + Ok(Value::Undefined) +} + +fn get_local<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + _this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + log::warn!("SharedObject.getLocal not implemented"); + let class = activation.context.avm2.classes().sharedobject; + let new_shared_object = class.construct(activation, &[])?; + + Ok(new_shared_object.into()) +} + +fn flush<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + _this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + log::warn!("SharedObject.flush not implemented"); + Ok(Value::Undefined) +} + +/// Construct `SharedObject`'s class. +pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { + let class = Class::new( + QName::new(Namespace::package("flash.net"), "SharedObject"), + Some(QName::new(Namespace::package("flash.events"), "EventDispatcher").into()), + Method::from_builtin(instance_init, "", mc), + Method::from_builtin(class_init, "", mc), + mc, + ); + + let mut write = class.write(mc); + write.set_attributes(ClassAttributes::SEALED); + + write.define_instance_trait(Trait::from_slot( + QName::new(Namespace::public(), "data"), + QName::new(Namespace::public(), "Object").into(), + None, + )); + + const PUBLIC_CLASS_METHODS: &[(&str, NativeMethodImpl)] = &[("getLocal", get_local)]; + write.define_public_builtin_class_methods(mc, PUBLIC_CLASS_METHODS); + + const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("flush", flush)]; + write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS); + class +}