avm1: Correctly mark unloaded movies as unloaded instead of relying on depth

This commit is contained in:
Lord-McSweeney 2023-11-06 19:05:18 -08:00 committed by TÖRÖK Attila
parent 44c4080ae4
commit 8096146a0d
2 changed files with 22 additions and 4 deletions

View File

@ -556,6 +556,11 @@ impl<'gc> DisplayObjectBase<'gc> {
self.flags.contains(DisplayObjectFlags::AVM1_REMOVED)
}
fn avm1_pending_removal(&self) -> bool {
self.flags
.contains(DisplayObjectFlags::AVM1_PENDING_REMOVAL)
}
pub fn should_skip_next_enter_frame(&self) -> bool {
self.flags
.contains(DisplayObjectFlags::SKIP_NEXT_ENTER_FRAME)
@ -570,6 +575,11 @@ impl<'gc> DisplayObjectBase<'gc> {
self.flags.set(DisplayObjectFlags::AVM1_REMOVED, value);
}
fn set_avm1_pending_removal(&mut self, value: bool) {
self.flags
.set(DisplayObjectFlags::AVM1_PENDING_REMOVAL, value);
}
fn scale_rotation_cached(&self) -> bool {
self.flags
.contains(DisplayObjectFlags::SCALE_ROTATION_CACHED)
@ -1650,7 +1660,11 @@ pub trait TDisplayObject<'gc>:
/// Is this object waiting to be removed on the start of the next frame
fn avm1_pending_removal(&self) -> bool {
self.depth() < 0
self.base().avm1_pending_removal()
}
fn set_avm1_pending_removal(&self, gc_context: &Mutation<'gc>, value: bool) {
self.base_mut(gc_context).set_avm1_pending_removal(value)
}
/// Whether this display object is visible.
@ -2394,7 +2408,7 @@ bitflags! {
struct DisplayObjectFlags: u16 {
/// Whether this object has been removed from the display list.
/// Necessary in AVM1 to throw away queued actions from removed movie clips.
const AVM1_REMOVED = 1 << 0;
const AVM1_REMOVED = 1 << 0;
/// If this object is visible (`_visible` property).
const VISIBLE = 1 << 1;
@ -2436,10 +2450,13 @@ bitflags! {
/// This is set for objects constructed from ActionScript,
/// which are observed to lag behind objects placed by the timeline
/// (even if they are both placed in the same frame)
const SKIP_NEXT_ENTER_FRAME = 1 << 11;
const SKIP_NEXT_ENTER_FRAME = 1 << 11;
/// If this object has already had `invalidate_cached_bitmap` called this frame
const CACHE_INVALIDATED = 1 << 12;
const CACHE_INVALIDATED = 1 << 12;
/// If this AVM1 object is pending removal (will be removed on the next frame).
const AVM1_PENDING_REMOVAL = 1 << 13;
}
}

View File

@ -1018,6 +1018,7 @@ impl<'gc> ChildContainer<'gc> {
let cur_depth = child.depth();
// Note that the depth returned by AS will be offset by the `AVM_DEPTH_BIAS`, so this is really `-(cur_depth+1+AVM_DEPTH_BIAS)`
child.set_depth(context.gc_context, -cur_depth - 1);
child.set_avm1_pending_removal(context.gc_context, true);
if let Some(mc) = child.as_movie_clip() {
// Clip events should still fire