-
-
Notifications
You must be signed in to change notification settings - Fork 776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AVM2 Frame Events Ordering Fixes #5876
Conversation
700acef
to
6c557f7
Compare
I've decided to call time on this PR and
|
e565f3e
to
c10f7f0
Compare
9271f9b
to
8b537da
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not going to pretend I understood everything in movie_clip.rs
... :(
Would also appreciate if @Herschel reviewed this.
da6fe53
to
c8c017b
Compare
0444a3c
to
0af8e09
Compare
f61c0e5
to
b78c721
Compare
Done the usual testings with AVM1 files, everything looks good to me. |
This lets 'Pixel Legions' get further in the startup screen - previously, it would freeze almost immediately due to an error when dispatching an event. |
b78c721
to
6be3b69
Compare
259a754
to
88174a2
Compare
88174a2
to
8e44f37
Compare
…e root movie clip too
… except `destroy_frame` If we don't do this, then display objects created in event handlers will have a frame number desynchronized from their tag stream position. Unfortunately we cannot test for this.
…`, and/or `exitFrame`
…s a broadcast event.
…stily fix up the clip so it looks like the implicit goto already completed.
…stream position desyncs on AVM2.
…lip, even if we already executed that script beforehand.
…ing goto commands.
… frame number advances.
…`, and `frameConstructed`
…ed back and doing so breaks fast-forwarding.
…ers to avoid a tag stream desync.
… in line with frame advance.
… broken by fixes I moved to another PR
00dd8e0
to
ab0a955
Compare
This PR aims to fix remaining order-of-events bugs in AVM2. The previous work to implement frame lifecycle events was deliberately unfinished. Now that some games are getting close to running, these bugs need to get fixed.
So far, I've fixed the following unaccounted-for things:
EventDispatcher
methods need to work before initialization, so they now lazily initialize the object's event dispatch list. It is possible to gain access to uninitialized display objects (e.g. in parent constructors) and AVM2 movies expect to be able to put event handlers on them. (@adrian17 caught this one, thanks)MovieClip
s are actually playing (as cached atenterFrame
). Otherwise, if you stopped a MovieClip on a frame with aPlaceObject
tag, it would constantly keep creating that tag.tag_stream_pos
has changed subtly. In AVM1, it's just a pointer to the next frame's tags, because they all run at once. In AVM2, we have to process this multiple times, so we do not updatetag_stream_pos
until we are done processing the current frame's tags.tag_stream_pos
to work like it works in AVM1. Any time that it doesn't, we say that the tag stream has desynchronized.run_goto
needs to check if we have done so and either skip tags or rewind.Idle
phase) will desync if werun_frame_internal
; so we skip that part.gotoAndPlay(1)
. This requires us to maintain various lies about the state of the timeline, especiallytag_stream_pos
, as the loop's effects are split across the various frame lifecycle phases.MovieClip
does a whole bunch of extra work beforeenterFrame
is dispatched:self.playing()
, which now becomesself.playing_at_frame_advance()
. Every playback check that happens after frame advance needs to use the cached flag instead ofself.playing()
, at least in AVM2.RemoveObject
tags now.null
s to the render list for all children to be placed during frame construction. We don't do this yet.MovieClip
to the next frame and queue that frame's frame scripts.determine_next_frame
(which, incidentally, no longer exists) asnatural_playhead_action
. We use this to either revert or commit to the lie above in later frame phases.enterFrame
.MovieClip
was playing when we entered the current frame.enterFrame
beforehand.frameConstructed
andexitFrame
events, as well as running queued frame scripts. Gotos are one of them.goto_commands
internally) has finished.MovieClip
is already running its frame scripts. If so, the script is left on the queue.MovieClip
s would not drop theEXECUTING_AVM2_FRAME_SCRIPT
tag if they tried to execute frame scripts, but couldn't find any. This would lock up the clip timeline until the next frame script.place_frame
got removed. These may become irrelevant if core: Simplifiy goto logic and use ratio field #5431 merges before this PR.SimpleButton
has a whole host of oddities to it:SimpleButton
and it's child classes initialize as you would expect: i.e. in line with the rest of the code.PlaceObject
, the AVM2 instance initializer for the button will not run until we enter the next frame.Up
state, it dispatches a recursive frame on all of it's children (in a slightly different order, no less).#[ignore]
the tests that are affected by this for now. The effects are deterministic, but I suspect they are caused by some deeper unimplemented behavior in the Player. Talking with one of our sponsors it sounded like this was a known problem with Flash Player that people programmed around rather than relied upon.instantiate_child
, symbol class construction, and button state construction.Idle
phase for event handlers (none of which exist in this PR, but I've been testing this alongside avm2: Mouse event support #5767).construct_frame
calls internally; we use display object flags to prevent duplicate construction.added
/addedToStage
(at least, if you set up a document class); but runningconstruct_frame
on the root before those events naturally fire was rather difficult. Instead, I re-fire the event when the root is constructed in the normal frame flow.This list will grow as I fix more broken tests in the PR, or add new broken tests.I'm calling time on this PR.