core: New-depth children should always be placed before higher children, not after lower ones.

We will call this the "before-above" rule, to contrast with the previous "after-below" behavior. The main difference is how off-depth-list children are handled, which more closely matches AVM2.

The previous implementation of after-below wouldn't work unless we made the fallback case of not having a below child put it to the *end* of the list. This gave us test pass but broke animations. The first one I tried, Cirno's Perfect Math Class, prepends the entire depth list, which with the half-broken after-below behavior wound up appending to the render list.

There isn't an inverse problem with before-below and the end of the list, since we cover that case and we don't have to put weird exceptions.
This commit is contained in:
David Wendt 2020-11-14 19:55:43 -05:00 committed by Mike Welsh
parent 74b50f2586
commit 365601f2d9
1 changed files with 5 additions and 5 deletions

View File

@ -11,7 +11,7 @@ use enumset::{EnumSet, EnumSetType};
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::fmt::Debug;
use std::ops::RangeBounds;
use std::ops::{RangeBounds, Bound};
/// The three lists that a display object container is supposed to maintain.
#[derive(EnumSetType)]
@ -569,17 +569,17 @@ impl<'gc> ChildContainer<'gc> {
None
}
} else if let Some((_, below_child)) = self.depth_list.range(..depth).rev().next() {
} else if let Some((_, above_child)) = self.depth_list.range((Bound::Excluded(depth), Bound::Unbounded)).next() {
let position = self
.render_list
.iter()
.position(|x| DisplayObject::ptr_eq(*x, *below_child))
.position(|x| DisplayObject::ptr_eq(*x, *above_child))
.unwrap();
self.render_list.insert(position + 1, child);
self.render_list.insert(position, child);
None
} else {
self.render_list.insert(0, child);
self.render_list.push(child);
None
};