core: Fast-forward removals as the result of a goto happen before the frame number advances.

This commit is contained in:
David Wendt 2022-02-02 17:49:08 -05:00 committed by kmeisthax
parent 66c24ff188
commit 8feb3fc7b0
1 changed files with 26 additions and 9 deletions

View File

@ -1364,6 +1364,8 @@ impl<'gc> MovieClip<'gc> {
self.assert_expected_tag_start(); self.assert_expected_tag_start();
} }
let from_frame = self.current_frame();
// Flash gotos are tricky: // Flash gotos are tricky:
// 1) Conceptually, a goto should act like the playhead is advancing forward or // 1) Conceptually, a goto should act like the playhead is advancing forward or
// backward to a frame. // backward to a frame.
@ -1438,12 +1440,22 @@ impl<'gc> MovieClip<'gc> {
mc.goto_place_object(reader, tag_len, 4, &mut goto_commands, is_rewind, index) mc.goto_place_object(reader, tag_len, 4, &mut goto_commands, is_rewind, index)
} }
TagCode::RemoveObject => { TagCode::RemoveObject => self.goto_remove_object(
self.goto_remove_object(reader, 1, context, &mut goto_commands, is_rewind) reader,
} 1,
TagCode::RemoveObject2 => { context,
self.goto_remove_object(reader, 2, context, &mut goto_commands, is_rewind) &mut goto_commands,
} is_rewind,
from_frame,
),
TagCode::RemoveObject2 => self.goto_remove_object(
reader,
2,
context,
&mut goto_commands,
is_rewind,
from_frame,
),
_ => Ok(()), _ => Ok(()),
}; };
let _ = tag_utils::decode_tags(&mut reader, tag_callback, TagCode::ShowFrame); let _ = tag_utils::decode_tags(&mut reader, tag_callback, TagCode::ShowFrame);
@ -1791,6 +1803,7 @@ impl<'gc> MovieClip<'gc> {
context: &mut UpdateContext<'_, 'gc, '_>, context: &mut UpdateContext<'_, 'gc, '_>,
goto_commands: &mut Vec<GotoPlaceObject<'a>>, goto_commands: &mut Vec<GotoPlaceObject<'a>>,
is_rewind: bool, is_rewind: bool,
from_frame: FrameNumber,
) -> DecodeResult { ) -> DecodeResult {
let remove_object = if version == 1 { let remove_object = if version == 1 {
reader.read_remove_object_1() reader.read_remove_object_1()
@ -1807,15 +1820,19 @@ impl<'gc> MovieClip<'gc> {
// Don't do this for rewinds, because they conceptually // Don't do this for rewinds, because they conceptually
// start from an empty display list, and we also want to examine // start from an empty display list, and we also want to examine
// the old children to decide if they persist (place_frame <= goto_frame). // the old children to decide if they persist (place_frame <= goto_frame).
let read = self.0.read(); let to_frame = self.current_frame();
if let Some(child) = read.container.get_depth(depth) { self.0.write(context.gc_context).current_frame = from_frame;
drop(read);
let child = self.0.read().container.get_depth(depth);
if let Some(child) = child {
if !child.placed_by_script() { if !child.placed_by_script() {
self.remove_child(context, child, Lists::all()); self.remove_child(context, child, Lists::all());
} else { } else {
self.remove_child(context, child, Lists::DEPTH); self.remove_child(context, child, Lists::DEPTH);
} }
} }
self.0.write(context.gc_context).current_frame = to_frame;
} }
Ok(()) Ok(())
} }