diff --git a/core/src/avm2/globals.rs b/core/src/avm2/globals.rs index bcd4d4922..f0d783e59 100644 --- a/core/src/avm2/globals.rs +++ b/core/src/avm2/globals.rs @@ -1,6 +1,6 @@ //! Global scope built-ins -use crate::avm2::function::FunctionObject; +use crate::avm2::function::{FunctionObject, NativeFunction}; use crate::avm2::names::{Namespace, QName}; use crate::avm2::object::{Object, TObject}; use crate::avm2::script_object::ScriptObject; @@ -18,6 +18,26 @@ pub struct SystemPrototypes<'gc> { pub function: Object<'gc>, } +fn class<'gc>( + mc: MutationContext<'gc, '_>, + mut global_scope: Object<'gc>, + package: &str, + name: &str, + constr: NativeFunction<'gc>, + proto: Object<'gc>, + fn_proto: Object<'gc>, +) { + global_scope + .install_dynamic_property( + mc, + QName::new(Namespace::package(package), name), + FunctionObject::from_builtin_constr(mc, constr, proto, fn_proto) + .unwrap() + .into(), + ) + .unwrap(); +} + /// Construct a new global scope. /// /// This function returns both the global scope object, as well as all builtin @@ -25,76 +45,108 @@ pub struct SystemPrototypes<'gc> { pub fn construct_global_scope<'gc>( mc: MutationContext<'gc, '_>, ) -> (Object<'gc>, SystemPrototypes<'gc>) { - let mut global_scope = ScriptObject::bare_object(mc); + let gs = ScriptObject::bare_object(mc); + // public / root package let object_proto = ScriptObject::bare_object(mc); - let function_proto = function::create_proto(mc, object_proto); - let sprite_proto = flash::display::sprite::create_proto(mc, object_proto, function_proto); - let movieclip_proto = flash::display::movieclip::create_proto(mc, sprite_proto, function_proto); + let fn_proto = function::create_proto(mc, object_proto); - object::fill_proto(mc, object_proto, function_proto); + object::fill_proto(mc, object_proto, fn_proto); + + class( + mc, + gs, + "", + "Object", + object::constructor, + object_proto, + fn_proto, + ); + class( + mc, + gs, + "", + "Function", + function::constructor, + fn_proto, + fn_proto, + ); + + // package `flash.events` + let eventdispatcher_proto = + flash::events::eventdispatcher::create_proto(mc, object_proto, fn_proto); + + class( + mc, + gs, + "flash.events", + "EventDispatcher", + flash::events::eventdispatcher::constructor, + eventdispatcher_proto, + fn_proto, + ); + + // package `flash.display` + let displayobject_proto = + flash::display::displayobject::create_proto(mc, eventdispatcher_proto, fn_proto); + let interactiveobject_proto = + flash::display::interactiveobject::create_proto(mc, displayobject_proto, fn_proto); + let displayobjectcontainer_proto = + flash::display::displayobjectcontainer::create_proto(mc, interactiveobject_proto, fn_proto); + let sprite_proto = + flash::display::sprite::create_proto(mc, displayobjectcontainer_proto, fn_proto); + let movieclip_proto = flash::display::movieclip::create_proto(mc, sprite_proto, fn_proto); + + class( + mc, + gs, + "flash.display", + "DisplayObject", + flash::display::displayobject::constructor, + displayobject_proto, + fn_proto, + ); + class( + mc, + gs, + "flash.display", + "InteractiveObject", + flash::display::interactiveobject::constructor, + interactiveobject_proto, + fn_proto, + ); + class( + mc, + gs, + "flash.display", + "DisplayObjectContainer", + flash::display::displayobjectcontainer::constructor, + sprite_proto, + fn_proto, + ); + class( + mc, + gs, + "flash.display", + "Sprite", + flash::display::sprite::constructor, + sprite_proto, + fn_proto, + ); + class( + mc, + gs, + "flash.display", + "MovieClip", + flash::display::movieclip::constructor, + movieclip_proto, + fn_proto, + ); let system_prototypes = SystemPrototypes { object: object_proto, - function: function_proto, + function: fn_proto, }; - global_scope - .install_dynamic_property( - mc, - QName::new(Namespace::public_namespace(), "Object"), - FunctionObject::from_builtin_constr( - mc, - object::constructor, - object_proto, - function_proto, - ) - .unwrap() - .into(), - ) - .unwrap(); - global_scope - .install_dynamic_property( - mc, - QName::new(Namespace::public_namespace(), "Function"), - FunctionObject::from_builtin_constr( - mc, - function::constructor, - function_proto, - function_proto, - ) - .unwrap() - .into(), - ) - .unwrap(); - global_scope - .install_dynamic_property( - mc, - QName::new(Namespace::package("flash.display"), "Sprite"), - FunctionObject::from_builtin_constr( - mc, - flash::display::sprite::constructor, - sprite_proto, - function_proto, - ) - .unwrap() - .into(), - ) - .unwrap(); - global_scope - .install_dynamic_property( - mc, - QName::new(Namespace::package("flash.display"), "MovieClip"), - FunctionObject::from_builtin_constr( - mc, - flash::display::movieclip::constructor, - movieclip_proto, - function_proto, - ) - .unwrap() - .into(), - ) - .unwrap(); - - (global_scope, system_prototypes) + (gs, system_prototypes) } diff --git a/core/src/avm2/globals/flash.rs b/core/src/avm2/globals/flash.rs index ba16b1402..18e6d2b4e 100644 --- a/core/src/avm2/globals/flash.rs +++ b/core/src/avm2/globals/flash.rs @@ -1,3 +1,4 @@ //! `flash` namespace pub mod display; +pub mod events; diff --git a/core/src/avm2/globals/flash/display.rs b/core/src/avm2/globals/flash/display.rs index 40c0fbc01..c0dc34135 100644 --- a/core/src/avm2/globals/flash/display.rs +++ b/core/src/avm2/globals/flash/display.rs @@ -1,4 +1,7 @@ //! `flash.display` namespace +pub mod displayobject; +pub mod displayobjectcontainer; +pub mod interactiveobject; pub mod movieclip; pub mod sprite; diff --git a/core/src/avm2/globals/flash/display/displayobject.rs b/core/src/avm2/globals/flash/display/displayobject.rs new file mode 100644 index 000000000..cf8192ef0 --- /dev/null +++ b/core/src/avm2/globals/flash/display/displayobject.rs @@ -0,0 +1,29 @@ +//! `flash.display.DisplayObject` builtin/prototype + +use crate::avm2::object::Object; +use crate::avm2::return_value::ReturnValue; +use crate::avm2::script_object::ScriptObject; +use crate::avm2::value::Value; +use crate::avm2::{Avm2, Error}; +use crate::context::UpdateContext; +use gc_arena::MutationContext; + +/// Implements `flash.display.DisplayObject`'s constructor. +pub fn constructor<'gc>( + _avm: &mut Avm2<'gc>, + _action_context: &mut UpdateContext<'_, 'gc, '_>, + _this: Object<'gc>, + _args: &[Value<'gc>], +) -> Result, Error> { + Ok(Value::Undefined.into()) +} + +/// Construct `DisplayObject.prototype`. +pub fn create_proto<'gc>( + mc: MutationContext<'gc, '_>, + super_proto: Object<'gc>, + _fn_proto: Object<'gc>, +) -> Object<'gc> { + // TODO: Use `StageObject` here. + ScriptObject::object(mc, super_proto) +} diff --git a/core/src/avm2/globals/flash/display/displayobjectcontainer.rs b/core/src/avm2/globals/flash/display/displayobjectcontainer.rs new file mode 100644 index 000000000..bd63e1f94 --- /dev/null +++ b/core/src/avm2/globals/flash/display/displayobjectcontainer.rs @@ -0,0 +1,29 @@ +//! `flash.display.DisplayObjectContainer` builtin/prototype + +use crate::avm2::object::Object; +use crate::avm2::return_value::ReturnValue; +use crate::avm2::script_object::ScriptObject; +use crate::avm2::value::Value; +use crate::avm2::{Avm2, Error}; +use crate::context::UpdateContext; +use gc_arena::MutationContext; + +/// Implements `flash.display.DisplayObjectContainer`'s constructor. +pub fn constructor<'gc>( + _avm: &mut Avm2<'gc>, + _action_context: &mut UpdateContext<'_, 'gc, '_>, + _this: Object<'gc>, + _args: &[Value<'gc>], +) -> Result, Error> { + Ok(Value::Undefined.into()) +} + +/// Construct `DisplayObjectContainer.prototype`. +pub fn create_proto<'gc>( + mc: MutationContext<'gc, '_>, + super_proto: Object<'gc>, + _fn_proto: Object<'gc>, +) -> Object<'gc> { + // TODO: Use `StageObject` here. + ScriptObject::object(mc, super_proto) +} diff --git a/core/src/avm2/globals/flash/display/interactiveobject.rs b/core/src/avm2/globals/flash/display/interactiveobject.rs new file mode 100644 index 000000000..4500d5e3a --- /dev/null +++ b/core/src/avm2/globals/flash/display/interactiveobject.rs @@ -0,0 +1,29 @@ +//! `flash.display.InteractiveObject` builtin/prototype + +use crate::avm2::object::Object; +use crate::avm2::return_value::ReturnValue; +use crate::avm2::script_object::ScriptObject; +use crate::avm2::value::Value; +use crate::avm2::{Avm2, Error}; +use crate::context::UpdateContext; +use gc_arena::MutationContext; + +/// Implements `flash.display.InteractiveObject`'s constructor. +pub fn constructor<'gc>( + _avm: &mut Avm2<'gc>, + _action_context: &mut UpdateContext<'_, 'gc, '_>, + _this: Object<'gc>, + _args: &[Value<'gc>], +) -> Result, Error> { + Ok(Value::Undefined.into()) +} + +/// Construct `InteractiveObject.prototype`. +pub fn create_proto<'gc>( + mc: MutationContext<'gc, '_>, + super_proto: Object<'gc>, + _fn_proto: Object<'gc>, +) -> Object<'gc> { + // TODO: Use `StageObject` here. + ScriptObject::object(mc, super_proto) +} diff --git a/core/src/avm2/globals/flash/events.rs b/core/src/avm2/globals/flash/events.rs new file mode 100644 index 000000000..afd4e106b --- /dev/null +++ b/core/src/avm2/globals/flash/events.rs @@ -0,0 +1,3 @@ +//! `flash.events` namespace + +pub mod eventdispatcher; diff --git a/core/src/avm2/globals/flash/events/eventdispatcher.rs b/core/src/avm2/globals/flash/events/eventdispatcher.rs new file mode 100644 index 000000000..10ec93ddd --- /dev/null +++ b/core/src/avm2/globals/flash/events/eventdispatcher.rs @@ -0,0 +1,29 @@ +//! `flash.events.EventDispatcher` builtin/prototype + +use crate::avm2::object::Object; +use crate::avm2::return_value::ReturnValue; +use crate::avm2::script_object::ScriptObject; +use crate::avm2::value::Value; +use crate::avm2::{Avm2, Error}; +use crate::context::UpdateContext; +use gc_arena::MutationContext; + +/// Implements `flash.events.EventDispatcher`'s constructor. +pub fn constructor<'gc>( + _avm: &mut Avm2<'gc>, + _action_context: &mut UpdateContext<'_, 'gc, '_>, + _this: Object<'gc>, + _args: &[Value<'gc>], +) -> Result, Error> { + Ok(Value::Undefined.into()) +} + +/// Construct `EventDispatcher.prototype`. +pub fn create_proto<'gc>( + mc: MutationContext<'gc, '_>, + super_proto: Object<'gc>, + _fn_proto: Object<'gc>, +) -> Object<'gc> { + // TODO: Use `StageObject` here. + ScriptObject::object(mc, super_proto) +}