Skip to content
Merged
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
10 changes: 10 additions & 0 deletions core/src/display_object/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2443,6 +2443,16 @@ impl<'gc> MovieClip<'gc> {
let goto_frame = self.0.queued_goto_frame.take();
if let Some(frame) = goto_frame {
self.goto_frame_now(context, frame);

// In SWFv10+, the `goto_frame_now` above will trigger an inner goto
// frame, which will call `construct_frame`. However, this is not
// the case in SWFv9, where inner goto frames are no-ops, so we need
// to manually run `construct_frame` to ensure that children are
// constructed. This prevents situations such as a frame script
// queued to run on this frame seeing not-yet-constructed children.
if self.swf_version() <= 9 {
self.construct_frame(context);
}
}
}

Expand Down
8 changes: 0 additions & 8 deletions core/src/frame_lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
//! inline in the order that clips were originally created.

use crate::avm2::{Avm2, EventObject};
use crate::avm2_stub_method_context;
use crate::context::UpdateContext;
use crate::display_object::{DisplayObject, MovieClip, TDisplayObject};
use crate::loader::LoadManager;
Expand Down Expand Up @@ -125,13 +124,6 @@ pub fn run_inner_goto_frame<'gc>(
initial_clip: MovieClip<'gc>,
) {
if initial_clip.swf_version() <= 9 && initial_clip.movie().is_action_script_3() {
avm2_stub_method_context!(
context,
"flash.display.MovieClip",
"goto",
"with SWF 9 movie"
);

// We skip the next `enter_frame` call, so that we will still run the framescripts
// queued for our target frame.
initial_clip.base().set_skip_next_enter_frame(true);
Expand Down
51 changes: 51 additions & 0 deletions tests/tests/swfs/avm2/swf_10_queued_goto_scripts_construct/Test.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package {
import flash.display.MovieClip;

public class Test extends MovieClip {
public var counter:int = 0;

public var theSprite:TheSprite;

public function Test() {
super();
var self:Test = this;
addEventListener("enterFrame",function(e:*):void {
trace("enterFrame dispatched");
trace("Number of root children: " + self.numChildren);
trace("placed theSprite: " + self.theSprite);
trace("theSprite: " + theSprite);
});
addEventListener("frameConstructed",function(e:*):void {
trace("frameConstructed dispatched");
trace("Number of root children: " + self.numChildren);
trace("placed theSprite: " + self.theSprite);
trace("theSprite: " + theSprite);
});
addEventListener("exitFrame",function(e:*):void {
trace("exitFrame dispatched");
trace("Number of root children: " + self.numChildren);
trace("placed theSprite: " + self.theSprite);
trace("theSprite: " + theSprite);
});
addFrameScript(1,frame2,2,frame3);
gotoAndStop(2);
trace("Test constructor complete");
}

public function frame2() : void {
trace("frame 2 framescript: On frame 2");
gotoAndStop(3);
trace("frame 2 framescript: Ran gotoAndStop(3) from frame 2");
}

public function frame3() : void {
trace("frame 3 framescript: On frame 3");
trace("frame 3 framescript: placed theSprite is " + this.theSprite);
if(counter < 2) {
counter++;
gotoAndStop(3);
trace("frame 3 framescript: Ran gotoAndStop(3) from frame 3");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package {
import flash.display.MovieClip;

public class TheSprite extends MovieClip {
public function TheSprite() {
trace("Start of TheSprite ctor");
super();
theSprite = this;
trace("End of TheSprite ctor");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
frameConstructed dispatched
Number of root children: 0
placed theSprite: null
theSprite: null
frame 2 framescript: On frame 2
frame 2 framescript: Ran gotoAndStop(3) from frame 2
Start of TheSprite ctor
End of TheSprite ctor
frameConstructed dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
frame 3 framescript: On frame 3
frame 3 framescript: placed theSprite is [object TheSprite]
frame 3 framescript: Ran gotoAndStop(3) from frame 3
frameConstructed dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
exitFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
exitFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
exitFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
Test constructor complete
frameConstructed dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
exitFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
enterFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
frameConstructed dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
exitFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
num_frames = 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package {
public var theSprite:TheSprite;
}
51 changes: 51 additions & 0 deletions tests/tests/swfs/avm2/swf_9_queued_goto_scripts_construct/Test.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package {
import flash.display.MovieClip;

public class Test extends MovieClip {
public var counter:int = 0;

public var theSprite:TheSprite;

public function Test() {
super();
var self:Test = this;
addEventListener("enterFrame",function(e:*):void {
trace("enterFrame dispatched");
trace("Number of root children: " + self.numChildren);
trace("placed theSprite: " + self.theSprite);
trace("theSprite: " + theSprite);
});
addEventListener("frameConstructed",function(e:*):void {
trace("frameConstructed dispatched");
trace("Number of root children: " + self.numChildren);
trace("placed theSprite: " + self.theSprite);
trace("theSprite: " + theSprite);
});
addEventListener("exitFrame",function(e:*):void {
trace("exitFrame dispatched");
trace("Number of root children: " + self.numChildren);
trace("placed theSprite: " + self.theSprite);
trace("theSprite: " + theSprite);
});
addFrameScript(1,frame2,2,frame3);
gotoAndStop(2);
trace("Test constructor complete");
}

public function frame2() : void {
trace("frame 2 framescript: On frame 2");
gotoAndStop(3);
trace("frame 2 framescript: Ran gotoAndStop(3) from frame 2");
}

public function frame3() : void {
trace("frame 3 framescript: On frame 3");
trace("frame 3 framescript: placed theSprite is " + this.theSprite);
if(counter < 2) {
counter++;
gotoAndStop(3);
trace("frame 3 framescript: Ran gotoAndStop(3) from frame 3");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package {
import flash.display.MovieClip;

public class TheSprite extends MovieClip {
public function TheSprite() {
trace("Start of TheSprite ctor");
super();
theSprite = this;
trace("End of TheSprite ctor");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Test constructor complete
frameConstructed dispatched
Number of root children: 0
placed theSprite: null
theSprite: null
frame 2 framescript: On frame 2
frame 2 framescript: Ran gotoAndStop(3) from frame 2
Start of TheSprite ctor
End of TheSprite ctor
frame 3 framescript: On frame 3
frame 3 framescript: placed theSprite is [object TheSprite]
frame 3 framescript: Ran gotoAndStop(3) from frame 3
exitFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
enterFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
frameConstructed dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
exitFrame dispatched
Number of root children: 1
placed theSprite: [object TheSprite]
theSprite: [object TheSprite]
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
num_frames = 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package {
public var theSprite:TheSprite;
}
Loading