Move AVM1 inside UpdateContext.
This commit is contained in:
parent
14bfbc358f
commit
7c7b019087
|
@ -172,7 +172,6 @@ impl<'gc> Avm1<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut parent_activation = Activation::from_nothing(
|
let mut parent_activation = Activation::from_nothing(
|
||||||
self,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Actions Parent]"),
|
ActivationIdentifier::root("[Actions Parent]"),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -191,9 +190,8 @@ impl<'gc> Avm1<'gc> {
|
||||||
clip_obj,
|
clip_obj,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let constant_pool = parent_activation.avm.constant_pool;
|
let constant_pool = parent_activation.context.avm1.constant_pool;
|
||||||
let mut child_activation = Activation::from_action(
|
let mut child_activation = Activation::from_action(
|
||||||
parent_activation.avm,
|
|
||||||
parent_activation.context,
|
parent_activation.context,
|
||||||
parent_activation.id.child(name),
|
parent_activation.id.child(name),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -234,7 +232,6 @@ impl<'gc> Avm1<'gc> {
|
||||||
Scope::new(global_scope, scope::ScopeClass::Target, clip_obj),
|
Scope::new(global_scope, scope::ScopeClass::Target, clip_obj),
|
||||||
);
|
);
|
||||||
let mut activation = Activation::from_action(
|
let mut activation = Activation::from_action(
|
||||||
self,
|
|
||||||
action_context,
|
action_context,
|
||||||
ActivationIdentifier::root("[Display Object]"),
|
ActivationIdentifier::root("[Display Object]"),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -263,7 +260,6 @@ impl<'gc> Avm1<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut parent_activation = Activation::from_nothing(
|
let mut parent_activation = Activation::from_nothing(
|
||||||
self,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Init Parent]"),
|
ActivationIdentifier::root("[Init Parent]"),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -282,10 +278,9 @@ impl<'gc> Avm1<'gc> {
|
||||||
clip_obj,
|
clip_obj,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
parent_activation.avm.push(Value::Undefined);
|
parent_activation.context.avm1.push(Value::Undefined);
|
||||||
let constant_pool = parent_activation.avm.constant_pool;
|
let constant_pool = parent_activation.context.avm1.constant_pool;
|
||||||
let mut child_activation = Activation::from_action(
|
let mut child_activation = Activation::from_action(
|
||||||
parent_activation.avm,
|
|
||||||
parent_activation.context,
|
parent_activation.context,
|
||||||
parent_activation.id.child("[Init]"),
|
parent_activation.id.child("[Init]"),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -319,7 +314,6 @@ impl<'gc> Avm1<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
self,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root(name.to_owned()),
|
ActivationIdentifier::root(name.to_owned()),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -347,7 +341,6 @@ impl<'gc> Avm1<'gc> {
|
||||||
let global = self.global_object();
|
let global = self.global_object();
|
||||||
|
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
self,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[System Listeners]"),
|
ActivationIdentifier::root("[System Listeners]"),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -448,7 +441,7 @@ pub fn root_error_handler<'gc>(activation: &mut Activation<'_, '_, 'gc, '_>, err
|
||||||
log::error!("{}", error);
|
log::error!("{}", error);
|
||||||
}
|
}
|
||||||
if error.is_halting() {
|
if error.is_halting() {
|
||||||
activation.avm.halt();
|
activation.context.avm1.halt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -249,7 +249,7 @@ impl<'gc> Executable<'gc> {
|
||||||
);
|
);
|
||||||
let arguments = ScriptObject::array(
|
let arguments = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().array),
|
Some(activation.context.avm1.prototypes().array),
|
||||||
);
|
);
|
||||||
arguments.define_value(
|
arguments.define_value(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
@ -311,11 +311,12 @@ impl<'gc> Executable<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut frame = Activation::from_action(
|
let mut frame = Activation::from_action(
|
||||||
activation.avm,
|
|
||||||
activation.context,
|
activation.context,
|
||||||
activation
|
activation.id.function(
|
||||||
.id
|
name,
|
||||||
.function(name, reason, activation.avm.max_recursion_depth())?,
|
reason,
|
||||||
|
activation.context.avm1.max_recursion_depth(),
|
||||||
|
)?,
|
||||||
effective_ver,
|
effective_ver,
|
||||||
child_scope,
|
child_scope,
|
||||||
af.constant_pool,
|
af.constant_pool,
|
||||||
|
@ -369,7 +370,7 @@ impl<'gc> Executable<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if af.preload_global {
|
if af.preload_global {
|
||||||
let global = frame.avm.global_object();
|
let global = frame.context.avm1.global_object();
|
||||||
frame.set_local_register(preload_r, global);
|
frame.set_local_register(preload_r, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ pub fn array_function<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let mut consumed = false;
|
let mut consumed = false;
|
||||||
|
|
||||||
let prototype = activation.avm.prototypes.array;
|
let prototype = activation.context.avm1.prototypes.array;
|
||||||
let array_obj = prototype.create_bare_object(activation, prototype)?;
|
let array_obj = prototype.create_bare_object(activation, prototype)?;
|
||||||
|
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
|
@ -324,7 +324,7 @@ pub fn slice<'gc>(
|
||||||
|
|
||||||
let array = ScriptObject::array(
|
let array = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.array),
|
Some(activation.context.avm1.prototypes.array),
|
||||||
);
|
);
|
||||||
|
|
||||||
if start < end {
|
if start < end {
|
||||||
|
@ -369,7 +369,7 @@ pub fn splice<'gc>(
|
||||||
|
|
||||||
let removed = ScriptObject::array(
|
let removed = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.array),
|
Some(activation.context.avm1.prototypes.array),
|
||||||
);
|
);
|
||||||
let to_remove = count.min(old_length as i32 - start as i32).max(0) as usize;
|
let to_remove = count.min(old_length as i32 - start as i32).max(0) as usize;
|
||||||
let to_add = if args.len() > 2 { &args[2..] } else { &[] };
|
let to_add = if args.len() > 2 { &args[2..] } else { &[] };
|
||||||
|
@ -428,7 +428,7 @@ pub fn concat<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let array = ScriptObject::array(
|
let array = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.array),
|
Some(activation.context.avm1.prototypes.array),
|
||||||
);
|
);
|
||||||
let mut length = 0;
|
let mut length = 0;
|
||||||
|
|
||||||
|
@ -450,7 +450,13 @@ pub fn concat<'gc>(
|
||||||
|
|
||||||
if let Value::Object(object) = arg {
|
if let Value::Object(object) = arg {
|
||||||
let object = *object;
|
let object = *object;
|
||||||
if activation.avm.prototypes.array.is_prototype_of(object) {
|
if activation
|
||||||
|
.context
|
||||||
|
.avm1
|
||||||
|
.prototypes
|
||||||
|
.array
|
||||||
|
.is_prototype_of(object)
|
||||||
|
{
|
||||||
added = true;
|
added = true;
|
||||||
for i in 0..object.length() {
|
for i in 0..object.length() {
|
||||||
let old = object
|
let old = object
|
||||||
|
@ -623,7 +629,7 @@ fn sort_with_function<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let length = this.length();
|
let length = this.length();
|
||||||
let mut values: Vec<(usize, Value<'gc>)> = this.array().into_iter().enumerate().collect();
|
let mut values: Vec<(usize, Value<'gc>)> = this.array().into_iter().enumerate().collect();
|
||||||
let array_proto = activation.avm.prototypes.array;
|
let array_proto = activation.context.avm1.prototypes.array;
|
||||||
|
|
||||||
let descending = (flags & DESCENDING) != 0;
|
let descending = (flags & DESCENDING) != 0;
|
||||||
let unique_sort = (flags & UNIQUE_SORT) != 0;
|
let unique_sort = (flags & UNIQUE_SORT) != 0;
|
||||||
|
|
|
@ -147,8 +147,8 @@ pub fn initialize<'gc>(
|
||||||
initialize_internal(
|
initialize_internal(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
broadcaster,
|
broadcaster,
|
||||||
activation.avm.broadcaster_functions,
|
activation.context.avm1.broadcaster_functions,
|
||||||
activation.avm.prototypes().array,
|
activation.context.avm1.prototypes().array,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
|
|
|
@ -115,7 +115,7 @@ fn get_transform<'gc>(
|
||||||
let color_transform = target.color_transform();
|
let color_transform = target.color_transform();
|
||||||
let out = ScriptObject::object(
|
let out = ScriptObject::object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.object),
|
Some(activation.context.avm1.prototypes.object),
|
||||||
);
|
);
|
||||||
out.set("ra", (color_transform.r_mult * 100.0).into(), activation)?;
|
out.set("ra", (color_transform.r_mult * 100.0).into(), activation)?;
|
||||||
out.set("ga", (color_transform.g_mult * 100.0).into(), activation)?;
|
out.set("ga", (color_transform.g_mult * 100.0).into(), activation)?;
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn constructor<'gc>(
|
||||||
|
|
||||||
this.set("onSelect", callback.into(), activation)?;
|
this.set("onSelect", callback.into(), activation)?;
|
||||||
|
|
||||||
let prototype = activation.avm.prototypes.object;
|
let prototype = activation.context.avm1.prototypes.object;
|
||||||
let built_in_items = prototype.create_bare_object(activation, prototype)?;
|
let built_in_items = prototype.create_bare_object(activation, prototype)?;
|
||||||
|
|
||||||
built_in_items.set("print", true.into(), activation)?;
|
built_in_items.set("print", true.into(), activation)?;
|
||||||
|
@ -32,7 +32,7 @@ pub fn constructor<'gc>(
|
||||||
|
|
||||||
this.set("builtInItems", built_in_items.into(), activation)?;
|
this.set("builtInItems", built_in_items.into(), activation)?;
|
||||||
|
|
||||||
let constructor = activation.avm.prototypes.array_constructor;
|
let constructor = activation.context.avm1.prototypes.array_constructor;
|
||||||
let custom_items = constructor.construct(activation, &[])?;
|
let custom_items = constructor.construct(activation, &[])?;
|
||||||
|
|
||||||
this.set("customItems", custom_items.into(), activation)?;
|
this.set("customItems", custom_items.into(), activation)?;
|
||||||
|
@ -49,7 +49,7 @@ pub fn copy<'gc>(
|
||||||
.get("onSelect", activation)?
|
.get("onSelect", activation)?
|
||||||
.coerce_to_object(activation);
|
.coerce_to_object(activation);
|
||||||
|
|
||||||
let constructor = activation.avm.prototypes.context_menu_constructor;
|
let constructor = activation.context.avm1.prototypes.context_menu_constructor;
|
||||||
let copy = constructor.construct(activation, &[callback.into()])?;
|
let copy = constructor.construct(activation, &[callback.into()])?;
|
||||||
|
|
||||||
let built_in = this
|
let built_in = this
|
||||||
|
|
|
@ -78,7 +78,11 @@ pub fn copy<'gc>(
|
||||||
.get("visible", activation)?
|
.get("visible", activation)?
|
||||||
.as_bool(activation.swf_version());
|
.as_bool(activation.swf_version());
|
||||||
|
|
||||||
let constructor = activation.avm.prototypes.context_menu_item_constructor;
|
let constructor = activation
|
||||||
|
.context
|
||||||
|
.avm1
|
||||||
|
.prototypes
|
||||||
|
.context_menu_item_constructor;
|
||||||
let copy = constructor.construct(
|
let copy = constructor.construct(
|
||||||
activation,
|
activation,
|
||||||
&[
|
&[
|
||||||
|
|
|
@ -56,7 +56,9 @@ pub fn define_display_object_proto<'gc>(
|
||||||
"_global",
|
"_global",
|
||||||
FunctionObject::function(
|
FunctionObject::function(
|
||||||
gc_context,
|
gc_context,
|
||||||
Executable::Native(|activation, _this, _args| Ok(activation.avm.global_object())),
|
Executable::Native(|activation, _this, _args| {
|
||||||
|
Ok(activation.context.avm1.global_object())
|
||||||
|
}),
|
||||||
Some(fn_proto),
|
Some(fn_proto),
|
||||||
fn_proto,
|
fn_proto,
|
||||||
),
|
),
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub fn call<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let this = match myargs.get(0) {
|
let this = match myargs.get(0) {
|
||||||
Some(Value::Object(this)) => *this,
|
Some(Value::Object(this)) => *this,
|
||||||
_ => activation.avm.globals,
|
_ => activation.context.avm1.globals,
|
||||||
};
|
};
|
||||||
let empty = [];
|
let empty = [];
|
||||||
let args = match myargs.len() {
|
let args = match myargs.len() {
|
||||||
|
@ -55,7 +55,7 @@ pub fn apply<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let this = match myargs.get(0) {
|
let this = match myargs.get(0) {
|
||||||
Some(Value::Object(this)) => *this,
|
Some(Value::Object(this)) => *this,
|
||||||
_ => activation.avm.globals,
|
_ => activation.context.avm1.globals,
|
||||||
};
|
};
|
||||||
let mut child_args = Vec::new();
|
let mut child_args = Vec::new();
|
||||||
let args_object = myargs.get(1).cloned().unwrap_or(Value::Undefined);
|
let args_object = myargs.get(1).cloned().unwrap_or(Value::Undefined);
|
||||||
|
|
|
@ -258,8 +258,8 @@ mod tests {
|
||||||
fn setup<'gc>(activation: &mut Activation<'_, '_, 'gc, '_>) -> Object<'gc> {
|
fn setup<'gc>(activation: &mut Activation<'_, '_, 'gc, '_>) -> Object<'gc> {
|
||||||
create(
|
create(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().object),
|
Some(activation.context.avm1.prototypes().object),
|
||||||
Some(activation.avm.prototypes().function),
|
Some(activation.context.avm1.prototypes().function),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,8 +476,8 @@ mod tests {
|
||||||
with_avm(19, |activation, _root| -> Result<(), Error> {
|
with_avm(19, |activation, _root| -> Result<(), Error> {
|
||||||
let math = create(
|
let math = create(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().object),
|
Some(activation.context.avm1.prototypes().object),
|
||||||
Some(activation.avm.prototypes().function),
|
Some(activation.context.avm1.prototypes().function),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(atan2(activation, math, &[]).unwrap(), NAN.into());
|
assert_eq!(atan2(activation, math, &[]).unwrap(), NAN.into());
|
||||||
|
@ -502,8 +502,8 @@ mod tests {
|
||||||
with_avm(19, |activation, _root| -> Result<(), Error> {
|
with_avm(19, |activation, _root| -> Result<(), Error> {
|
||||||
let math = create(
|
let math = create(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().object),
|
Some(activation.context.avm1.prototypes().object),
|
||||||
Some(activation.avm.prototypes().function),
|
Some(activation.context.avm1.prototypes().function),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -99,7 +99,7 @@ pub fn matrix_to_object<'gc>(
|
||||||
matrix.tx.to_pixels().into(),
|
matrix.tx.to_pixels().into(),
|
||||||
matrix.ty.to_pixels().into(),
|
matrix.ty.to_pixels().into(),
|
||||||
];
|
];
|
||||||
let constructor = activation.avm.prototypes.matrix_constructor;
|
let constructor = activation.context.avm1.prototypes.matrix_constructor;
|
||||||
let object = constructor.construct(activation, &args)?;
|
let object = constructor.construct(activation, &args)?;
|
||||||
Ok(object)
|
Ok(object)
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ fn clone<'gc>(
|
||||||
this.get("tx", activation)?,
|
this.get("tx", activation)?,
|
||||||
this.get("ty", activation)?,
|
this.get("ty", activation)?,
|
||||||
];
|
];
|
||||||
let constructor = activation.avm.prototypes.matrix_constructor;
|
let constructor = activation.context.avm1.prototypes.matrix_constructor;
|
||||||
let cloned = constructor.construct(activation, &args)?;
|
let cloned = constructor.construct(activation, &args)?;
|
||||||
Ok(cloned.into())
|
Ok(cloned.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,14 +456,8 @@ fn attach_movie<'gc>(
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
new_clip.post_instantiation(
|
new_clip.post_instantiation(activation.context, new_clip, init_object, true);
|
||||||
activation.avm,
|
new_clip.run_frame(activation.context);
|
||||||
activation.context,
|
|
||||||
new_clip,
|
|
||||||
init_object,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
new_clip.run_frame(activation.avm, activation.context);
|
|
||||||
|
|
||||||
Ok(new_clip.object().coerce_to_object(activation).into())
|
Ok(new_clip.object().coerce_to_object(activation).into())
|
||||||
} else {
|
} else {
|
||||||
|
@ -500,14 +494,8 @@ fn create_empty_movie_clip<'gc>(
|
||||||
// Set name and attach to parent.
|
// Set name and attach to parent.
|
||||||
new_clip.set_name(activation.context.gc_context, &new_instance_name);
|
new_clip.set_name(activation.context.gc_context, &new_instance_name);
|
||||||
movie_clip.add_child_from_avm(activation.context, new_clip.into(), depth);
|
movie_clip.add_child_from_avm(activation.context, new_clip.into(), depth);
|
||||||
new_clip.post_instantiation(
|
new_clip.post_instantiation(activation.context, new_clip.into(), None, true);
|
||||||
activation.avm,
|
new_clip.run_frame(activation.context);
|
||||||
activation.context,
|
|
||||||
new_clip.into(),
|
|
||||||
None,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
new_clip.run_frame(activation.avm, activation.context);
|
|
||||||
|
|
||||||
Ok(new_clip.object())
|
Ok(new_clip.object())
|
||||||
}
|
}
|
||||||
|
@ -556,7 +544,7 @@ fn create_text_field<'gc>(
|
||||||
text_field,
|
text_field,
|
||||||
(depth as Depth).wrapping_add(AVM_DEPTH_BIAS),
|
(depth as Depth).wrapping_add(AVM_DEPTH_BIAS),
|
||||||
);
|
);
|
||||||
text_field.post_instantiation(activation.avm, activation.context, text_field, None, true);
|
text_field.post_instantiation(activation.context, text_field, None, true);
|
||||||
|
|
||||||
if activation.current_swf_version() >= 8 {
|
if activation.current_swf_version() >= 8 {
|
||||||
//SWF8+ returns the `TextField` instance here
|
//SWF8+ returns the `TextField` instance here
|
||||||
|
@ -631,14 +619,8 @@ pub fn duplicate_movie_clip_with_bias<'gc>(
|
||||||
// Definitely not ScriptObject properties.
|
// Definitely not ScriptObject properties.
|
||||||
|
|
||||||
let init_object = init_object.map(|v| v.coerce_to_object(activation));
|
let init_object = init_object.map(|v| v.coerce_to_object(activation));
|
||||||
new_clip.post_instantiation(
|
new_clip.post_instantiation(activation.context, new_clip, init_object, true);
|
||||||
activation.avm,
|
new_clip.run_frame(activation.context);
|
||||||
activation.context,
|
|
||||||
new_clip,
|
|
||||||
init_object,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
new_clip.run_frame(activation.avm, activation.context);
|
|
||||||
|
|
||||||
Ok(new_clip.object().coerce_to_object(activation).into())
|
Ok(new_clip.object().coerce_to_object(activation).into())
|
||||||
} else {
|
} else {
|
||||||
|
@ -750,7 +732,7 @@ pub fn goto_frame<'gc>(
|
||||||
frame = frame.wrapping_add(i32::from(scene_offset));
|
frame = frame.wrapping_add(i32::from(scene_offset));
|
||||||
frame = frame.saturating_add(1);
|
frame = frame.saturating_add(1);
|
||||||
if frame > 0 {
|
if frame > 0 {
|
||||||
clip.goto_frame(activation.avm, activation.context, frame as u16, stop);
|
clip.goto_frame(activation.context, frame as u16, stop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
|
@ -761,7 +743,7 @@ fn next_frame<'gc>(
|
||||||
activation: &mut Activation<'_, '_, 'gc, '_>,
|
activation: &mut Activation<'_, '_, 'gc, '_>,
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
movie_clip.next_frame(activation.avm, activation.context);
|
movie_clip.next_frame(activation.context);
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,7 +761,7 @@ fn prev_frame<'gc>(
|
||||||
activation: &mut Activation<'_, '_, 'gc, '_>,
|
activation: &mut Activation<'_, '_, 'gc, '_>,
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
movie_clip.prev_frame(activation.avm, activation.context);
|
movie_clip.prev_frame(activation.context);
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -965,7 +947,7 @@ fn get_bounds<'gc>(
|
||||||
|
|
||||||
let out = ScriptObject::object(
|
let out = ScriptObject::object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.object),
|
Some(activation.context.avm1.prototypes.object),
|
||||||
);
|
);
|
||||||
out.set("xMin", out_bounds.x_min.to_pixels().into(), activation)?;
|
out.set("xMin", out_bounds.x_min.to_pixels().into(), activation)?;
|
||||||
out.set("yMin", out_bounds.y_min.to_pixels().into(), activation)?;
|
out.set("yMin", out_bounds.y_min.to_pixels().into(), activation)?;
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn constructor<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let listeners = ScriptObject::array(
|
let listeners = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().array),
|
Some(activation.context.avm1.prototypes().array),
|
||||||
);
|
);
|
||||||
this.define_value(
|
this.define_value(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub fn construct_new_point<'gc>(
|
||||||
args: &[Value<'gc>],
|
args: &[Value<'gc>],
|
||||||
activation: &mut Activation<'_, '_, 'gc, '_>,
|
activation: &mut Activation<'_, '_, 'gc, '_>,
|
||||||
) -> Result<Object<'gc>, Error<'gc>> {
|
) -> Result<Object<'gc>, Error<'gc>> {
|
||||||
let constructor = activation.avm.prototypes.point_constructor;
|
let constructor = activation.context.avm1.prototypes.point_constructor;
|
||||||
let object = constructor.construct(activation, &args)?;
|
let object = constructor.construct(activation, &args)?;
|
||||||
Ok(object)
|
Ok(object)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ fn clone<'gc>(
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let args = [this.get("x", activation)?, this.get("y", activation)?];
|
let args = [this.get("x", activation)?, this.get("y", activation)?];
|
||||||
let constructor = activation.avm.prototypes.point_constructor;
|
let constructor = activation.context.avm1.prototypes.point_constructor;
|
||||||
let cloned = constructor.construct(activation, &args)?;
|
let cloned = constructor.construct(activation, &args)?;
|
||||||
|
|
||||||
Ok(cloned.into())
|
Ok(cloned.into())
|
||||||
|
|
|
@ -115,7 +115,7 @@ fn clone<'gc>(
|
||||||
this.get("width", activation)?,
|
this.get("width", activation)?,
|
||||||
this.get("height", activation)?,
|
this.get("height", activation)?,
|
||||||
];
|
];
|
||||||
let constructor = activation.avm.prototypes.rectangle_constructor;
|
let constructor = activation.context.avm1.prototypes.rectangle_constructor;
|
||||||
let cloned = constructor.construct(activation, &args)?;
|
let cloned = constructor.construct(activation, &args)?;
|
||||||
Ok(cloned.into())
|
Ok(cloned.into())
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ fn union<'gc>(
|
||||||
Value::Number(width),
|
Value::Number(width),
|
||||||
Value::Number(height),
|
Value::Number(height),
|
||||||
];
|
];
|
||||||
let constructor = activation.avm.prototypes.rectangle_constructor;
|
let constructor = activation.context.avm1.prototypes.rectangle_constructor;
|
||||||
let result = constructor.construct(activation, &args)?;
|
let result = constructor.construct(activation, &args)?;
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ fn intersection<'gc>(
|
||||||
Value::Number(right - left),
|
Value::Number(right - left),
|
||||||
Value::Number(bottom - top),
|
Value::Number(bottom - top),
|
||||||
];
|
];
|
||||||
let constructor = activation.avm.prototypes.rectangle_constructor;
|
let constructor = activation.context.avm1.prototypes.rectangle_constructor;
|
||||||
let result = constructor.construct(activation, &args)?;
|
let result = constructor.construct(activation, &args)?;
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ fn recursive_serialize<'gc>(
|
||||||
Value::String(s) => json_obj[k] = s.to_string().into(),
|
Value::String(s) => json_obj[k] = s.to_string().into(),
|
||||||
Value::Object(o) => {
|
Value::Object(o) => {
|
||||||
// Don't attempt to serialize functions
|
// Don't attempt to serialize functions
|
||||||
let function = activation.avm.prototypes.function;
|
let function = activation.context.avm1.prototypes.function;
|
||||||
if !o
|
if !o
|
||||||
.is_instance_of(activation, o, function)
|
.is_instance_of(activation, o, function)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
@ -114,7 +114,7 @@ fn recursive_deserialize<'gc>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
JsonValue::Object(o) => {
|
JsonValue::Object(o) => {
|
||||||
let prototype = activation.avm.prototypes.object;
|
let prototype = activation.context.avm1.prototypes.object;
|
||||||
if let Ok(obj) = prototype.create_bare_object(activation, prototype) {
|
if let Ok(obj) = prototype.create_bare_object(activation, prototype) {
|
||||||
recursive_deserialize(JsonValue::Object(o.clone()), activation, obj);
|
recursive_deserialize(JsonValue::Object(o.clone()), activation, obj);
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ pub fn get_local<'gc>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data property only should exist when created with getLocal/Remote
|
// Data property only should exist when created with getLocal/Remote
|
||||||
let constructor = activation.avm.prototypes.shared_object_constructor;
|
let constructor = activation.context.avm1.prototypes.shared_object_constructor;
|
||||||
let this = constructor.construct(activation, &[])?;
|
let this = constructor.construct(activation, &[])?;
|
||||||
|
|
||||||
// Set the internal name
|
// Set the internal name
|
||||||
|
@ -164,7 +164,7 @@ pub fn get_local<'gc>(
|
||||||
obj_so.set_name(activation.context.gc_context, name.to_string());
|
obj_so.set_name(activation.context.gc_context, name.to_string());
|
||||||
|
|
||||||
// Create the data object
|
// Create the data object
|
||||||
let prototype = activation.avm.prototypes.object;
|
let prototype = activation.context.avm1.prototypes.object;
|
||||||
let data = prototype.create_bare_object(activation, prototype)?;
|
let data = prototype.create_bare_object(activation, prototype)?;
|
||||||
|
|
||||||
// Load the data object from storage if it existed prior
|
// Load the data object from storage if it existed prior
|
||||||
|
|
|
@ -410,7 +410,7 @@ fn split<'gc>(
|
||||||
};
|
};
|
||||||
let array = ScriptObject::array(
|
let array = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.array),
|
Some(activation.context.avm1.prototypes.array),
|
||||||
);
|
);
|
||||||
if !delimiter.is_empty() {
|
if !delimiter.is_empty() {
|
||||||
for (i, token) in this.split(delimiter.as_ref()).take(limit).enumerate() {
|
for (i, token) in this.split(delimiter.as_ref()).take(limit).enumerate() {
|
||||||
|
|
|
@ -108,7 +108,7 @@ pub fn get_language<'gc>(
|
||||||
.context
|
.context
|
||||||
.system
|
.system
|
||||||
.language
|
.language
|
||||||
.get_language_code(activation.avm.player_version)
|
.get_language_code(activation.context.avm1.player_version)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
|
@ -157,7 +157,7 @@ pub fn get_manufacturer<'gc>(
|
||||||
.context
|
.context
|
||||||
.system
|
.system
|
||||||
.manufacturer
|
.manufacturer
|
||||||
.get_manufacturer_string(activation.avm.player_version),
|
.get_manufacturer_string(activation.context.avm1.player_version),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,10 @@ pub fn get_version<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
Ok(AvmString::new(
|
Ok(AvmString::new(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
activation.context.system.get_version_string(activation.avm),
|
activation
|
||||||
|
.context
|
||||||
|
.system
|
||||||
|
.get_version_string(activation.context.avm1),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
@ -191,7 +194,10 @@ pub fn get_server_string<'gc>(
|
||||||
_this: Object<'gc>,
|
_this: Object<'gc>,
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let server_string = activation.context.system.get_server_string(activation.avm);
|
let server_string = activation
|
||||||
|
.context
|
||||||
|
.system
|
||||||
|
.get_server_string(activation.context.avm1);
|
||||||
Ok(AvmString::new(activation.context.gc_context, server_string).into())
|
Ok(AvmString::new(activation.context.gc_context, server_string).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ pub fn xmlnode_clone_node<'gc>(
|
||||||
|
|
||||||
return Ok(Value::Object(clone_node.script_object(
|
return Ok(Value::Object(clone_node.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.xml_node),
|
Some(activation.context.avm1.prototypes.xml_node),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ pub fn xmlnode_child_nodes<'gc>(
|
||||||
if let Some(node) = this.as_xml_node() {
|
if let Some(node) = this.as_xml_node() {
|
||||||
let array = ScriptObject::array(
|
let array = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.array),
|
Some(activation.context.avm1.prototypes.array),
|
||||||
);
|
);
|
||||||
if let Some(children) = node.children() {
|
if let Some(children) = node.children() {
|
||||||
let mut compatible_nodes = 0;
|
let mut compatible_nodes = 0;
|
||||||
|
@ -336,7 +336,7 @@ pub fn xmlnode_child_nodes<'gc>(
|
||||||
child
|
child
|
||||||
.script_object(
|
.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.xml_node),
|
Some(activation.context.avm1.prototypes.xml_node),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
@ -365,7 +365,7 @@ pub fn xmlnode_first_child<'gc>(
|
||||||
child
|
child
|
||||||
.script_object(
|
.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.xml_node),
|
Some(activation.context.avm1.prototypes.xml_node),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -389,7 +389,7 @@ pub fn xmlnode_last_child<'gc>(
|
||||||
child
|
child
|
||||||
.script_object(
|
.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.xml_node),
|
Some(activation.context.avm1.prototypes.xml_node),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -413,7 +413,7 @@ pub fn xmlnode_parent_node<'gc>(
|
||||||
parent
|
parent
|
||||||
.script_object(
|
.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.xml_node),
|
Some(activation.context.avm1.prototypes.xml_node),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -442,7 +442,7 @@ pub fn xmlnode_previous_sibling<'gc>(
|
||||||
.map(|mut prev| {
|
.map(|mut prev| {
|
||||||
prev.script_object(
|
prev.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.xml_node),
|
Some(activation.context.avm1.prototypes.xml_node),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -471,7 +471,7 @@ pub fn xmlnode_next_sibling<'gc>(
|
||||||
.map(|mut next| {
|
.map(|mut next| {
|
||||||
next.script_object(
|
next.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.xml_node),
|
Some(activation.context.avm1.prototypes.xml_node),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -822,7 +822,7 @@ pub fn xml_create_element<'gc>(
|
||||||
let object = XMLObject::from_xml_node(
|
let object = XMLObject::from_xml_node(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
xml_node,
|
xml_node,
|
||||||
Some(activation.avm.prototypes().xml_node),
|
Some(activation.context.avm1.prototypes().xml_node),
|
||||||
);
|
);
|
||||||
|
|
||||||
xml_node.introduce_script_object(activation.context.gc_context, object);
|
xml_node.introduce_script_object(activation.context.gc_context, object);
|
||||||
|
@ -849,7 +849,7 @@ pub fn xml_create_text_node<'gc>(
|
||||||
let object = XMLObject::from_xml_node(
|
let object = XMLObject::from_xml_node(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
xml_node,
|
xml_node,
|
||||||
Some(activation.avm.prototypes().xml_node),
|
Some(activation.context.avm1.prototypes().xml_node),
|
||||||
);
|
);
|
||||||
|
|
||||||
xml_node.introduce_script_object(activation.context.gc_context, object);
|
xml_node.introduce_script_object(activation.context.gc_context, object);
|
||||||
|
|
|
@ -106,7 +106,7 @@ impl<'gc> TObject<'gc> for ColorTransformObject<'gc> {
|
||||||
value,
|
value,
|
||||||
activation,
|
activation,
|
||||||
(*self).into(),
|
(*self).into(),
|
||||||
Some(activation.avm.prototypes.color_transform),
|
Some(activation.context.avm1.prototypes.color_transform),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,12 +118,11 @@ impl<'gc> TObject<'gc> for ColorTransformObject<'gc> {
|
||||||
fn create_bare_object(
|
fn create_bare_object(
|
||||||
&self,
|
&self,
|
||||||
activation: &mut Activation<'_, '_, 'gc, '_>,
|
activation: &mut Activation<'_, '_, 'gc, '_>,
|
||||||
|
|
||||||
_this: Object<'gc>,
|
_this: Object<'gc>,
|
||||||
) -> Result<Object<'gc>, Error<'gc>> {
|
) -> Result<Object<'gc>, Error<'gc>> {
|
||||||
Ok(ColorTransformObject::empty_color_transform_object(
|
Ok(ColorTransformObject::empty_color_transform_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.color_transform),
|
Some(activation.context.avm1.prototypes.color_transform),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,9 +908,10 @@ mod tests {
|
||||||
unbound_text_fields: &mut Vec::new(),
|
unbound_text_fields: &mut Vec::new(),
|
||||||
timers: &mut Timers::new(),
|
timers: &mut Timers::new(),
|
||||||
needs_render: &mut false,
|
needs_render: &mut false,
|
||||||
|
avm1: &mut avm,
|
||||||
};
|
};
|
||||||
|
|
||||||
root.post_instantiation(&mut avm, &mut context, root, None, false);
|
root.post_instantiation(&mut context, root, None, false);
|
||||||
root.set_name(context.gc_context, "");
|
root.set_name(context.gc_context, "");
|
||||||
|
|
||||||
let object = ScriptObject::object(gc_context, Some(avm.prototypes().object)).into();
|
let object = ScriptObject::object(gc_context, Some(avm.prototypes().object)).into();
|
||||||
|
@ -919,7 +920,6 @@ mod tests {
|
||||||
let base_clip = *context.levels.get(&0).unwrap();
|
let base_clip = *context.levels.get(&0).unwrap();
|
||||||
let swf_version = context.swf.version();
|
let swf_version = context.swf.version();
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
&mut avm,
|
|
||||||
&mut context,
|
&mut context,
|
||||||
ActivationIdentifier::root("[Test]"),
|
ActivationIdentifier::root("[Test]"),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
@ -1017,7 +1017,7 @@ mod tests {
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Executable::Native(|_avm, _this, _args| Ok("Virtual!".into())),
|
Executable::Native(|_avm, _this, _args| Ok("Virtual!".into())),
|
||||||
None,
|
None,
|
||||||
activation.avm.prototypes.function,
|
activation.context.avm1.prototypes.function,
|
||||||
);
|
);
|
||||||
|
|
||||||
object.as_script_object().unwrap().add_property(
|
object.as_script_object().unwrap().add_property(
|
||||||
|
@ -1043,7 +1043,7 @@ mod tests {
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Executable::Native(|_avm, _this, _args| Ok("Virtual!".into())),
|
Executable::Native(|_avm, _this, _args| Ok("Virtual!".into())),
|
||||||
None,
|
None,
|
||||||
activation.avm.prototypes.function,
|
activation.context.avm1.prototypes.function,
|
||||||
);
|
);
|
||||||
|
|
||||||
object.as_script_object().unwrap().add_property(
|
object.as_script_object().unwrap().add_property(
|
||||||
|
@ -1099,7 +1099,7 @@ mod tests {
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Executable::Native(|_avm, _this, _args| Ok(Value::Null)),
|
Executable::Native(|_avm, _this, _args| Ok(Value::Null)),
|
||||||
None,
|
None,
|
||||||
activation.avm.prototypes.function,
|
activation.context.avm1.prototypes.function,
|
||||||
);
|
);
|
||||||
|
|
||||||
object.as_script_object().unwrap().define_value(
|
object.as_script_object().unwrap().define_value(
|
||||||
|
|
|
@ -70,7 +70,7 @@ impl<'gc> TObject<'gc> for SharedObject<'gc> {
|
||||||
) -> Result<Object<'gc>, Error<'gc>> {
|
) -> Result<Object<'gc>, Error<'gc>> {
|
||||||
Ok(SharedObject::empty_shared_obj(
|
Ok(SharedObject::empty_shared_obj(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.shared_object),
|
Some(activation.context.avm1.prototypes.shared_object),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ impl<'gc> TObject<'gc> for SoundObject<'gc> {
|
||||||
) -> Result<Object<'gc>, Error<'gc>> {
|
) -> Result<Object<'gc>, Error<'gc>> {
|
||||||
Ok(SoundObject::empty_sound(
|
Ok(SoundObject::empty_sound(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes.sound),
|
Some(activation.context.avm1.prototypes.sound),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
||||||
activation: &mut Activation<'_, '_, 'gc, '_>,
|
activation: &mut Activation<'_, '_, 'gc, '_>,
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let obj = self.0.read();
|
let obj = self.0.read();
|
||||||
let props = activation.avm.display_properties;
|
let props = activation.context.avm1.display_properties;
|
||||||
let case_sensitive = activation.is_case_sensitive();
|
let case_sensitive = activation.is_case_sensitive();
|
||||||
// Property search order for DisplayObjects:
|
// Property search order for DisplayObjects:
|
||||||
if self.has_own_property(activation, name) {
|
if self.has_own_property(activation, name) {
|
||||||
|
@ -173,7 +173,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
||||||
activation: &mut Activation<'_, '_, 'gc, '_>,
|
activation: &mut Activation<'_, '_, 'gc, '_>,
|
||||||
) -> Result<(), Error<'gc>> {
|
) -> Result<(), Error<'gc>> {
|
||||||
let obj = self.0.read();
|
let obj = self.0.read();
|
||||||
let props = activation.avm.display_properties;
|
let props = activation.context.avm1.display_properties;
|
||||||
|
|
||||||
// Check if a text field is bound to this property and update the text if so.
|
// Check if a text field is bound to this property and update the text if so.
|
||||||
for binding in obj
|
for binding in obj
|
||||||
|
@ -346,7 +346,8 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if activation
|
if activation
|
||||||
.avm
|
.context
|
||||||
|
.avm1
|
||||||
.display_properties
|
.display_properties
|
||||||
.read()
|
.read()
|
||||||
.get_by_name(&name)
|
.get_by_name(&name)
|
||||||
|
|
|
@ -41,9 +41,9 @@ impl<'gc> ValueObject<'gc> {
|
||||||
ob
|
ob
|
||||||
} else {
|
} else {
|
||||||
let proto = match &value {
|
let proto = match &value {
|
||||||
Value::Bool(_) => Some(activation.avm.prototypes.boolean),
|
Value::Bool(_) => Some(activation.context.avm1.prototypes.boolean),
|
||||||
Value::Number(_) => Some(activation.avm.prototypes.number),
|
Value::Number(_) => Some(activation.context.avm1.prototypes.number),
|
||||||
Value::String(_) => Some(activation.avm.prototypes.string),
|
Value::String(_) => Some(activation.context.avm1.prototypes.string),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
|
||||||
Ok(node
|
Ok(node
|
||||||
.script_object(
|
.script_object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().xml_node),
|
Some(activation.context.avm1.prototypes().xml_node),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -26,7 +26,7 @@ where
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Activation<'_, '_, 'gc, '_>, Object<'gc>) -> Result<(), Error<'gc>>,
|
F: FnOnce(&mut Activation<'_, '_, 'gc, '_>, Object<'gc>) -> Result<(), Error<'gc>>,
|
||||||
{
|
{
|
||||||
let mut avm = Avm1::new(gc_context, swf_version);
|
let mut avm1 = Avm1::new(gc_context, swf_version);
|
||||||
let swf = Arc::new(SwfMovie::empty(swf_version));
|
let swf = Arc::new(SwfMovie::empty(swf_version));
|
||||||
let mut root: DisplayObject<'gc> =
|
let mut root: DisplayObject<'gc> =
|
||||||
MovieClip::new(SwfSlice::empty(swf.clone()), gc_context).into();
|
MovieClip::new(SwfSlice::empty(swf.clone()), gc_context).into();
|
||||||
|
@ -52,7 +52,7 @@ where
|
||||||
library: &mut Library::default(),
|
library: &mut Library::default(),
|
||||||
navigator: &mut NullNavigatorBackend::new(),
|
navigator: &mut NullNavigatorBackend::new(),
|
||||||
renderer: &mut NullRenderer::new(),
|
renderer: &mut NullRenderer::new(),
|
||||||
system_prototypes: avm.prototypes().clone(),
|
system_prototypes: avm1.prototypes().clone(),
|
||||||
mouse_hovered_object: None,
|
mouse_hovered_object: None,
|
||||||
mouse_position: &(Twips::new(0), Twips::new(0)),
|
mouse_position: &(Twips::new(0), Twips::new(0)),
|
||||||
drag_object: &mut None,
|
drag_object: &mut None,
|
||||||
|
@ -66,8 +66,9 @@ where
|
||||||
unbound_text_fields: &mut Vec::new(),
|
unbound_text_fields: &mut Vec::new(),
|
||||||
timers: &mut Timers::new(),
|
timers: &mut Timers::new(),
|
||||||
needs_render: &mut false,
|
needs_render: &mut false,
|
||||||
|
avm1: &mut avm1,
|
||||||
};
|
};
|
||||||
root.post_instantiation(&mut avm, &mut context, root, None, false);
|
root.post_instantiation(&mut context, root, None, false);
|
||||||
root.set_name(context.gc_context, "");
|
root.set_name(context.gc_context, "");
|
||||||
|
|
||||||
fn run_test<'a, 'gc: 'a, F>(
|
fn run_test<'a, 'gc: 'a, F>(
|
||||||
|
@ -84,11 +85,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let globals = avm.global_object_cell();
|
let globals = avm1.global_object_cell();
|
||||||
let base_clip = *context.levels.get(&0).unwrap();
|
let base_clip = *context.levels.get(&0).unwrap();
|
||||||
let swf_version = context.swf.version();
|
let swf_version = context.swf.version();
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
&mut avm,
|
|
||||||
&mut context,
|
&mut context,
|
||||||
ActivationIdentifier::root("[Test]"),
|
ActivationIdentifier::root("[Test]"),
|
||||||
swf_version,
|
swf_version,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//! TODO: Could we use this for AVM2 timers as well?
|
//! TODO: Could we use this for AVM2 timers as well?
|
||||||
|
|
||||||
use crate::avm1::object::search_prototype;
|
use crate::avm1::object::search_prototype;
|
||||||
use crate::avm1::{Activation, ActivationIdentifier, Avm1, Object, TObject, Value};
|
use crate::avm1::{Activation, ActivationIdentifier, Object, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use gc_arena::Collect;
|
use gc_arena::Collect;
|
||||||
use std::collections::{binary_heap::PeekMut, BinaryHeap};
|
use std::collections::{binary_heap::PeekMut, BinaryHeap};
|
||||||
|
@ -26,11 +26,7 @@ pub struct Timers<'gc> {
|
||||||
|
|
||||||
impl<'gc> Timers<'gc> {
|
impl<'gc> Timers<'gc> {
|
||||||
/// Ticks all timers and runs necessary callbacks.
|
/// Ticks all timers and runs necessary callbacks.
|
||||||
pub fn update_timers(
|
pub fn update_timers(context: &mut UpdateContext<'_, 'gc, '_>, dt: f64) -> Option<f64> {
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
|
||||||
dt: f64,
|
|
||||||
) -> Option<f64> {
|
|
||||||
context.timers.cur_time = context
|
context.timers.cur_time = context
|
||||||
.timers
|
.timers
|
||||||
.cur_time
|
.cur_time
|
||||||
|
@ -42,11 +38,10 @@ impl<'gc> Timers<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Timer Callback]"),
|
ActivationIdentifier::root("[Timer Callback]"),
|
||||||
context.swf.header().version,
|
context.swf.header().version,
|
||||||
avm.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
context.levels.get(&0).copied().unwrap(),
|
context.levels.get(&0).copied().unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -297,10 +297,10 @@ impl<'gc> Value<'gc> {
|
||||||
(Value::Bool(a), Value::Bool(b)) => Ok((a == b).into()),
|
(Value::Bool(a), Value::Bool(b)) => Ok((a == b).into()),
|
||||||
(Value::Object(a), Value::Object(b)) => Ok(Object::ptr_eq(*a, *b).into()),
|
(Value::Object(a), Value::Object(b)) => Ok(Object::ptr_eq(*a, *b).into()),
|
||||||
(Value::Object(a), Value::Null) | (Value::Object(a), Value::Undefined) => {
|
(Value::Object(a), Value::Null) | (Value::Object(a), Value::Undefined) => {
|
||||||
Ok(Object::ptr_eq(*a, activation.avm.global_object_cell()).into())
|
Ok(Object::ptr_eq(*a, activation.context.avm1.global_object_cell()).into())
|
||||||
}
|
}
|
||||||
(Value::Null, Value::Object(b)) | (Value::Undefined, Value::Object(b)) => {
|
(Value::Null, Value::Object(b)) | (Value::Undefined, Value::Object(b)) => {
|
||||||
Ok(Object::ptr_eq(*b, activation.avm.global_object_cell()).into())
|
Ok(Object::ptr_eq(*b, activation.context.avm1.global_object_cell()).into())
|
||||||
}
|
}
|
||||||
(Value::Undefined, Value::Null) => Ok(true.into()),
|
(Value::Undefined, Value::Null) => Ok(true.into()),
|
||||||
(Value::Null, Value::Undefined) => Ok(true.into()),
|
(Value::Null, Value::Undefined) => Ok(true.into()),
|
||||||
|
@ -416,8 +416,8 @@ impl<'gc> Value<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Coerce a value to a string.
|
/// Coerce a value to a string.
|
||||||
pub fn coerce_to_string<'a>(
|
pub fn coerce_to_string(
|
||||||
&'a self,
|
&self,
|
||||||
activation: &mut Activation<'_, '_, 'gc, '_>,
|
activation: &mut Activation<'_, '_, 'gc, '_>,
|
||||||
) -> Result<AvmString<'gc>, Error<'gc>> {
|
) -> Result<AvmString<'gc>, Error<'gc>> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
|
@ -436,8 +436,8 @@ impl<'gc> Value<'gc> {
|
||||||
Value::Bool(true) => "true".into(),
|
Value::Bool(true) => "true".into(),
|
||||||
Value::Bool(false) => "false".into(),
|
Value::Bool(false) => "false".into(),
|
||||||
Value::Number(v) => match f64_to_string(*v) {
|
Value::Number(v) => match f64_to_string(*v) {
|
||||||
Cow::Borrowed(str) => str.into(),
|
Cow::Borrowed(s) => s.into(),
|
||||||
Cow::Owned(str) => AvmString::new(activation.context.gc_context, str),
|
Cow::Owned(s) => AvmString::new(activation.context.gc_context, s),
|
||||||
},
|
},
|
||||||
Value::String(v) => v.to_owned(),
|
Value::String(v) => v.to_owned(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use crate::avm1;
|
use crate::avm1;
|
||||||
|
|
||||||
use crate::avm1::globals::system::SystemProperties;
|
use crate::avm1::globals::system::SystemProperties;
|
||||||
use crate::avm1::{Object, Timers, Value};
|
use crate::avm1::{Avm1, Object, Timers, Value};
|
||||||
use crate::backend::input::InputBackend;
|
use crate::backend::input::InputBackend;
|
||||||
use crate::backend::storage::StorageBackend;
|
use crate::backend::storage::StorageBackend;
|
||||||
use crate::backend::{audio::AudioBackend, navigator::NavigatorBackend, render::RenderBackend};
|
use crate::backend::{audio::AudioBackend, navigator::NavigatorBackend, render::RenderBackend};
|
||||||
|
@ -114,6 +114,9 @@ pub struct UpdateContext<'a, 'gc, 'gc_context> {
|
||||||
|
|
||||||
/// Timed callbacks created with `setInterval`/`setTimeout`.
|
/// Timed callbacks created with `setInterval`/`setTimeout`.
|
||||||
pub timers: &'a mut Timers<'gc>,
|
pub timers: &'a mut Timers<'gc>,
|
||||||
|
|
||||||
|
/// The AVM1 global state.
|
||||||
|
pub avm1: &'a mut Avm1<'gc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A queued ActionScript call.
|
/// A queued ActionScript call.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::avm1::{Avm1, Object, TObject, Value};
|
use crate::avm1::{Object, TObject, Value};
|
||||||
use crate::context::{RenderContext, UpdateContext};
|
use crate::context::{RenderContext, UpdateContext};
|
||||||
use crate::player::NEWEST_PLAYER_VERSION;
|
use crate::player::NEWEST_PLAYER_VERSION;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -723,14 +723,13 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug + Into<DisplayObject<'gc>>
|
||||||
/// so forth.
|
/// so forth.
|
||||||
fn handle_clip_event(
|
fn handle_clip_event(
|
||||||
&self,
|
&self,
|
||||||
_avm: &mut Avm1<'gc>,
|
|
||||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
_event: ClipEvent,
|
_event: ClipEvent,
|
||||||
) -> ClipEventResult {
|
) -> ClipEventResult {
|
||||||
ClipEventResult::NotHandled
|
ClipEventResult::NotHandled
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, _avm: &mut Avm1<'gc>, _context: &mut UpdateContext<'_, 'gc, '_>) {}
|
fn run_frame(&mut self, _context: &mut UpdateContext<'_, 'gc, '_>) {}
|
||||||
fn render(&self, _context: &mut RenderContext<'_, 'gc>) {}
|
fn render(&self, _context: &mut RenderContext<'_, 'gc>) {}
|
||||||
|
|
||||||
fn unload(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) {
|
fn unload(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) {
|
||||||
|
@ -834,7 +833,6 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug + Into<DisplayObject<'gc>>
|
||||||
|
|
||||||
fn mouse_pick(
|
fn mouse_pick(
|
||||||
&self,
|
&self,
|
||||||
_avm: &mut Avm1<'gc>,
|
|
||||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
_self_node: DisplayObject<'gc>,
|
_self_node: DisplayObject<'gc>,
|
||||||
_pos: (Twips, Twips),
|
_pos: (Twips, Twips),
|
||||||
|
@ -844,7 +842,6 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug + Into<DisplayObject<'gc>>
|
||||||
|
|
||||||
fn post_instantiation(
|
fn post_instantiation(
|
||||||
&mut self,
|
&mut self,
|
||||||
_avm: &mut Avm1<'gc>,
|
|
||||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
_display_object: DisplayObject<'gc>,
|
_display_object: DisplayObject<'gc>,
|
||||||
_init_object: Option<Object<'gc>>,
|
_init_object: Option<Object<'gc>>,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//! Bitmap display object
|
//! Bitmap display object
|
||||||
|
|
||||||
use crate::avm1::Avm1;
|
|
||||||
use crate::backend::render::BitmapHandle;
|
use crate::backend::render::BitmapHandle;
|
||||||
use crate::context::{RenderContext, UpdateContext};
|
use crate::context::{RenderContext, UpdateContext};
|
||||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||||
|
@ -80,7 +79,7 @@ impl<'gc> TDisplayObject<'gc> for Bitmap<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, _avm: &mut Avm1<'gc>, _context: &mut UpdateContext) {
|
fn run_frame(&mut self, _context: &mut UpdateContext) {
|
||||||
// Noop
|
// Noop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::avm1::{Avm1, Object, StageObject, Value};
|
use crate::avm1::{Object, StageObject, Value};
|
||||||
use crate::context::{ActionType, RenderContext, UpdateContext};
|
use crate::context::{ActionType, RenderContext, UpdateContext};
|
||||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||||
use crate::events::{ButtonKeyCode, ClipEvent, ClipEventResult};
|
use crate::events::{ButtonKeyCode, ClipEvent, ClipEventResult};
|
||||||
|
@ -119,7 +119,6 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
|
||||||
|
|
||||||
fn post_instantiation(
|
fn post_instantiation(
|
||||||
&mut self,
|
&mut self,
|
||||||
_avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
display_object: DisplayObject<'gc>,
|
display_object: DisplayObject<'gc>,
|
||||||
_init_object: Option<Object<'gc>>,
|
_init_object: Option<Object<'gc>>,
|
||||||
|
@ -138,10 +137,10 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, avm: &mut Avm1<'gc>, context: &mut UpdateContext<'_, 'gc, '_>) {
|
fn run_frame(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) {
|
||||||
self.0
|
self.0
|
||||||
.write(context.gc_context)
|
.write(context.gc_context)
|
||||||
.run_frame((*self).into(), avm, context)
|
.run_frame((*self).into(), context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, context: &mut RenderContext<'_, 'gc>) {
|
fn render(&self, context: &mut RenderContext<'_, 'gc>) {
|
||||||
|
@ -169,7 +168,6 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
|
||||||
|
|
||||||
fn mouse_pick(
|
fn mouse_pick(
|
||||||
&self,
|
&self,
|
||||||
_avm: &mut Avm1<'gc>,
|
|
||||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
self_node: DisplayObject<'gc>,
|
self_node: DisplayObject<'gc>,
|
||||||
point: (Twips, Twips),
|
point: (Twips, Twips),
|
||||||
|
@ -203,13 +201,12 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
|
||||||
/// so forth.
|
/// so forth.
|
||||||
fn handle_clip_event(
|
fn handle_clip_event(
|
||||||
&self,
|
&self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
event: ClipEvent,
|
event: ClipEvent,
|
||||||
) -> ClipEventResult {
|
) -> ClipEventResult {
|
||||||
if event.propagates() {
|
if event.propagates() {
|
||||||
for child in self.children() {
|
for child in self.children() {
|
||||||
if child.handle_clip_event(avm, context, event) == ClipEventResult::Handled {
|
if child.handle_clip_event(context, event) == ClipEventResult::Handled {
|
||||||
return ClipEventResult::Handled;
|
return ClipEventResult::Handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +214,7 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
|
||||||
|
|
||||||
self.0
|
self.0
|
||||||
.write(context.gc_context)
|
.write(context.gc_context)
|
||||||
.handle_clip_event((*self).into(), avm, context, event)
|
.handle_clip_event((*self).into(), context, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +222,6 @@ impl<'gc> ButtonData<'gc> {
|
||||||
fn set_state(
|
fn set_state(
|
||||||
&mut self,
|
&mut self,
|
||||||
self_display_object: DisplayObject<'gc>,
|
self_display_object: DisplayObject<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut crate::context::UpdateContext<'_, 'gc, '_>,
|
context: &mut crate::context::UpdateContext<'_, 'gc, '_>,
|
||||||
state: ButtonState,
|
state: ButtonState,
|
||||||
) {
|
) {
|
||||||
|
@ -250,8 +246,8 @@ impl<'gc> ButtonData<'gc> {
|
||||||
&record.color_transform.clone().into(),
|
&record.color_transform.clone().into(),
|
||||||
);
|
);
|
||||||
child.set_depth(context.gc_context, record.depth.into());
|
child.set_depth(context.gc_context, record.depth.into());
|
||||||
child.post_instantiation(avm, context, child, None, false);
|
child.post_instantiation(context, child, None, false);
|
||||||
child.run_frame(avm, context);
|
child.run_frame(context);
|
||||||
self.children.insert(record.depth.into(), child);
|
self.children.insert(record.depth.into(), child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,13 +257,12 @@ impl<'gc> ButtonData<'gc> {
|
||||||
fn run_frame(
|
fn run_frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
self_display_object: DisplayObject<'gc>,
|
self_display_object: DisplayObject<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
) {
|
) {
|
||||||
// TODO: Move this to post_instantiation.
|
// TODO: Move this to post_instantiation.
|
||||||
if !self.initialized {
|
if !self.initialized {
|
||||||
self.initialized = true;
|
self.initialized = true;
|
||||||
self.set_state(self_display_object, avm, context, ButtonState::Up);
|
self.set_state(self_display_object, context, ButtonState::Up);
|
||||||
|
|
||||||
for record in &self.static_data.read().records {
|
for record in &self.static_data.read().records {
|
||||||
if record.states.contains(&swf::ButtonState::HitTest) {
|
if record.states.contains(&swf::ButtonState::HitTest) {
|
||||||
|
@ -281,7 +276,7 @@ impl<'gc> ButtonData<'gc> {
|
||||||
child.set_matrix(context.gc_context, &record.matrix);
|
child.set_matrix(context.gc_context, &record.matrix);
|
||||||
child.set_parent(context.gc_context, Some(self_display_object));
|
child.set_parent(context.gc_context, Some(self_display_object));
|
||||||
child.set_depth(context.gc_context, record.depth.into());
|
child.set_depth(context.gc_context, record.depth.into());
|
||||||
child.post_instantiation(avm, context, child, None, false);
|
child.post_instantiation(context, child, None, false);
|
||||||
}
|
}
|
||||||
self.hit_area.insert(record.depth.into(), child);
|
self.hit_area.insert(record.depth.into(), child);
|
||||||
}
|
}
|
||||||
|
@ -299,14 +294,13 @@ impl<'gc> ButtonData<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for child in self.children.values_mut() {
|
for child in self.children.values_mut() {
|
||||||
child.run_frame(avm, context);
|
child.run_frame(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_clip_event(
|
fn handle_clip_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
self_display_object: DisplayObject<'gc>,
|
self_display_object: DisplayObject<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut crate::context::UpdateContext<'_, 'gc, '_>,
|
context: &mut crate::context::UpdateContext<'_, 'gc, '_>,
|
||||||
event: ClipEvent,
|
event: ClipEvent,
|
||||||
) -> ClipEventResult {
|
) -> ClipEventResult {
|
||||||
|
@ -366,7 +360,7 @@ impl<'gc> ButtonData<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_state(self_display_object, avm, context, new_state);
|
self.set_state(self_display_object, context, new_state);
|
||||||
|
|
||||||
handled
|
handled
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! `EditText` display object and support code.
|
//! `EditText` display object and support code.
|
||||||
use crate::avm1::activation::Activation;
|
use crate::avm1::activation::Activation;
|
||||||
use crate::avm1::globals::text_field::attach_virtual_properties;
|
use crate::avm1::globals::text_field::attach_virtual_properties;
|
||||||
use crate::avm1::{Avm1, AvmString, Object, StageObject, TObject, Value};
|
use crate::avm1::{AvmString, Object, StageObject, TObject, Value};
|
||||||
use crate::context::{RenderContext, UpdateContext};
|
use crate::context::{RenderContext, UpdateContext};
|
||||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||||
use crate::drawing::Drawing;
|
use crate::drawing::Drawing;
|
||||||
|
@ -838,7 +838,7 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
|
||||||
Some(self.0.read().static_data.swf.clone())
|
Some(self.0.read().static_data.swf.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, _avm: &mut Avm1<'gc>, _context: &mut UpdateContext) {
|
fn run_frame(&mut self, _context: &mut UpdateContext) {
|
||||||
// Noop
|
// Noop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +848,6 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
|
||||||
|
|
||||||
fn post_instantiation(
|
fn post_instantiation(
|
||||||
&mut self,
|
&mut self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
display_object: DisplayObject<'gc>,
|
display_object: DisplayObject<'gc>,
|
||||||
_init_object: Option<Object<'gc>>,
|
_init_object: Option<Object<'gc>>,
|
||||||
|
@ -887,7 +886,7 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
|
||||||
drop(text);
|
drop(text);
|
||||||
|
|
||||||
// If this text field has a variable set, initialize text field binding.
|
// If this text field has a variable set, initialize text field binding.
|
||||||
avm.run_with_stack_frame_for_display_object(
|
context.avm1.run_with_stack_frame_for_display_object(
|
||||||
(*self).into(),
|
(*self).into(),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
context,
|
context,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::avm1::Avm1;
|
|
||||||
use crate::backend::render::ShapeHandle;
|
use crate::backend::render::ShapeHandle;
|
||||||
use crate::context::{RenderContext, UpdateContext};
|
use crate::context::{RenderContext, UpdateContext};
|
||||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||||
|
@ -54,7 +53,7 @@ impl<'gc> TDisplayObject<'gc> for Graphic<'gc> {
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, _avm: &mut Avm1<'gc>, _context: &mut UpdateContext) {
|
fn run_frame(&mut self, _context: &mut UpdateContext) {
|
||||||
// Noop
|
// Noop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::avm1::Avm1;
|
|
||||||
use crate::backend::render::{RenderBackend, ShapeHandle};
|
use crate::backend::render::{RenderBackend, ShapeHandle};
|
||||||
use crate::context::{RenderContext, UpdateContext};
|
use crate::context::{RenderContext, UpdateContext};
|
||||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||||
|
@ -52,7 +51,7 @@ impl<'gc> TDisplayObject<'gc> for MorphShape<'gc> {
|
||||||
Some(*self)
|
Some(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, _avm: &mut Avm1<'gc>, _context: &mut UpdateContext) {
|
fn run_frame(&mut self, _context: &mut UpdateContext) {
|
||||||
// Noop
|
// Noop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
|
|
||||||
pub fn preload(
|
pub fn preload(
|
||||||
self,
|
self,
|
||||||
avm1: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
morph_shapes: &mut fnv::FnvHashMap<CharacterId, MorphShapeStatic>,
|
morph_shapes: &mut fnv::FnvHashMap<CharacterId, MorphShapeStatic>,
|
||||||
) {
|
) {
|
||||||
|
@ -250,7 +249,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
.write(context.gc_context)
|
.write(context.gc_context)
|
||||||
.define_sound(context, reader),
|
.define_sound(context, reader),
|
||||||
TagCode::DefineSprite => self.0.write(context.gc_context).define_sprite(
|
TagCode::DefineSprite => self.0.write(context.gc_context).define_sprite(
|
||||||
avm1,
|
|
||||||
context,
|
context,
|
||||||
reader,
|
reader,
|
||||||
tag_len,
|
tag_len,
|
||||||
|
@ -264,7 +262,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
.0
|
.0
|
||||||
.write(context.gc_context)
|
.write(context.gc_context)
|
||||||
.define_text(context, reader, 2),
|
.define_text(context, reader, 2),
|
||||||
TagCode::DoInitAction => self.do_init_action(avm1, context, reader, tag_len),
|
TagCode::DoInitAction => self.do_init_action(context, reader, tag_len),
|
||||||
TagCode::DoAbc => self.do_abc(context, reader, tag_len),
|
TagCode::DoAbc => self.do_abc(context, reader, tag_len),
|
||||||
TagCode::ExportAssets => self
|
TagCode::ExportAssets => self
|
||||||
.0
|
.0
|
||||||
|
@ -326,9 +324,10 @@ impl<'gc> MovieClip<'gc> {
|
||||||
reader,
|
reader,
|
||||||
&mut cur_frame,
|
&mut cur_frame,
|
||||||
),
|
),
|
||||||
TagCode::ScriptLimits => {
|
TagCode::ScriptLimits => self
|
||||||
self.0.write(context.gc_context).script_limits(reader, avm1)
|
.0
|
||||||
}
|
.write(context.gc_context)
|
||||||
|
.script_limits(reader, context.avm1),
|
||||||
TagCode::SoundStreamHead => self
|
TagCode::SoundStreamHead => self
|
||||||
.0
|
.0
|
||||||
.write(context.gc_context)
|
.write(context.gc_context)
|
||||||
|
@ -362,7 +361,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn do_init_action(
|
fn do_init_action(
|
||||||
self,
|
self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
reader: &mut SwfStream<&[u8]>,
|
reader: &mut SwfStream<&[u8]>,
|
||||||
tag_len: usize,
|
tag_len: usize,
|
||||||
|
@ -387,7 +385,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
avm.run_stack_frame_for_init_action(
|
context.avm1.run_stack_frame_for_init_action(
|
||||||
self.into(),
|
self.into(),
|
||||||
context.swf.header().version,
|
context.swf.header().version,
|
||||||
slice,
|
slice,
|
||||||
|
@ -442,9 +440,9 @@ impl<'gc> MovieClip<'gc> {
|
||||||
self.0.read().playing()
|
self.0.read().playing()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_frame(self, avm: &mut Avm1<'gc>, context: &mut UpdateContext<'_, 'gc, '_>) {
|
pub fn next_frame(self, context: &mut UpdateContext<'_, 'gc, '_>) {
|
||||||
if self.current_frame() < self.total_frames() {
|
if self.current_frame() < self.total_frames() {
|
||||||
self.goto_frame(avm, context, self.current_frame() + 1, true);
|
self.goto_frame(context, self.current_frame() + 1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,9 +450,9 @@ impl<'gc> MovieClip<'gc> {
|
||||||
self.0.write(context.gc_context).play()
|
self.0.write(context.gc_context).play()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev_frame(self, avm: &mut Avm1<'gc>, context: &mut UpdateContext<'_, 'gc, '_>) {
|
pub fn prev_frame(self, context: &mut UpdateContext<'_, 'gc, '_>) {
|
||||||
if self.current_frame() > 1 {
|
if self.current_frame() > 1 {
|
||||||
self.goto_frame(avm, context, self.current_frame() - 1, true);
|
self.goto_frame(context, self.current_frame() - 1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +464,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
/// `frame` should be 1-based.
|
/// `frame` should be 1-based.
|
||||||
pub fn goto_frame(
|
pub fn goto_frame(
|
||||||
self,
|
self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
mut frame: FrameNumber,
|
mut frame: FrameNumber,
|
||||||
stop: bool,
|
stop: bool,
|
||||||
|
@ -484,7 +481,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if frame != self.current_frame() {
|
if frame != self.current_frame() {
|
||||||
self.run_goto(self.into(), avm, context, frame);
|
self.run_goto(self.into(), context, frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +673,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
fn run_frame_internal(
|
fn run_frame_internal(
|
||||||
self,
|
self,
|
||||||
self_display_object: DisplayObject<'gc>,
|
self_display_object: DisplayObject<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
run_display_actions: bool,
|
run_display_actions: bool,
|
||||||
) {
|
) {
|
||||||
|
@ -687,7 +683,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
// Looping acts exactly like a gotoAndPlay(1).
|
// Looping acts exactly like a gotoAndPlay(1).
|
||||||
// Specifically, object that existed on frame 1 should not be destroyed
|
// Specifically, object that existed on frame 1 should not be destroyed
|
||||||
// and recreated.
|
// and recreated.
|
||||||
self.run_goto(self_display_object, avm, context, 1);
|
self.run_goto(self_display_object, context, 1);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Single frame clips do not play.
|
// Single frame clips do not play.
|
||||||
|
@ -711,16 +707,16 @@ impl<'gc> MovieClip<'gc> {
|
||||||
match tag_code {
|
match tag_code {
|
||||||
TagCode::DoAction => self.do_action(self_display_object, context, reader, tag_len),
|
TagCode::DoAction => self.do_action(self_display_object, context, reader, tag_len),
|
||||||
TagCode::PlaceObject if run_display_actions => {
|
TagCode::PlaceObject if run_display_actions => {
|
||||||
self.place_object(self_display_object, avm, context, reader, tag_len, 1)
|
self.place_object(self_display_object, context, reader, tag_len, 1)
|
||||||
}
|
}
|
||||||
TagCode::PlaceObject2 if run_display_actions => {
|
TagCode::PlaceObject2 if run_display_actions => {
|
||||||
self.place_object(self_display_object, avm, context, reader, tag_len, 2)
|
self.place_object(self_display_object, context, reader, tag_len, 2)
|
||||||
}
|
}
|
||||||
TagCode::PlaceObject3 if run_display_actions => {
|
TagCode::PlaceObject3 if run_display_actions => {
|
||||||
self.place_object(self_display_object, avm, context, reader, tag_len, 3)
|
self.place_object(self_display_object, context, reader, tag_len, 3)
|
||||||
}
|
}
|
||||||
TagCode::PlaceObject4 if run_display_actions => {
|
TagCode::PlaceObject4 if run_display_actions => {
|
||||||
self.place_object(self_display_object, avm, context, reader, tag_len, 4)
|
self.place_object(self_display_object, context, reader, tag_len, 4)
|
||||||
}
|
}
|
||||||
TagCode::RemoveObject if run_display_actions => {
|
TagCode::RemoveObject if run_display_actions => {
|
||||||
self.remove_object(context, reader, 1)
|
self.remove_object(context, reader, 1)
|
||||||
|
@ -751,7 +747,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
fn instantiate_child(
|
fn instantiate_child(
|
||||||
self,
|
self,
|
||||||
self_display_object: DisplayObject<'gc>,
|
self_display_object: DisplayObject<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
id: CharacterId,
|
id: CharacterId,
|
||||||
depth: Depth,
|
depth: Depth,
|
||||||
|
@ -786,8 +781,8 @@ impl<'gc> MovieClip<'gc> {
|
||||||
}
|
}
|
||||||
// Run first frame.
|
// Run first frame.
|
||||||
child.apply_place_object(context.gc_context, place_object);
|
child.apply_place_object(context.gc_context, place_object);
|
||||||
child.post_instantiation(avm, context, child, None, false);
|
child.post_instantiation(context, child, None, false);
|
||||||
child.run_frame(avm, context);
|
child.run_frame(context);
|
||||||
}
|
}
|
||||||
Some(child)
|
Some(child)
|
||||||
} else {
|
} else {
|
||||||
|
@ -799,7 +794,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
pub fn run_goto(
|
pub fn run_goto(
|
||||||
self,
|
self,
|
||||||
self_display_object: DisplayObject<'gc>,
|
self_display_object: DisplayObject<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
frame: FrameNumber,
|
frame: FrameNumber,
|
||||||
) {
|
) {
|
||||||
|
@ -943,7 +937,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
|
|
||||||
// Run the list of goto commands to actually create and update the display objects.
|
// Run the list of goto commands to actually create and update the display objects.
|
||||||
let run_goto_command = |clip: MovieClip<'gc>,
|
let run_goto_command = |clip: MovieClip<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
params: &GotoPlaceObject| {
|
params: &GotoPlaceObject| {
|
||||||
let child_entry = clip.0.read().children.get(¶ms.depth()).copied();
|
let child_entry = clip.0.read().children.get(¶ms.depth()).copied();
|
||||||
|
@ -961,7 +954,6 @@ impl<'gc> MovieClip<'gc> {
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(mut child) = clip.instantiate_child(
|
if let Some(mut child) = clip.instantiate_child(
|
||||||
self_display_object,
|
self_display_object,
|
||||||
avm,
|
|
||||||
context,
|
context,
|
||||||
params.id(),
|
params.id(),
|
||||||
params.depth(),
|
params.depth(),
|
||||||
|
@ -987,7 +979,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
goto_commands
|
goto_commands
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|params| params.frame < frame)
|
.filter(|params| params.frame < frame)
|
||||||
.for_each(|goto| run_goto_command(self, avm, context, goto));
|
.for_each(|goto| run_goto_command(self, context, goto));
|
||||||
|
|
||||||
// Next, run the final frame for the parent clip.
|
// Next, run the final frame for the parent clip.
|
||||||
// Re-run the final frame without display tags (DoAction, StartSound, etc.)
|
// Re-run the final frame without display tags (DoAction, StartSound, etc.)
|
||||||
|
@ -996,7 +988,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
if hit_target_frame {
|
if hit_target_frame {
|
||||||
self.0.write(context.gc_context).current_frame -= 1;
|
self.0.write(context.gc_context).current_frame -= 1;
|
||||||
self.0.write(context.gc_context).tag_stream_pos = frame_pos;
|
self.0.write(context.gc_context).tag_stream_pos = frame_pos;
|
||||||
self.run_frame_internal(self_display_object, avm, context, false);
|
self.run_frame_internal(self_display_object, context, false);
|
||||||
} else {
|
} else {
|
||||||
self.0.write(context.gc_context).current_frame = clamped_frame;
|
self.0.write(context.gc_context).current_frame = clamped_frame;
|
||||||
}
|
}
|
||||||
|
@ -1005,7 +997,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
goto_commands
|
goto_commands
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|params| params.frame >= frame)
|
.filter(|params| params.frame >= frame)
|
||||||
.for_each(|goto| run_goto_command(self, avm, context, goto));
|
.for_each(|goto| run_goto_command(self, context, goto));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,10 +1012,10 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
Some(self.0.read().movie())
|
Some(self.0.read().movie())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, avm: &mut Avm1<'gc>, context: &mut UpdateContext<'_, 'gc, '_>) {
|
fn run_frame(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) {
|
||||||
// Children must run first.
|
// Children must run first.
|
||||||
for mut child in self.children() {
|
for mut child in self.children() {
|
||||||
child.run_frame(avm, context);
|
child.run_frame(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run my load/enterFrame clip event.
|
// Run my load/enterFrame clip event.
|
||||||
|
@ -1039,7 +1031,7 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
|
|
||||||
// Run my SWF tags.
|
// Run my SWF tags.
|
||||||
if self.playing() {
|
if self.playing() {
|
||||||
self.run_frame_internal((*self).into(), avm, context, true);
|
self.run_frame_internal((*self).into(), context, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_load_frame {
|
if is_load_frame {
|
||||||
|
@ -1068,7 +1060,6 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
|
|
||||||
fn mouse_pick(
|
fn mouse_pick(
|
||||||
&self,
|
&self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
self_node: DisplayObject<'gc>,
|
self_node: DisplayObject<'gc>,
|
||||||
point: (Twips, Twips),
|
point: (Twips, Twips),
|
||||||
|
@ -1080,11 +1071,10 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Mouse Pick]"),
|
ActivationIdentifier::root("[Mouse Pick]"),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
avm.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
*context.levels.get(&0).unwrap(),
|
*context.levels.get(&0).unwrap(),
|
||||||
);
|
);
|
||||||
let object = self.object().coerce_to_object(&mut activation);
|
let object = self.object().coerce_to_object(&mut activation);
|
||||||
|
@ -1100,7 +1090,7 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
// Maybe we could skip recursing down at all if !world_bounds.contains(point),
|
// Maybe we could skip recursing down at all if !world_bounds.contains(point),
|
||||||
// but a child button can have an invisible hit area outside the parent's bounds.
|
// but a child button can have an invisible hit area outside the parent's bounds.
|
||||||
for child in self.0.read().children.values().rev() {
|
for child in self.0.read().children.values().rev() {
|
||||||
let result = child.mouse_pick(avm, context, *child, point);
|
let result = child.mouse_pick(context, *child, point);
|
||||||
if result.is_some() {
|
if result.is_some() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1112,13 +1102,12 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
|
|
||||||
fn handle_clip_event(
|
fn handle_clip_event(
|
||||||
&self,
|
&self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
event: ClipEvent,
|
event: ClipEvent,
|
||||||
) -> ClipEventResult {
|
) -> ClipEventResult {
|
||||||
if event.propagates() {
|
if event.propagates() {
|
||||||
for child in self.children() {
|
for child in self.children() {
|
||||||
if child.handle_clip_event(avm, context, event) == ClipEventResult::Handled {
|
if child.handle_clip_event(context, event) == ClipEventResult::Handled {
|
||||||
return ClipEventResult::Handled;
|
return ClipEventResult::Handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1133,7 +1122,6 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
|
|
||||||
fn post_instantiation(
|
fn post_instantiation(
|
||||||
&mut self,
|
&mut self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
display_object: DisplayObject<'gc>,
|
display_object: DisplayObject<'gc>,
|
||||||
init_object: Option<Object<'gc>>,
|
init_object: Option<Object<'gc>>,
|
||||||
|
@ -1146,11 +1134,10 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
// If we are not, then this must be queued to be ran first-thing
|
// If we are not, then this must be queued to be ran first-thing
|
||||||
if instantiated_from_avm && self.0.read().avm1_constructor.is_some() {
|
if instantiated_from_avm && self.0.read().avm1_constructor.is_some() {
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Construct]"),
|
ActivationIdentifier::root("[Construct]"),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
avm.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
(*self).into(),
|
(*self).into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1186,11 +1173,10 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
);
|
);
|
||||||
if let Some(init_object) = init_object {
|
if let Some(init_object) = init_object {
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Init]"),
|
ActivationIdentifier::root("[Init]"),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
avm.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
(*self).into(),
|
(*self).into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1224,7 +1210,7 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this text field has a variable set, initialize text field binding.
|
// If this text field has a variable set, initialize text field binding.
|
||||||
avm.run_with_stack_frame_for_display_object(
|
context.avm1.run_with_stack_frame_for_display_object(
|
||||||
(*self).into(),
|
(*self).into(),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
context,
|
context,
|
||||||
|
@ -2066,7 +2052,6 @@ impl<'gc, 'a> MovieClipData<'gc> {
|
||||||
|
|
||||||
fn define_sprite(
|
fn define_sprite(
|
||||||
&mut self,
|
&mut self,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
reader: &mut SwfStream<&'a [u8]>,
|
reader: &mut SwfStream<&'a [u8]>,
|
||||||
tag_len: usize,
|
tag_len: usize,
|
||||||
|
@ -2089,7 +2074,7 @@ impl<'gc, 'a> MovieClipData<'gc> {
|
||||||
num_frames,
|
num_frames,
|
||||||
);
|
);
|
||||||
|
|
||||||
movie_clip.preload(avm, context, morph_shapes);
|
movie_clip.preload(context, morph_shapes);
|
||||||
|
|
||||||
context
|
context
|
||||||
.library
|
.library
|
||||||
|
@ -2248,7 +2233,6 @@ impl<'gc, 'a> MovieClip<'gc> {
|
||||||
fn place_object(
|
fn place_object(
|
||||||
self,
|
self,
|
||||||
self_display_object: DisplayObject<'gc>,
|
self_display_object: DisplayObject<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
reader: &mut SwfStream<&'a [u8]>,
|
reader: &mut SwfStream<&'a [u8]>,
|
||||||
tag_len: usize,
|
tag_len: usize,
|
||||||
|
@ -2264,7 +2248,6 @@ impl<'gc, 'a> MovieClip<'gc> {
|
||||||
PlaceObjectAction::Place(id) | PlaceObjectAction::Replace(id) => {
|
PlaceObjectAction::Place(id) | PlaceObjectAction::Replace(id) => {
|
||||||
if let Some(child) = self.instantiate_child(
|
if let Some(child) = self.instantiate_child(
|
||||||
self_display_object,
|
self_display_object,
|
||||||
avm,
|
|
||||||
context,
|
context,
|
||||||
id,
|
id,
|
||||||
place_object.depth.into(),
|
place_object.depth.into(),
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::avm1::Avm1;
|
|
||||||
use crate::context::{RenderContext, UpdateContext};
|
use crate::context::{RenderContext, UpdateContext};
|
||||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -53,7 +52,7 @@ impl<'gc> TDisplayObject<'gc> for Text<'gc> {
|
||||||
Some(self.0.read().static_data.swf.clone())
|
Some(self.0.read().static_data.swf.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_frame(&mut self, _avm: &mut Avm1<'gc>, _context: &mut UpdateContext) {
|
fn run_frame(&mut self, _context: &mut UpdateContext) {
|
||||||
// Noop
|
// Noop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ impl TextFormat {
|
||||||
) -> Result<Object<'gc>, crate::avm1::error::Error<'gc>> {
|
) -> Result<Object<'gc>, crate::avm1::error::Error<'gc>> {
|
||||||
let object = ScriptObject::object(
|
let object = ScriptObject::object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().text_format),
|
Some(activation.context.avm1.prototypes().text_format),
|
||||||
);
|
);
|
||||||
|
|
||||||
object.set(
|
object.set(
|
||||||
|
@ -469,7 +469,7 @@ impl TextFormat {
|
||||||
if let Some(ts) = &self.tab_stops {
|
if let Some(ts) = &self.tab_stops {
|
||||||
let tab_stops = ScriptObject::array(
|
let tab_stops = ScriptObject::array(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
Some(activation.avm.prototypes().array),
|
Some(activation.context.avm1.prototypes().array),
|
||||||
);
|
);
|
||||||
|
|
||||||
tab_stops.set_length(activation.context.gc_context, ts.len());
|
tab_stops.set_length(activation.context.gc_context, ts.len());
|
||||||
|
|
|
@ -372,7 +372,7 @@ impl<'gc> Loader<'gc> {
|
||||||
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
player.lock().expect("Could not lock player!!").update(
|
player.lock().expect("Could not lock player!!").update(
|
||||||
|_avm1, _avm2, uc| -> Result<(), Error> {
|
|_avm2, uc| -> Result<(), Error> {
|
||||||
url = uc.navigator.resolve_relative_url(&url).into_owned();
|
url = uc.navigator.resolve_relative_url(&url).into_owned();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -416,7 +416,7 @@ impl<'gc> Loader<'gc> {
|
||||||
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
player.lock().expect("Could not lock player!!").update(
|
player.lock().expect("Could not lock player!!").update(
|
||||||
|avm1, _avm2, uc| -> Result<(), Error> {
|
|_avm2, uc| -> Result<(), Error> {
|
||||||
url = uc.navigator.resolve_relative_url(&url).into_owned();
|
url = uc.navigator.resolve_relative_url(&url).into_owned();
|
||||||
|
|
||||||
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
||||||
|
@ -436,7 +436,7 @@ impl<'gc> Loader<'gc> {
|
||||||
.replace_with_movie(uc.gc_context, None);
|
.replace_with_movie(uc.gc_context, None);
|
||||||
|
|
||||||
if let Some(broadcaster) = broadcaster {
|
if let Some(broadcaster) = broadcaster {
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
clip,
|
clip,
|
||||||
broadcaster,
|
broadcaster,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
@ -458,7 +458,7 @@ impl<'gc> Loader<'gc> {
|
||||||
player
|
player
|
||||||
.lock()
|
.lock()
|
||||||
.expect("Could not lock player!!")
|
.expect("Could not lock player!!")
|
||||||
.update(|avm1, _avm2, uc| {
|
.update(|_avm2, uc| {
|
||||||
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
|
@ -470,7 +470,7 @@ impl<'gc> Loader<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(broadcaster) = broadcaster {
|
if let Some(broadcaster) = broadcaster {
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
clip,
|
clip,
|
||||||
broadcaster,
|
broadcaster,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
@ -490,10 +490,10 @@ impl<'gc> Loader<'gc> {
|
||||||
.expect("Attempted to load movie into not movie clip");
|
.expect("Attempted to load movie into not movie clip");
|
||||||
|
|
||||||
mc.replace_with_movie(uc.gc_context, Some(movie.clone()));
|
mc.replace_with_movie(uc.gc_context, Some(movie.clone()));
|
||||||
mc.post_instantiation(avm1, uc, clip, None, false);
|
mc.post_instantiation(uc, clip, None, false);
|
||||||
|
|
||||||
let mut morph_shapes = fnv::FnvHashMap::default();
|
let mut morph_shapes = fnv::FnvHashMap::default();
|
||||||
mc.preload(avm1, uc, &mut morph_shapes);
|
mc.preload(uc, &mut morph_shapes);
|
||||||
|
|
||||||
// Finalize morph shapes.
|
// Finalize morph shapes.
|
||||||
for (id, static_data) in morph_shapes {
|
for (id, static_data) in morph_shapes {
|
||||||
|
@ -507,7 +507,7 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(broadcaster) = broadcaster {
|
if let Some(broadcaster) = broadcaster {
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
clip,
|
clip,
|
||||||
broadcaster,
|
broadcaster,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
@ -532,7 +532,7 @@ impl<'gc> Loader<'gc> {
|
||||||
//This also can get errors from decoding an invalid SWF file,
|
//This also can get errors from decoding an invalid SWF file,
|
||||||
//too. We should distinguish those to player code.
|
//too. We should distinguish those to player code.
|
||||||
player.lock().expect("Could not lock player!!").update(
|
player.lock().expect("Could not lock player!!").update(
|
||||||
|avm1, _avm2, uc| -> Result<(), Error> {
|
|_avm2, uc| -> Result<(), Error> {
|
||||||
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
|
@ -544,7 +544,7 @@ impl<'gc> Loader<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(broadcaster) = broadcaster {
|
if let Some(broadcaster) = broadcaster {
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
clip,
|
clip,
|
||||||
broadcaster,
|
broadcaster,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
@ -589,7 +589,7 @@ impl<'gc> Loader<'gc> {
|
||||||
let data = fetch.await?;
|
let data = fetch.await?;
|
||||||
|
|
||||||
// Fire the load handler.
|
// Fire the load handler.
|
||||||
player.lock().unwrap().update(|avm1, _avm2, uc| {
|
player.lock().unwrap().update(|_avm2, uc| {
|
||||||
let loader = uc.load_manager.get_loader(handle);
|
let loader = uc.load_manager.get_loader(handle);
|
||||||
let that = match loader {
|
let that = match loader {
|
||||||
Some(&Loader::Form { target_object, .. }) => target_object,
|
Some(&Loader::Form { target_object, .. }) => target_object,
|
||||||
|
@ -598,11 +598,10 @@ impl<'gc> Loader<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm1,
|
|
||||||
uc,
|
uc,
|
||||||
ActivationIdentifier::root("[Form Loader]"),
|
ActivationIdentifier::root("[Form Loader]"),
|
||||||
uc.swf.version(),
|
uc.swf.version(),
|
||||||
avm1.global_object_cell(),
|
uc.avm1.global_object_cell(),
|
||||||
*uc.levels.get(&0).unwrap(),
|
*uc.levels.get(&0).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -640,7 +639,7 @@ impl<'gc> Loader<'gc> {
|
||||||
let data = fetch.await;
|
let data = fetch.await;
|
||||||
|
|
||||||
// Fire the load handler.
|
// Fire the load handler.
|
||||||
player.lock().unwrap().update(|avm1, _avm2, uc| {
|
player.lock().unwrap().update(|_avm2, uc| {
|
||||||
let loader = uc.load_manager.get_loader(handle);
|
let loader = uc.load_manager.get_loader(handle);
|
||||||
let that = match loader {
|
let that = match loader {
|
||||||
Some(&Loader::LoadVars { target_object, .. }) => target_object,
|
Some(&Loader::LoadVars { target_object, .. }) => target_object,
|
||||||
|
@ -649,11 +648,10 @@ impl<'gc> Loader<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm1,
|
|
||||||
uc,
|
uc,
|
||||||
ActivationIdentifier::root("[Form Loader]"),
|
ActivationIdentifier::root("[Form Loader]"),
|
||||||
uc.swf.version(),
|
uc.swf.version(),
|
||||||
avm1.global_object_cell(),
|
uc.avm1.global_object_cell(),
|
||||||
*uc.levels.get(&0).unwrap(),
|
*uc.levels.get(&0).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -744,7 +742,7 @@ impl<'gc> Loader<'gc> {
|
||||||
let xmlstring = String::from_utf8(data)?;
|
let xmlstring = String::from_utf8(data)?;
|
||||||
|
|
||||||
player.lock().expect("Could not lock player!!").update(
|
player.lock().expect("Could not lock player!!").update(
|
||||||
|avm1, _avm2, uc| -> Result<(), Error> {
|
|_avm2, uc| -> Result<(), Error> {
|
||||||
let (mut node, active_clip) = match uc.load_manager.get_loader(handle) {
|
let (mut node, active_clip) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::XML {
|
Some(Loader::XML {
|
||||||
target_node,
|
target_node,
|
||||||
|
@ -756,8 +754,8 @@ impl<'gc> Loader<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let object =
|
let object =
|
||||||
node.script_object(uc.gc_context, Some(avm1.prototypes().xml_node));
|
node.script_object(uc.gc_context, Some(uc.avm1.prototypes().xml_node));
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
active_clip,
|
active_clip,
|
||||||
object,
|
object,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
@ -766,7 +764,7 @@ impl<'gc> Loader<'gc> {
|
||||||
&[200.into()],
|
&[200.into()],
|
||||||
);
|
);
|
||||||
|
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
active_clip,
|
active_clip,
|
||||||
object,
|
object,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
@ -780,7 +778,7 @@ impl<'gc> Loader<'gc> {
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
player.lock().expect("Could not lock player!!").update(
|
player.lock().expect("Could not lock player!!").update(
|
||||||
|avm1, _avm2, uc| -> Result<(), Error> {
|
|_avm2, uc| -> Result<(), Error> {
|
||||||
let (mut node, active_clip) = match uc.load_manager.get_loader(handle) {
|
let (mut node, active_clip) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::XML {
|
Some(Loader::XML {
|
||||||
target_node,
|
target_node,
|
||||||
|
@ -792,9 +790,9 @@ impl<'gc> Loader<'gc> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let object =
|
let object =
|
||||||
node.script_object(uc.gc_context, Some(avm1.prototypes().xml_node));
|
node.script_object(uc.gc_context, Some(uc.avm1.prototypes().xml_node));
|
||||||
|
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
active_clip,
|
active_clip,
|
||||||
object,
|
object,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
@ -803,7 +801,7 @@ impl<'gc> Loader<'gc> {
|
||||||
&[404.into()],
|
&[404.into()],
|
||||||
);
|
);
|
||||||
|
|
||||||
avm1.run_stack_frame_for_method(
|
uc.avm1.run_stack_frame_for_method(
|
||||||
active_clip,
|
active_clip,
|
||||||
object,
|
object,
|
||||||
NEWEST_PLAYER_VERSION,
|
NEWEST_PLAYER_VERSION,
|
||||||
|
|
|
@ -275,7 +275,7 @@ impl Player {
|
||||||
/// This should not be called if a root movie fetch has already been kicked
|
/// This should not be called if a root movie fetch has already been kicked
|
||||||
/// off.
|
/// off.
|
||||||
pub fn fetch_root_movie(&mut self, movie_url: &str) {
|
pub fn fetch_root_movie(&mut self, movie_url: &str) {
|
||||||
self.mutate_with_update_context(|_avm1, _avm2, context| {
|
self.mutate_with_update_context(|_avm2, context| {
|
||||||
let fetch = context.navigator.fetch(movie_url, RequestOptions::get());
|
let fetch = context.navigator.fetch(movie_url, RequestOptions::get());
|
||||||
let process = context.load_manager.load_root_movie(
|
let process = context.load_manager.load_root_movie(
|
||||||
context.player.clone().unwrap(),
|
context.player.clone().unwrap(),
|
||||||
|
@ -305,11 +305,11 @@ impl Player {
|
||||||
self.frame_rate = movie.header().frame_rate.into();
|
self.frame_rate = movie.header().frame_rate.into();
|
||||||
self.swf = movie;
|
self.swf = movie;
|
||||||
|
|
||||||
self.mutate_with_update_context(|avm1, _avm2, context| {
|
self.mutate_with_update_context(|_avm2, context| {
|
||||||
let mut root: DisplayObject =
|
let mut root: DisplayObject =
|
||||||
MovieClip::from_movie(context.gc_context, context.swf.clone()).into();
|
MovieClip::from_movie(context.gc_context, context.swf.clone()).into();
|
||||||
root.set_depth(context.gc_context, 0);
|
root.set_depth(context.gc_context, 0);
|
||||||
root.post_instantiation(avm1, context, root, None, false);
|
root.post_instantiation(context, root, None, false);
|
||||||
root.set_name(context.gc_context, "");
|
root.set_name(context.gc_context, "");
|
||||||
context.levels.insert(0, root);
|
context.levels.insert(0, root);
|
||||||
|
|
||||||
|
@ -331,15 +331,17 @@ impl Player {
|
||||||
|
|
||||||
// Set the version parameter on the root.
|
// Set the version parameter on the root.
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm1,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Version Setter]"),
|
ActivationIdentifier::root("[Version Setter]"),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
avm1.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
*context.levels.get(&0).unwrap(),
|
*context.levels.get(&0).unwrap(),
|
||||||
);
|
);
|
||||||
let object = root.object().coerce_to_object(&mut activation);
|
let object = root.object().coerce_to_object(&mut activation);
|
||||||
let version_string = activation.context.system.get_version_string(activation.avm);
|
let version_string = activation
|
||||||
|
.context
|
||||||
|
.system
|
||||||
|
.get_version_string(activation.context.avm1);
|
||||||
object.define_value(
|
object.define_value(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
"$version",
|
"$version",
|
||||||
|
@ -448,22 +450,21 @@ impl Player {
|
||||||
{
|
{
|
||||||
if self.input.is_key_down(KeyCode::Control) && self.input.is_key_down(KeyCode::Alt)
|
if self.input.is_key_down(KeyCode::Control) && self.input.is_key_down(KeyCode::Alt)
|
||||||
{
|
{
|
||||||
self.mutate_with_update_context(|avm1, _avm2, context| {
|
self.mutate_with_update_context(|_avm2, context| {
|
||||||
let mut dumper = VariableDumper::new(" ");
|
let mut dumper = VariableDumper::new(" ");
|
||||||
|
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm1,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Variable Dumper]"),
|
ActivationIdentifier::root("[Variable Dumper]"),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
avm1.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
*context.levels.get(&0).unwrap(),
|
*context.levels.get(&0).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
dumper.print_variables(
|
dumper.print_variables(
|
||||||
"Global Variables:",
|
"Global Variables:",
|
||||||
"_global",
|
"_global",
|
||||||
&activation.avm.global_object_cell(),
|
&activation.context.avm1.global_object_cell(),
|
||||||
&mut activation,
|
&mut activation,
|
||||||
);
|
);
|
||||||
let levels = context.levels.clone();
|
let levels = context.levels.clone();
|
||||||
|
@ -487,18 +488,18 @@ impl Player {
|
||||||
{
|
{
|
||||||
if self.input.is_key_down(KeyCode::Control) && self.input.is_key_down(KeyCode::Alt)
|
if self.input.is_key_down(KeyCode::Control) && self.input.is_key_down(KeyCode::Alt)
|
||||||
{
|
{
|
||||||
self.mutate_with_update_context(|avm1, avm2, _context| {
|
self.mutate_with_update_context(|avm2, context| {
|
||||||
if avm1.show_debug_output() {
|
if context.avm1.show_debug_output() {
|
||||||
log::info!(
|
log::info!(
|
||||||
"AVM Debugging turned off! Press CTRL+ALT+D to turn off again."
|
"AVM Debugging turned off! Press CTRL+ALT+D to turn off again."
|
||||||
);
|
);
|
||||||
avm1.set_show_debug_output(false);
|
context.avm1.set_show_debug_output(false);
|
||||||
avm2.set_show_debug_output(false);
|
avm2.set_show_debug_output(false);
|
||||||
} else {
|
} else {
|
||||||
log::info!(
|
log::info!(
|
||||||
"AVM Debugging turned on! Press CTRL+ALT+D to turn on again."
|
"AVM Debugging turned on! Press CTRL+ALT+D to turn on again."
|
||||||
);
|
);
|
||||||
avm1.set_show_debug_output(true);
|
context.avm1.set_show_debug_output(true);
|
||||||
avm2.set_show_debug_output(true);
|
avm2.set_show_debug_output(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -541,11 +542,11 @@ impl Player {
|
||||||
};
|
};
|
||||||
|
|
||||||
if button_event.is_some() {
|
if button_event.is_some() {
|
||||||
self.mutate_with_update_context(|avm1, _avm2, context| {
|
self.mutate_with_update_context(|_avm2, context| {
|
||||||
let levels: Vec<DisplayObject<'_>> = context.levels.values().copied().collect();
|
let levels: Vec<DisplayObject<'_>> = context.levels.values().copied().collect();
|
||||||
for level in levels {
|
for level in levels {
|
||||||
if let Some(button_event) = button_event {
|
if let Some(button_event) = button_event {
|
||||||
let state = level.handle_clip_event(avm1, context, button_event);
|
let state = level.handle_clip_event(context, button_event);
|
||||||
if state == ClipEventResult::Handled {
|
if state == ClipEventResult::Handled {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -569,12 +570,12 @@ impl Player {
|
||||||
};
|
};
|
||||||
|
|
||||||
if clip_event.is_some() || listener.is_some() {
|
if clip_event.is_some() || listener.is_some() {
|
||||||
self.mutate_with_update_context(|avm1, _avm2, context| {
|
self.mutate_with_update_context(|_avm2, context| {
|
||||||
let levels: Vec<DisplayObject<'_>> = context.levels.values().copied().collect();
|
let levels: Vec<DisplayObject<'_>> = context.levels.values().copied().collect();
|
||||||
|
|
||||||
for level in levels {
|
for level in levels {
|
||||||
if let Some(clip_event) = clip_event {
|
if let Some(clip_event) = clip_event {
|
||||||
level.handle_clip_event(avm1, context, clip_event);
|
level.handle_clip_event(context, clip_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,7 +594,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut is_mouse_down = self.is_mouse_down;
|
let mut is_mouse_down = self.is_mouse_down;
|
||||||
self.mutate_with_update_context(|avm1, avm2, context| {
|
self.mutate_with_update_context(|avm2, context| {
|
||||||
if let Some(node) = context.mouse_hovered_object {
|
if let Some(node) = context.mouse_hovered_object {
|
||||||
if node.removed() {
|
if node.removed() {
|
||||||
context.mouse_hovered_object = None;
|
context.mouse_hovered_object = None;
|
||||||
|
@ -605,7 +606,7 @@ impl Player {
|
||||||
is_mouse_down = true;
|
is_mouse_down = true;
|
||||||
needs_render = true;
|
needs_render = true;
|
||||||
if let Some(node) = context.mouse_hovered_object {
|
if let Some(node) = context.mouse_hovered_object {
|
||||||
node.handle_clip_event(avm1, context, ClipEvent::Press);
|
node.handle_clip_event(context, ClipEvent::Press);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,14 +614,14 @@ impl Player {
|
||||||
is_mouse_down = false;
|
is_mouse_down = false;
|
||||||
needs_render = true;
|
needs_render = true;
|
||||||
if let Some(node) = context.mouse_hovered_object {
|
if let Some(node) = context.mouse_hovered_object {
|
||||||
node.handle_clip_event(avm1, context, ClipEvent::Release);
|
node.handle_clip_event(context, ClipEvent::Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::run_actions(avm1, avm2, context);
|
Self::run_actions(avm2, context);
|
||||||
});
|
});
|
||||||
self.is_mouse_down = is_mouse_down;
|
self.is_mouse_down = is_mouse_down;
|
||||||
if needs_render {
|
if needs_render {
|
||||||
|
@ -631,7 +632,7 @@ impl Player {
|
||||||
/// Update dragged object, if any.
|
/// Update dragged object, if any.
|
||||||
fn update_drag(&mut self) {
|
fn update_drag(&mut self) {
|
||||||
let mouse_pos = self.mouse_pos;
|
let mouse_pos = self.mouse_pos;
|
||||||
self.mutate_with_update_context(|_avm1, _avm2, context| {
|
self.mutate_with_update_context(|_avm2, context| {
|
||||||
if let Some(drag_object) = &mut context.drag_object {
|
if let Some(drag_object) = &mut context.drag_object {
|
||||||
if drag_object.display_object.removed() {
|
if drag_object.display_object.removed() {
|
||||||
// Be sure to clear the drag if the object was removed.
|
// Be sure to clear the drag if the object was removed.
|
||||||
|
@ -666,13 +667,12 @@ impl Player {
|
||||||
let mouse_pos = self.mouse_pos;
|
let mouse_pos = self.mouse_pos;
|
||||||
|
|
||||||
let mut new_cursor = self.mouse_cursor;
|
let mut new_cursor = self.mouse_cursor;
|
||||||
let hover_changed = self.mutate_with_update_context(|avm1, avm2, context| {
|
let hover_changed = self.mutate_with_update_context(|avm2, context| {
|
||||||
// Check hovered object.
|
// Check hovered object.
|
||||||
let mut new_hovered = None;
|
let mut new_hovered = None;
|
||||||
for (_depth, level) in context.levels.clone().iter().rev() {
|
for (_depth, level) in context.levels.clone().iter().rev() {
|
||||||
if new_hovered.is_none() {
|
if new_hovered.is_none() {
|
||||||
new_hovered =
|
new_hovered = level.mouse_pick(context, *level, (mouse_pos.0, mouse_pos.1));
|
||||||
level.mouse_pick(avm1, context, *level, (mouse_pos.0, mouse_pos.1));
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -684,7 +684,7 @@ impl Player {
|
||||||
// RollOut of previous node.
|
// RollOut of previous node.
|
||||||
if let Some(node) = cur_hovered {
|
if let Some(node) = cur_hovered {
|
||||||
if !node.removed() {
|
if !node.removed() {
|
||||||
node.handle_clip_event(avm1, context, ClipEvent::RollOut);
|
node.handle_clip_event(context, ClipEvent::RollOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,12 +692,12 @@ impl Player {
|
||||||
new_cursor = MouseCursor::Arrow;
|
new_cursor = MouseCursor::Arrow;
|
||||||
if let Some(node) = new_hovered {
|
if let Some(node) = new_hovered {
|
||||||
new_cursor = MouseCursor::Hand;
|
new_cursor = MouseCursor::Hand;
|
||||||
node.handle_clip_event(avm1, context, ClipEvent::RollOver);
|
node.handle_clip_event(context, ClipEvent::RollOver);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.mouse_hovered_object = new_hovered;
|
context.mouse_hovered_object = new_hovered;
|
||||||
|
|
||||||
Self::run_actions(avm1, avm2, context);
|
Self::run_actions(avm2, context);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -718,12 +718,12 @@ impl Player {
|
||||||
/// This should only be called once. Further movie loads should preload the
|
/// This should only be called once. Further movie loads should preload the
|
||||||
/// specific `MovieClip` referenced.
|
/// specific `MovieClip` referenced.
|
||||||
fn preload(&mut self) {
|
fn preload(&mut self) {
|
||||||
self.mutate_with_update_context(|avm1, _avm2, context| {
|
self.mutate_with_update_context(|_avm2, context| {
|
||||||
let mut morph_shapes = fnv::FnvHashMap::default();
|
let mut morph_shapes = fnv::FnvHashMap::default();
|
||||||
let root = *context.levels.get(&0).expect("root level");
|
let root = *context.levels.get(&0).expect("root level");
|
||||||
root.as_movie_clip()
|
root.as_movie_clip()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.preload(avm1, context, &mut morph_shapes);
|
.preload(context, &mut morph_shapes);
|
||||||
|
|
||||||
// Finalize morph shapes.
|
// Finalize morph shapes.
|
||||||
for (id, static_data) in morph_shapes {
|
for (id, static_data) in morph_shapes {
|
||||||
|
@ -737,7 +737,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_frame(&mut self) {
|
pub fn run_frame(&mut self) {
|
||||||
self.update(|avm1, _avm2, update_context| {
|
self.update(|_avm2, update_context| {
|
||||||
// TODO: In what order are levels run?
|
// TODO: In what order are levels run?
|
||||||
// NOTE: We have to copy all the layer pointers into a separate list
|
// NOTE: We have to copy all the layer pointers into a separate list
|
||||||
// because level updates can create more levels, which we don't
|
// because level updates can create more levels, which we don't
|
||||||
|
@ -745,7 +745,7 @@ impl Player {
|
||||||
let levels: Vec<_> = update_context.levels.values().copied().collect();
|
let levels: Vec<_> = update_context.levels.values().copied().collect();
|
||||||
|
|
||||||
for mut level in levels {
|
for mut level in levels {
|
||||||
level.run_frame(avm1, update_context);
|
level.run_frame(update_context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.needs_render = true;
|
self.needs_render = true;
|
||||||
|
@ -818,11 +818,7 @@ impl Player {
|
||||||
self.input.deref_mut()
|
self.input.deref_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_actions<'gc>(
|
fn run_actions<'gc>(avm2: &mut Avm2<'gc>, context: &mut UpdateContext<'_, 'gc, '_>) {
|
||||||
avm1: &mut Avm1<'gc>,
|
|
||||||
avm2: &mut Avm2<'gc>,
|
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
|
||||||
) {
|
|
||||||
// Note that actions can queue further actions, so a while loop is necessary here.
|
// Note that actions can queue further actions, so a while loop is necessary here.
|
||||||
while let Some(actions) = context.action_queue.pop_action() {
|
while let Some(actions) = context.action_queue.pop_action() {
|
||||||
// We don't run frame actions if the clip was removed after it queued the action.
|
// We don't run frame actions if the clip was removed after it queued the action.
|
||||||
|
@ -833,7 +829,7 @@ impl Player {
|
||||||
match actions.action_type {
|
match actions.action_type {
|
||||||
// DoAction/clip event code
|
// DoAction/clip event code
|
||||||
ActionType::Normal { bytecode } => {
|
ActionType::Normal { bytecode } => {
|
||||||
avm1.run_stack_frame_for_action(
|
context.avm1.run_stack_frame_for_action(
|
||||||
actions.clip,
|
actions.clip,
|
||||||
"[Frame]",
|
"[Frame]",
|
||||||
context.swf.header().version,
|
context.swf.header().version,
|
||||||
|
@ -847,11 +843,10 @@ impl Player {
|
||||||
events,
|
events,
|
||||||
} => {
|
} => {
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm1,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Construct]"),
|
ActivationIdentifier::root("[Construct]"),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
avm1.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
actions.clip,
|
actions.clip,
|
||||||
);
|
);
|
||||||
if let Ok(prototype) = constructor
|
if let Ok(prototype) = constructor
|
||||||
|
@ -879,7 +874,7 @@ impl Player {
|
||||||
events,
|
events,
|
||||||
} => {
|
} => {
|
||||||
for event in events {
|
for event in events {
|
||||||
avm1.run_stack_frame_for_action(
|
context.avm1.run_stack_frame_for_action(
|
||||||
actions.clip,
|
actions.clip,
|
||||||
"[Construct]",
|
"[Construct]",
|
||||||
context.swf.header().version,
|
context.swf.header().version,
|
||||||
|
@ -890,7 +885,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
// Event handler method call (e.g. onEnterFrame)
|
// Event handler method call (e.g. onEnterFrame)
|
||||||
ActionType::Method { object, name, args } => {
|
ActionType::Method { object, name, args } => {
|
||||||
avm1.run_stack_frame_for_method(
|
context.avm1.run_stack_frame_for_method(
|
||||||
actions.clip,
|
actions.clip,
|
||||||
object,
|
object,
|
||||||
context.swf.header().version,
|
context.swf.header().version,
|
||||||
|
@ -908,7 +903,7 @@ impl Player {
|
||||||
} => {
|
} => {
|
||||||
// A native function ends up resolving immediately,
|
// A native function ends up resolving immediately,
|
||||||
// so this doesn't require any further execution.
|
// so this doesn't require any further execution.
|
||||||
avm1.notify_system_listeners(
|
context.avm1.notify_system_listeners(
|
||||||
actions.clip,
|
actions.clip,
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
context,
|
context,
|
||||||
|
@ -973,11 +968,7 @@ impl Player {
|
||||||
/// This takes cares of populating the `UpdateContext` struct, avoiding borrow issues.
|
/// This takes cares of populating the `UpdateContext` struct, avoiding borrow issues.
|
||||||
fn mutate_with_update_context<F, R>(&mut self, f: F) -> R
|
fn mutate_with_update_context<F, R>(&mut self, f: F) -> R
|
||||||
where
|
where
|
||||||
F: for<'a, 'gc> FnOnce(
|
F: for<'a, 'gc> FnOnce(&mut Avm2<'gc>, &mut UpdateContext<'a, 'gc, '_>) -> R,
|
||||||
&mut Avm1<'gc>,
|
|
||||||
&mut Avm2<'gc>,
|
|
||||||
&mut UpdateContext<'a, 'gc, '_>,
|
|
||||||
) -> R,
|
|
||||||
{
|
{
|
||||||
// We have to do this piecewise borrowing of fields before the closure to avoid
|
// We have to do this piecewise borrowing of fields before the closure to avoid
|
||||||
// completely borrowing `self`.
|
// completely borrowing `self`.
|
||||||
|
@ -1060,9 +1051,10 @@ impl Player {
|
||||||
unbound_text_fields,
|
unbound_text_fields,
|
||||||
timers,
|
timers,
|
||||||
needs_render,
|
needs_render,
|
||||||
|
avm1,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret = f(avm1, avm2, &mut update_context);
|
let ret = f(avm2, &mut update_context);
|
||||||
|
|
||||||
// Hovered object may have been updated; copy it back to the GC root.
|
// Hovered object may have been updated; copy it back to the GC root.
|
||||||
root_data.mouse_hovered_object = update_context.mouse_hovered_object;
|
root_data.mouse_hovered_object = update_context.mouse_hovered_object;
|
||||||
|
@ -1095,15 +1087,14 @@ impl Player {
|
||||||
pub fn update<F, R>(&mut self, func: F) -> R
|
pub fn update<F, R>(&mut self, func: F) -> R
|
||||||
where
|
where
|
||||||
F: for<'a, 'gc, 'gc_context> FnOnce(
|
F: for<'a, 'gc, 'gc_context> FnOnce(
|
||||||
&mut Avm1<'gc>,
|
|
||||||
&mut Avm2<'gc>,
|
&mut Avm2<'gc>,
|
||||||
&mut UpdateContext<'a, 'gc, 'gc_context>,
|
&mut UpdateContext<'a, 'gc, 'gc_context>,
|
||||||
) -> R,
|
) -> R,
|
||||||
{
|
{
|
||||||
let rval = self.mutate_with_update_context(|avm1, avm2, context| {
|
let rval = self.mutate_with_update_context(|avm2, context| {
|
||||||
let rval = func(avm1, avm2, context);
|
let rval = func(avm2, context);
|
||||||
|
|
||||||
Self::run_actions(avm1, avm2, context);
|
Self::run_actions(avm2, context);
|
||||||
|
|
||||||
rval
|
rval
|
||||||
});
|
});
|
||||||
|
@ -1119,13 +1110,12 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flush_shared_objects(&mut self) {
|
pub fn flush_shared_objects(&mut self) {
|
||||||
self.update(|avm1, _avm2, context| {
|
self.update(|_avm2, context| {
|
||||||
let mut activation = Activation::from_nothing(
|
let mut activation = Activation::from_nothing(
|
||||||
avm1,
|
|
||||||
context,
|
context,
|
||||||
ActivationIdentifier::root("[Flush]"),
|
ActivationIdentifier::root("[Flush]"),
|
||||||
context.swf.version(),
|
context.swf.version(),
|
||||||
avm1.global_object_cell(),
|
context.avm1.global_object_cell(),
|
||||||
*context.levels.get(&0).unwrap(),
|
*context.levels.get(&0).unwrap(),
|
||||||
);
|
);
|
||||||
let shared_objects = activation.context.shared_objects.clone();
|
let shared_objects = activation.context.shared_objects.clone();
|
||||||
|
@ -1138,9 +1128,8 @@ impl Player {
|
||||||
/// Update all AVM-based timers (such as created via setInterval).
|
/// Update all AVM-based timers (such as created via setInterval).
|
||||||
/// Returns the approximate amount of time until the next timer tick.
|
/// Returns the approximate amount of time until the next timer tick.
|
||||||
pub fn update_timers(&mut self, dt: f64) {
|
pub fn update_timers(&mut self, dt: f64) {
|
||||||
self.time_til_next_timer = self.mutate_with_update_context(|avm1, _avm2, context| {
|
self.time_til_next_timer =
|
||||||
Timers::update_timers(avm1, context, dt)
|
self.mutate_with_update_context(|_avm2, context| Timers::update_timers(context, dt));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue