Move AVM1 inside UpdateContext.

This commit is contained in:
David Wendt 2020-07-27 20:57:42 -04:00
parent 14bfbc358f
commit 7c7b019087
42 changed files with 539 additions and 561 deletions

View File

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

View File

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

View File

@ -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;

View File

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

View File

@ -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)?;

View File

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

View File

@ -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,
&[ &[

View File

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

View File

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

View File

@ -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!(

View File

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

View File

@ -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)?;

View File

@ -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,

View File

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

View File

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

View File

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

View File

@ -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() {

View File

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

View File

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

View File

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

View File

@ -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(

View File

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

View File

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

View File

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

View File

@ -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,
}; };

View File

@ -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 {

View File

@ -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,

View File

@ -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(),
); );

View File

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

View File

@ -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.

View File

@ -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>>,

View File

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

View File

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

View File

@ -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,

View File

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

View File

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

View File

@ -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(&params.depth()).copied(); let child_entry = clip.0.read().children.get(&params.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(),

View File

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

View File

@ -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());

View File

@ -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,

View File

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