Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/src/avm1/globals/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1604,7 +1604,7 @@ fn load_movie<'gc>(
None,
crate::loader::MovieLoaderVMData::Avm1 { broadcaster: None },
);
activation.context.navigator.spawn_future(future);
activation.context.avm1.deferred_loads.push(future);

Ok(Value::Undefined)
}
Expand All @@ -1625,7 +1625,7 @@ fn load_variables<'gc>(
target,
request,
);
activation.context.navigator.spawn_future(future);
activation.context.avm1.deferred_loads.push(future);

Ok(Value::Undefined)
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/avm1/globals/movie_clip_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fn load_clip<'gc>(
broadcaster: Some(this),
},
);
activation.context.navigator.spawn_future(future);
activation.context.avm1.deferred_loads.push(future);

return Ok(true.into());
}
Expand Down
10 changes: 10 additions & 0 deletions core/src/avm1/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ pub struct Avm1<'gc> {
/// More examples of this are in the movieclip_invalid_get_bounds_X tests.
use_new_invalid_bounds_value: bool,

#[collect(require_static)]
pub deferred_loads: Vec<crate::backend::navigator::OwnedFuture<(), crate::loader::Error>>,

#[cfg(feature = "avm_debug")]
pub debug_output: bool,
}
Expand Down Expand Up @@ -117,6 +120,7 @@ impl<'gc> Avm1<'gc> {
#[cfg(feature = "avm_debug")]
debug_output: false,
use_new_invalid_bounds_value: false,
deferred_loads: Vec::new(),
}
}

Expand Down Expand Up @@ -462,6 +466,12 @@ impl<'gc> Avm1<'gc> {
// Run a single frame.
#[instrument(level = "debug", skip_all)]
pub fn run_frame(context: &mut UpdateContext<'gc>) {
if !context.avm1.deferred_loads.is_empty() {
let loads = std::mem::take(&mut context.avm1.deferred_loads);
for future in loads {
context.navigator.spawn_future(future);
}
}
// Remove pending objects
Self::remove_pending(context);

Expand Down
34 changes: 30 additions & 4 deletions core/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ pub struct ActionQueue<'gc> {

impl<'gc> ActionQueue<'gc> {
const DEFAULT_CAPACITY: usize = 32;
const NUM_PRIORITIES: usize = 3;
const NUM_PRIORITIES: usize = 5;

/// Crates a new `ActionQueue` with an empty queue.
pub fn new() -> Self {
Expand Down Expand Up @@ -652,6 +652,18 @@ pub enum ActionType<'gc> {
args: Vec<Avm1Value<'gc>>,
},

OnLoad {
object: Avm1Object<'gc>,
name: AvmString<'gc>,
args: Vec<Avm1Value<'gc>>,
},

OnLoadInit {
object: Avm1Object<'gc>,
name: AvmString<'gc>,
args: Vec<Avm1Value<'gc>>,
},

/// A system listener method.
NotifyListeners {
listener: AvmString<'gc>,
Expand All @@ -663,9 +675,11 @@ pub enum ActionType<'gc> {
impl ActionType<'_> {
fn priority(&self) -> usize {
match self {
ActionType::Initialize { .. } => 2,
ActionType::Construct { .. } => 1,
_ => 0,
ActionType::Initialize { .. } => 4,
ActionType::Construct { .. } => 3,
ActionType::OnLoadInit { .. } => 1,
ActionType::OnLoad { .. } => 0,
_ => 2,
}
}
}
Expand Down Expand Up @@ -695,6 +709,18 @@ impl fmt::Debug for ActionType<'_> {
.field("name", name)
.field("args", args)
.finish(),
ActionType::OnLoad { object, name, args } => f
.debug_struct("ActionType::OnLoad")
.field("object", object)
.field("name", name)
.field("args", args)
.finish(),
ActionType::OnLoadInit { object, name, args } => f
.debug_struct("ActionType::OnLoadInit")
.field("object", object)
.field("name", name)
.field("args", args)
.finish(),
ActionType::NotifyListeners {
listener,
method,
Expand Down
30 changes: 21 additions & 9 deletions core/src/display_object/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2698,15 +2698,27 @@ impl<'gc> TInteractiveObject<'gc> for MovieClip<'gc> {
// (e.g., clip.onEnterFrame = foo).
if self.should_fire_event_handlers(context, event) {
if let Some(name) = event.method_name(&context.strings) {
context.action_queue.queue_action(
self.into(),
ActionType::Method {
object,
name,
args: vec![],
},
event == ClipEvent::Unload,
);
if let ClipEvent::Load = event {
context.action_queue.queue_action(
self.into(),
ActionType::OnLoad {
object,
name,
args: vec![],
},
event == ClipEvent::Unload,
);
} else {
context.action_queue.queue_action(
self.into(),
ActionType::Method {
object,
name,
args: vec![],
},
event == ClipEvent::Unload,
);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2703,7 +2703,7 @@ impl<'gc> Loader<'gc> {
{
queue.queue_action(
clip,
ActionType::Method {
ActionType::OnLoadInit {
object: broadcaster,
name: istr!(strings, "broadcastMessage"),
args: vec![istr!(strings, "onLoadInit").into(), clip.object()],
Expand Down
8 changes: 8 additions & 0 deletions core/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2146,6 +2146,14 @@ impl Player {
Avm1::run_stack_frame_for_method(action.clip, object, name, &args, context);
}

ActionType::OnLoad { object, name, args } => {
Avm1::run_stack_frame_for_method(action.clip, object, name, &args, context);
}

ActionType::OnLoadInit { object, name, args } => {
Avm1::run_stack_frame_for_method(action.clip, object, name, &args, context);
}

// Event handler method call (e.g. onEnterFrame).
ActionType::NotifyListeners {
listener,
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/focusrect_property_swf5/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 2
num_ticks = 3
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/focusrect_property_swf6/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 2
num_ticks = 3
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/focusrect_property_swf7/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 2
num_ticks = 3
3 changes: 1 addition & 2 deletions tests/tests/swfs/avm1/from_shumway/moviecliploader/test.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Test adapted from Shumway at https://github.com/mozilla/shumway/tree/master/test/swfs/avm1/moviecliploader

num_frames = 3
known_failure = true # https://github.com/ruffle-rs/ruffle/issues/12273
num_frames = 4
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/loadmovie_fail/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_frames = 1
num_frames = 2
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/loadmovie_method/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_frames = 2
num_frames = 3
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/loadmovie_var_persistence/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 6
num_ticks = 7
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/lock_root/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_frames = 2
num_frames = 3
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/mcl_loadclip_properties/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 2
num_ticks = 3
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/mcl_loadclip_replace_root/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 2
num_ticks = 3
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/moviecliploader_flashvars/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 2
num_ticks = 3
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/register_class/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_frames = 3
num_frames = 6
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/register_class_swf6/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_frames = 3
num_frames = 6
1 change: 0 additions & 1 deletion tests/tests/swfs/avm1/root_onload/test.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
num_frames = 1
known_failure = true
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/sandbox_type_remote/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_ticks = 3
num_ticks = 400
2 changes: 1 addition & 1 deletion tests/tests/swfs/avm1/string_paths_eval2/test.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
num_frames = 5
num_frames = 6
Loading