Don't call `render` from `Player::tick`; instead, require the
frontends to explicitly call `render` when they wish to redraw.
The frontend can query `Player::needs_render` to see if the stage
is dirty and needs a redraw. Update desktop and web to use this
new method.
This fits better with the newer winit event loop model, which
requires explicitly calling `request_redraw`, and should avoid
spurious renders.
A base prototype is only applicable in cases where a method is being called as a property on an object. Bare function calls, `apply`/`call` calls, and so on do not generate a base prototype.
We also add a convenience method, `call_method`, to all objects. This method automatically calculates the correct base prototype for a method call on an object, which is the only operation that should generate base prototypes.
Revert to the old action queue method of popping off actions in a
loop, as new actions can be queued while iterating. Store proto
changes in a separate queue to maintain the high priority behavior.
It doesn't feel like Flash without having the hand cursor display
when hovering over buttons. First pass at implementing this;
core communicates which mouse cursor to use via
`InputBackend::set_mouse_cursor`.
TODO: Hand cursor only displayed for Button display objects
currently. Movie clips should also display this when they are in
"button mode" (when a button mouse event is set on them in AVM1,
or `buttonMode` property in AVM2).
`_root` is calculated dynamically based on the clip the currently executing function was called in.
Other things that used `context.root` have been changed to either update all layers or just update layer 0, which is the former `context.root`.
This allows the formation of `'static` futures that can still interact with a player. Async code will need to upgrade the weak reference in order to be able to interact with the player.
Previously we set the name of the root clip to `_level0`. Top-level
clips should actually have no name (`_root._name` returns `""`).
However, when constructing a dot path, `_level0` still gets inserted
by `DisplayObject::path` for the top-level, so that `trace(_root)`
still correctly prints `_level0`.
TODO: When `loadMovieNum` gets merged in, the proper level # needs
to be returned by `.DisplayObject::path`.
Functions now store their base clip (the code that contains the
executing bytecode). This is because `GotoFrame` and other actions
will execute on the clip the bytecode exists on, not on `this`.
(Note that `this.gotoAndStop` uses `GetMember` actions, which
worked correctly).
`Activation` now stores `target_clip`, and `Avm1::target_clip` and
`target_clip_or_root` grab this from the current stack frame.
Renamed `start_clip` to `base_clip` to match Flash conventions.
Removed `active_clip` as this was superfluous. Now you can use
`Avm1::target_clip_or_root`.
`UpdateContext` no longer contains `target_clip` etc.
When running an clip event handler (e.g. onEnterFrame), a stack
frame is pushed to get the property value. However, this frame
was causing an extra Undefined to be pushed on the operand stack in
`Avm1::retire_stack_frame`, which would blow out the stack.
Now this stack frame is popped after the property is resolved and
before the function is executed. The function will push its own
stack frame when it executes.
This is a very rough stub out of Stage.width and height to get
basic V-cams to start functioning.
TODO: Implement the different stage scaling modes. We will probably
want to add a "Stage" display object to handle this.
DoAction was accidentally creating its stack frame using
Avm1::insert_stack_frame_for_init_action, causing a dummy
Undefined to be pushed and blowing out the stack.
Fire unload clip event when a movie clip is removed. Added
`ActionType` enum used by `ActionQueue::queue_actions` that
determines the type of action that is running (replaces `is_init`
parameter).