Add the entire class hierarchy of `MovieClip` and `Sprite`.

This commit is contained in:
David Wendt 2020-02-22 19:39:12 -05:00
parent f6e2ca1fe5
commit a557867c71
8 changed files with 240 additions and 65 deletions

View File

@ -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)
}

View File

@ -1,3 +1,4 @@
//! `flash` namespace
pub mod display;
pub mod events;

View File

@ -1,4 +1,7 @@
//! `flash.display` namespace
pub mod displayobject;
pub mod displayobjectcontainer;
pub mod interactiveobject;
pub mod movieclip;
pub mod sprite;

View File

@ -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<ReturnValue<'gc>, 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)
}

View File

@ -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<ReturnValue<'gc>, 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)
}

View File

@ -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<ReturnValue<'gc>, 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)
}

View File

@ -0,0 +1,3 @@
//! `flash.events` namespace
pub mod eventdispatcher;

View File

@ -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<ReturnValue<'gc>, 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)
}