`core` already depends on the `instant` crate which abstracts
`std::instant::Instant` and polyfills it on Web. Use it to replace
`NavigatorBackend::time_since_launch` in order to make `NavigatorBackend`
a little smaller and more simple.
Previously there were 3 implementations of `LocaleBackend`:
`DesktopLocaleBackend`, `WebLocaleBackend` and `NullLocaleBackend`.
While `DesktopLocaleBackend`, `WebLocaleBackend` were identical,
`NullLocaleBackend` always returned a fixed date/time for tests
determinism.
Unify them in a single file, and use `cfg!(test)` and a new dedicated
`deterministic` feature to decide whether to mock date/time or not.
This should not cause any behavioral changes.
Instead of storing shared pointers to `Avm1ConstructorRegistry` in
`MovieLibrary`, access the `PropertyMap` directly, without an extra
abstraction.
Also, move the constructor registries to `Avm1`, for better
encapsulation.
This requires adding another notion of mouse-release events to `ClipEvent`. We now have four:
* `MouseUp` - the mouse was released, any object on the render list can handle this event ("anycast" event)
* `MouseUpInside` - the mouse was released inside this display object, only the mouse-picked target of the event can handle it
* `Release` - the mouse was released inside the last clicked display object
* `ReleaseOutside` - the mouse was released outside the last clicked display object
For those keeping score at home, in AVM2, the valid progression of events is either...
* On the same object, `mouseDown`, `mouseUp`, and `click`
* On one object, `mouseDown`, then some mouse movement that takes the cursor out of the first object, then on another object `mouseUp`, and then finally the first object gets `releaseOutside`.
`onLoadInit` is queued after all `DoAction`s of the loaded clips.
That is, if clip1, clip2, clip3 are loaded in the same frame
(in this order), then actions will be executed as follows:
* `DoAction` of clip3
* `DoAction` of clip2
* `DoAction` of clip1
* `onLoadInit` of clip3
* `onLoadInit` of clip2
* `onLoadInit` of clip1
Previously, those were incorrectly executed as follows:
* `DoAction` of clip3
* `onLoadInit` of clip3
* `DoAction` of clip2
* `onLoadInit` of clip2
* `DoAction` of clip1
* `onLoadInit` of clip1
`handle_clip_event` is now a default trait method that calls three methods in order:
* `filter_clip_event`, to determine which events that either this object or it's children may handle
* `propagate_to_children`, to check if any children of this object want to handle an event. (This also includes AVM2 button states, which are not technically "children" in the usual sense...)
* `event_dispatch`, which does the actual "object reacts to an event" bit if no child handles the object.
These roughly correspond to phases of existing event-handling objects pre-`InteractiveObject`.
Use prototype depths instead. Most calls passed `base_proto = None`,
which is equivalent to `depth = 0`, and is now the default.
The few other cases were adapted to use `Executable::exec` directly,
where `depth` can be specified manually.
The last usage of it was in `Player`, which anyway should operate
only on newly created objects that don't have any virtual properties
nor watchers. So it is safe to replace with `define_value`, that
also cannot fail.
`__proto__` seems to behave much like a regular data property. So
simply remove the `prototype` field of `ScriptObject` in favor of
storing the prototype in the general properties hash map.
This also incurred a large number of ancillary changes, as it turns out nearly every native object is currently pulling a prototype and sticking it into an object. Right now, I have it instead pulling the constructor out of the prototype, but a future PR will also remove `system_prototypes` as well.
Other ancillary changes include:
* `Domain` now supports partial initialization to avoid an order-of-events issue. Accessing domain memory on a partially-initialized `Domain` will panic.
* `Domain` construction requires a full `activation` now, except for `global_scope` which needs to be initialized later with valid domain memory before user code runs.
* Pretty much every native object constructor now takes a proto/constr pair
* Trait lookup was rewritten to handle this. It's still buggy - seven tests don't work
* `TObject.construct` now actually does the full object construction dance. This allows `ClassObject` to implement the ES4 object construction pathway directly while `FunctionObject` maintains ES3 compatibility.
This is a tentative commit; there are still seven failing tests that I need to fix.