Convert our stub implementations of all non-ECMA classes into `Class`es.
This was surprisingly tricky - due to the need to look up superclasses, class trait instantiation requires an active `Activation` and `UpdateContext`. We can't get those during VM instance creation, since the player needs the VM first before it can give it a context to work with. Ergo, we have to tear the global scope initialization in two. At the first possible moment, the player calls a new `load_player_globals` method that initializes all class traits in global scope.
This commit is contained in:
parent
6f284f60eb
commit
3585cf983b
|
@ -77,6 +77,11 @@ impl<'gc> Avm2<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_player_globals(context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error> {
|
||||
let mut activation = Activation::from_nothing(context.reborrow());
|
||||
globals::load_player_globals(&mut activation)
|
||||
}
|
||||
|
||||
/// Return the current set of system prototypes.
|
||||
pub fn prototypes(&self) -> &SystemPrototypes<'gc> {
|
||||
&self.system_prototypes
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
//! Global scope built-ins
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::method::NativeMethod;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::{FunctionObject, ScriptObject};
|
||||
use crate::avm2::object::{Object, TObject};
|
||||
use crate::avm2::object::{FunctionObject, Object, ScriptObject, TObject};
|
||||
use crate::avm2::r#trait::Trait;
|
||||
use crate::avm2::string::AvmString;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use gc_arena::{Collect, MutationContext};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::f64::NAN;
|
||||
|
||||
mod boolean;
|
||||
|
@ -67,8 +68,8 @@ fn function<'gc>(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Add a class builtin to the global scope.
|
||||
fn class<'gc>(
|
||||
/// Add an ES3-style builtin to the global scope.
|
||||
fn oldstyle_class<'gc>(
|
||||
mc: MutationContext<'gc, '_>,
|
||||
mut global_scope: Object<'gc>,
|
||||
package: impl Into<AvmString<'gc>>,
|
||||
|
@ -88,6 +89,17 @@ fn class<'gc>(
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
/// Add a class builtin to the global scope.
|
||||
fn class<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
mut global_scope: Object<'gc>,
|
||||
class_def: GcCell<'gc, Class<'gc>>,
|
||||
) -> Result<(), Error> {
|
||||
let class_trait = Trait::from_class(class_def);
|
||||
|
||||
global_scope.install_trait(activation, class_trait, global_scope)
|
||||
}
|
||||
|
||||
/// Add a builtin constant to the global scope.
|
||||
fn constant<'gc>(
|
||||
mc: MutationContext<'gc, '_>,
|
||||
|
@ -103,6 +115,14 @@ fn constant<'gc>(
|
|||
///
|
||||
/// This function returns both the global scope object, as well as all builtin
|
||||
/// prototypes that other parts of the VM will need to use.
|
||||
///
|
||||
/// Due to a limitation of our type system and our garbage collector, the
|
||||
/// player needs a valid `Avm2` but cannot provide us an `UpdateContext` yet.
|
||||
/// As a result, global scope initialization is split into an "oldstyle phase"
|
||||
/// and a "player-globals phase". This is the former phase, where we initialize
|
||||
/// as much as we can without an `UpdateContext`. Note that not all
|
||||
/// `SystemPrototypes` will be necessarily valid at this point in time, and
|
||||
/// using them right away will result in objects of the wrong type.
|
||||
pub fn construct_global_scope<'gc>(
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> (Object<'gc>, SystemPrototypes<'gc>) {
|
||||
|
@ -121,7 +141,7 @@ pub fn construct_global_scope<'gc>(
|
|||
|
||||
object::fill_proto(mc, object_proto, fn_proto);
|
||||
|
||||
class(
|
||||
oldstyle_class(
|
||||
mc,
|
||||
gs,
|
||||
"",
|
||||
|
@ -130,7 +150,7 @@ pub fn construct_global_scope<'gc>(
|
|||
object_proto,
|
||||
fn_proto,
|
||||
);
|
||||
class(
|
||||
oldstyle_class(
|
||||
mc,
|
||||
gs,
|
||||
"",
|
||||
|
@ -139,7 +159,7 @@ pub fn construct_global_scope<'gc>(
|
|||
fn_proto,
|
||||
fn_proto,
|
||||
);
|
||||
class(
|
||||
oldstyle_class(
|
||||
mc,
|
||||
gs,
|
||||
"",
|
||||
|
@ -148,7 +168,7 @@ pub fn construct_global_scope<'gc>(
|
|||
class_proto,
|
||||
fn_proto,
|
||||
);
|
||||
class(
|
||||
oldstyle_class(
|
||||
mc,
|
||||
gs,
|
||||
"",
|
||||
|
@ -157,7 +177,7 @@ pub fn construct_global_scope<'gc>(
|
|||
string_proto,
|
||||
fn_proto,
|
||||
);
|
||||
class(
|
||||
oldstyle_class(
|
||||
mc,
|
||||
gs,
|
||||
"",
|
||||
|
@ -166,7 +186,7 @@ pub fn construct_global_scope<'gc>(
|
|||
boolean_proto,
|
||||
fn_proto,
|
||||
);
|
||||
class(
|
||||
oldstyle_class(
|
||||
mc,
|
||||
gs,
|
||||
"",
|
||||
|
@ -175,9 +195,9 @@ pub fn construct_global_scope<'gc>(
|
|||
number_proto,
|
||||
fn_proto,
|
||||
);
|
||||
class(mc, gs, "", "int", int::constructor, int_proto, fn_proto);
|
||||
class(mc, gs, "", "uint", uint::constructor, uint_proto, fn_proto);
|
||||
class(
|
||||
oldstyle_class(mc, gs, "", "int", int::constructor, int_proto, fn_proto);
|
||||
oldstyle_class(mc, gs, "", "uint", uint::constructor, uint_proto, fn_proto);
|
||||
oldstyle_class(
|
||||
mc,
|
||||
gs,
|
||||
"",
|
||||
|
@ -192,77 +212,6 @@ pub fn construct_global_scope<'gc>(
|
|||
constant(mc, gs, "", "NaN", NAN.into());
|
||||
constant(mc, gs, "", "Infinity", f64::INFINITY.into());
|
||||
|
||||
// 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: fn_proto,
|
||||
|
@ -277,3 +226,49 @@ pub fn construct_global_scope<'gc>(
|
|||
|
||||
(gs, system_prototypes)
|
||||
}
|
||||
|
||||
/// Initialize all remaining builtin classes.
|
||||
///
|
||||
/// Due to a limitation of our type system and our garbage collector, the
|
||||
/// player needs a valid `Avm2` but cannot provide us an `UpdateContext` yet.
|
||||
/// As a result, global scope initialization is split into an "oldstyle phase"
|
||||
/// and a "player-globals phase". This is the latter phase.
|
||||
pub fn load_player_globals<'gc>(activation: &mut Activation<'_, 'gc, '_>) -> Result<(), Error> {
|
||||
let gs = activation.avm2().globals();
|
||||
|
||||
// package `flash.events`
|
||||
class(
|
||||
activation,
|
||||
gs,
|
||||
flash::events::eventdispatcher::create_class(activation.context.gc_context),
|
||||
)?;
|
||||
|
||||
// package `flash.display`
|
||||
class(
|
||||
activation,
|
||||
gs,
|
||||
flash::display::displayobject::create_class(activation.context.gc_context),
|
||||
)?;
|
||||
class(
|
||||
activation,
|
||||
gs,
|
||||
flash::display::interactiveobject::create_class(activation.context.gc_context),
|
||||
)?;
|
||||
class(
|
||||
activation,
|
||||
gs,
|
||||
flash::display::displayobjectcontainer::create_class(activation.context.gc_context),
|
||||
)?;
|
||||
class(
|
||||
activation,
|
||||
gs,
|
||||
flash::display::sprite::create_class(activation.context.gc_context),
|
||||
)?;
|
||||
class(
|
||||
activation,
|
||||
gs,
|
||||
flash::display::movieclip::create_class(activation.context.gc_context),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
//! `flash.display.DisplayObject` builtin/prototype
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::{Object, ScriptObject};
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::method::Method;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::Object;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use gc_arena::MutationContext;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
/// Implements `flash.display.DisplayObject`'s constructor.
|
||||
pub fn constructor<'gc>(
|
||||
/// Implements `flash.display.DisplayObject`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -15,12 +18,22 @@ pub fn constructor<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
/// Implements `flash.display.DisplayObject`'s class constructor.
|
||||
pub fn class_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `DisplayObject`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "DisplayObject"),
|
||||
Some(QName::new(Namespace::package("flash.events"), "EventDispatcher").into()),
|
||||
Method::from_builtin(instance_init),
|
||||
Method::from_builtin(class_init),
|
||||
mc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
//! `flash.display.DisplayObjectContainer` builtin/prototype
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::{Object, ScriptObject};
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::method::Method;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::Object;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use gc_arena::MutationContext;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
/// Implements `flash.display.DisplayObjectContainer`'s constructor.
|
||||
pub fn constructor<'gc>(
|
||||
/// Implements `flash.display.DisplayObjectContainer`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -15,12 +18,25 @@ pub fn constructor<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
/// Implements `flash.display.DisplayObjectContainer`'s class constructor.
|
||||
pub fn class_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `DisplayObjectContainer`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
Class::new(
|
||||
QName::new(
|
||||
Namespace::package("flash.display"),
|
||||
"DisplayObjectContainer",
|
||||
),
|
||||
Some(QName::new(Namespace::package("flash.display"), "InteractiveObject").into()),
|
||||
Method::from_builtin(instance_init),
|
||||
Method::from_builtin(class_init),
|
||||
mc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
//! `flash.display.InteractiveObject` builtin/prototype
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::{Object, ScriptObject};
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::method::Method;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::Object;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use gc_arena::MutationContext;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
/// Implements `flash.display.InteractiveObject`'s constructor.
|
||||
pub fn constructor<'gc>(
|
||||
/// Implements `flash.display.InteractiveObject`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -15,12 +18,22 @@ pub fn constructor<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
/// Implements `flash.display.InteractiveObject`'s class constructor.
|
||||
pub fn class_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `InteractiveObject`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "InteractiveObject"),
|
||||
Some(QName::new(Namespace::package("flash.display"), "DisplayObject").into()),
|
||||
Method::from_builtin(instance_init),
|
||||
Method::from_builtin(class_init),
|
||||
mc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
//! `flash.display.MovieClip` builtin/prototype
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::{Object, ScriptObject};
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::method::Method;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::Object;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use gc_arena::MutationContext;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
/// Implements `flash.display.MovieClip`'s constructor.
|
||||
pub fn constructor<'gc>(
|
||||
/// Implements `flash.display.MovieClip`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -15,12 +18,22 @@ pub fn constructor<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `MovieClip.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)
|
||||
/// Implements `flash.display.MovieClip`'s class constructor.
|
||||
pub fn class_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `MovieClip`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "MovieClip"),
|
||||
Some(QName::new(Namespace::package("flash.display"), "Sprite").into()),
|
||||
Method::from_builtin(instance_init),
|
||||
Method::from_builtin(class_init),
|
||||
mc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
//! `flash.display.Sprite` builtin/prototype
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::{Object, ScriptObject};
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::method::Method;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::Object;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use gc_arena::MutationContext;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
/// Implements `flash.display.Sprite`'s constructor.
|
||||
pub fn constructor<'gc>(
|
||||
/// Implements `flash.display.Sprite`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -15,12 +18,28 @@ pub fn constructor<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `Sprite.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)
|
||||
/// Implements `flash.display.Sprite`'s class constructor.
|
||||
pub fn class_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `Sprite`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "Sprite"),
|
||||
Some(
|
||||
QName::new(
|
||||
Namespace::package("flash.display"),
|
||||
"DisplayObjectContainer",
|
||||
)
|
||||
.into(),
|
||||
),
|
||||
Method::from_builtin(instance_init),
|
||||
Method::from_builtin(class_init),
|
||||
mc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
//! `flash.events.EventDispatcher` builtin/prototype
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::{Object, ScriptObject};
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::method::Method;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::Object;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use gc_arena::MutationContext;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
/// Implements `flash.events.EventDispatcher`'s constructor.
|
||||
pub fn constructor<'gc>(
|
||||
/// Implements `flash.events.EventDispatcher`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -15,12 +18,22 @@ pub fn constructor<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
/// Implements `flash.events.EventDispatcher`'s class constructor.
|
||||
pub fn class_init<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `EventDispatcher`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
Class::new(
|
||||
QName::new(Namespace::package("flash.events"), "EventDispatcher"),
|
||||
Some(QName::new(Namespace::public_namespace(), "Object").into()),
|
||||
Method::from_builtin(instance_init),
|
||||
Method::from_builtin(class_init),
|
||||
mc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -345,6 +345,10 @@ impl Player {
|
|||
AvmString::new(activation.context.gc_context, version_string).into(),
|
||||
EnumSet::empty(),
|
||||
);
|
||||
|
||||
drop(activation);
|
||||
|
||||
Avm2::load_player_globals(context).unwrap();
|
||||
});
|
||||
|
||||
self.build_matrices();
|
||||
|
|
Loading…
Reference in New Issue