Skip to content

Commit f139e46

Browse files
kjaroshLord-McSweeney
authored andcommitted
avm1: Do not panic when swapping children on depth/render list desync
Unfortunately sometimes the render list and the depth list become desynchronized. When swapping children this caused panics. I haven't been able to reproduce those scenarios, but it's better to leave the render/depth list messed up than to panic in this case.
1 parent 0c72ed3 commit f139e46

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

core/src/display_object/container.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -999,31 +999,46 @@ impl<'gc> ChildContainer<'gc> {
999999
let prev_position = self
10001000
.render_list
10011001
.iter()
1002-
.position(|x| DisplayObject::ptr_eq(*x, prev_child))
1003-
.unwrap();
1002+
.position(|x| DisplayObject::ptr_eq(*x, prev_child));
10041003
let next_position = self
10051004
.render_list
10061005
.iter()
1007-
.position(|x| DisplayObject::ptr_eq(*x, child))
1008-
.unwrap();
1009-
self.render_list_mut().swap(prev_position, next_position);
1006+
.position(|x| DisplayObject::ptr_eq(*x, child));
1007+
1008+
match (prev_position, next_position) {
1009+
(Some(prev_position), Some(next_position)) => {
1010+
self.render_list_mut().swap(prev_position, next_position);
1011+
}
1012+
_ => {
1013+
tracing::error!(
1014+
"ChildContainer::swap_at_depth: A child is missing in the render list"
1015+
);
1016+
}
1017+
}
10101018
} else {
10111019
self.depth_list.remove(&prev_depth);
10121020

1013-
let old_position = self
1021+
if let Some(old_position) = self
10141022
.render_list
10151023
.iter()
10161024
.position(|x| DisplayObject::ptr_eq(*x, child))
1017-
.unwrap();
1018-
self.render_list_mut().remove(old_position);
1025+
{
1026+
self.render_list_mut().remove(old_position);
1027+
}
10191028

10201029
if let Some((_, below_child)) = self.depth_list.range(..depth).next_back() {
10211030
let new_position = self
10221031
.render_list
10231032
.iter()
10241033
.position(|x| DisplayObject::ptr_eq(*x, *below_child))
1025-
.unwrap();
1026-
self.render_list_mut().insert(new_position + 1, child);
1034+
.map(|pos| pos + 1)
1035+
.unwrap_or_else(|| {
1036+
tracing::error!(
1037+
"ChildContainer::swap_at_depth: below_child is missing in the render list"
1038+
);
1039+
0
1040+
});
1041+
self.render_list_mut().insert(new_position, child);
10271042
} else {
10281043
self.render_list_mut().insert(0, child);
10291044
}

0 commit comments

Comments
 (0)