Skip to content
Open
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
36 changes: 36 additions & 0 deletions core/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,42 @@ impl<'gc> ActionQueue<'gc> {
}
}

/// Queues an action to run for the given movie clip to the front.
/// The action will be skipped if the clip is removed before the action runs.
pub fn queue_front_action(
&mut self,
clip: DisplayObject<'gc>,
action_type: ActionType<'gc>,
is_unload: bool,
) {
let priority = action_type.priority();
let action = QueuedAction {
clip,
action_type,
is_unload,
};
debug_assert!(priority < Self::NUM_PRIORITIES);
if let Some(queue) = self.action_queue.get_mut(priority) {
queue.push_front(action)
}
}

/// Conditionally queues an action to run for the given movie clip to either the front (true), or the back (false).
/// The action will be skipped if the clip is removed before the action runs.
pub fn queue_front_or_back_action(
&mut self,
clip: DisplayObject<'gc>,
action_type: ActionType<'gc>,
is_unload: bool,
is_front: bool,
) {
if is_front {
self.queue_front_action(clip, action_type, is_unload);
} else {
self.queue_action(clip, action_type, is_unload);
}
}

/// Sorts and drains the actions from the queue.
pub fn pop_action(&mut self) -> Option<QueuedAction<'gc>> {
self.action_queue
Expand Down
6 changes: 4 additions & 2 deletions core/src/display_object/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3003,12 +3003,13 @@ impl<'gc> TInteractiveObject<'gc> for MovieClip<'gc> {
}
}

context.action_queue.queue_action(
context.action_queue.queue_front_or_back_action(
self.into(),
ActionType::Normal {
bytecode: event_handler.action_data.clone(),
},
event == ClipEvent::Unload,
event.propagates(),
);
}
}
Expand All @@ -3019,14 +3020,15 @@ impl<'gc> TInteractiveObject<'gc> for MovieClip<'gc> {
if let Some(name) = event.method_name() {
// Keyboard events don't fire their methods unless the MovieClip has focus (#2120).
if !event.is_key_event() || read.has_focus {
context.action_queue.queue_action(
context.action_queue.queue_front_or_back_action(
self.into(),
ActionType::Method {
object,
name,
args: vec![],
},
event == ClipEvent::Unload,
event.propagates(),
);
}
}
Expand Down
59 changes: 59 additions & 0 deletions tests/tests/swfs/avm1/propagated_clip_event_order/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
[
{
"type": "MouseMove",
"pos": [295.0, 180.0]
},
{
"type": "MouseDown",
"pos": [295.0, 180.0],
"btn": "Left"
},
{
"type": "Wait"
},
{
"type": "MouseUp",
"pos": [295.0, 180.0],
"btn": "Left"
},
{
"type": "Wait"
},
{
"type": "MouseMove",
"pos": [340.0, 180.0]
},
{
"type": "MouseDown",
"pos": [340.0, 180.0],
"btn": "Left"
},
{
"type": "Wait"
},
{
"type": "MouseUp",
"pos": [340.0, 180.0],
"btn": "Left"
},
{
"type": "Wait"
},
{
"type": "MouseMove",
"pos": [320.0, 180.0]
},
{
"type": "MouseDown",
"pos": [320.0, 180.0],
"btn": "Left"
},
{
"type": "Wait"
},
{
"type": "MouseUp",
"pos": [320.0, 180.0],
"btn": "Left"
}
]
6 changes: 6 additions & 0 deletions tests/tests/swfs/avm1/propagated_clip_event_order/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
button_2: _parent.val: 0
button_1: _parent.val: 2
button_1: _parent.button_2.val[_parent.val]: 2
button_1: _parent.val: 1
button_1: _parent.button_2.val[_parent.val]: 1
button_2: _parent.val: 1
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
num_ticks = 5