This is in keeping with the whole idea of a "recursive frame": gotos run the entire frame lifecycle on the target clip, including broadcasts for `frameConstructed` and `exitFrame`.
We still retain the queue system as events are fired at removal time, and those events can trigger more gotos. If such a goto happens, AS3 code will hit a clip still in the old state rather than an inconsistent one. I don't have test coverage for this exact scenario just yet.
The rationale for the catch-up logic is as follows:
* We must always enter-frame and construct objects, even if those respective display events haven't happened yet.
* Display objects created in event handlers still need to run catchup phases, otherwise they will tag-stream desync
* Frame scripts are never triggered by catchup phases
* `exit_frame` is not a catchup phase as it is *only* an event broadcast currently
Normally a function closures also closes around its base clip.
If the base clip is removed, and then the function is executed, the
base clip then defaults to `this`.
However, Ruffle was incorrectly using the wrong base clip when
loading the `_root` and `_parent` registers in this case.
Fixes#5645.
This PR implements the `Loader.load` method, as well as
the associated `LoaderInfo` properties and events.
We can now load in an external AVM2 SWf: it will be added
as a child of `Loader` object, and will render properly
to the screen.
Limitations:
* The only supported `URLRequest` property is `url`
* `LoaderContext` is not supported at all - we always use the default
behavior
* Only `Loader.load` is implemented - we do not yet support unloading.
* We fire a plain 'Event' for the 'progress' event, instead of using
the (not yet implemented) 'ProgressEvent' class
The main changes in this PR are:
* The AVM2 `Loader` class now has an associated display object,
`LoaderDisplay`. This is basically a stub, and just renders
its single child (if it exists).
* `LoaderStream::Stage` is renamed to `LoaderStream::NotYetLoaded`.
This is used for both the `Stage` and an 'uninitialized'
`Loader.contentLoaderInfo`. In both cases, certain properties throw
errors, while others return actual values.
* The rust `Loader` manager now handles both AVM1 and AVM2 movie loads.