`npm start` is a common convention for launching a web server.
Also use the `npm start` and `npm test` shorthands instead of
`npm run start` and `npm run test`.
In both `FrameLabel` and `Scene`, we define multiple
'public property / private slot' pairs.
The public property has a getter which delegates to the private
property. There is no setter for the property, ensuring that
the private slot can only be modified from within Ruffle itself.
This PR adds a macro `define_indirect_properties` to abstract over
this pattern. Currently, it only supports the read-only property
pattern - however, it could be extended in the future to generate
a setter that invokes a caller-provided callback function.
This needs to be a macro (rather than a method) so that we can
generate a function with the property name hard-coded into it.
Using a closure that references an upvar will not work, since
`Method::from_builtin` requires a function pointer.
This feature allows `RUST_LOG` to include a regex filter. While
it's nice to have, it's not worth over 440KB added to the release
binary. `grep` / `findstr` are great and even better alternatives.
Document roots (a.k.a. `XML` objects) are very similar to regular
element nodes (a.k.a. `XMLNode` objects). The primary difference is
that `XML` objects return `null` for their `nodeName`. But this can
be changed too; Setting `xml.nodeName = "someName"` will make `XML`
objects behave much like `XMLNode`. Moreover, many checks in Ruffle
that refuse to operate on document roots were wrong, and actually
these should be accepted as normal element nodes.
Besides the functional corrections, this also simplifies the code.
`AudioContext.getOutputTimestamp` returns incorrect values in
Safari 15.1+, and this would cause movies with 'stream' sounds to
soft-lock because the calculated audio position would barely
progress.
See:
https://developer.apple.com/forums/thread/696356
Change the output timestamp calculation to use
`AudioContext.currentTime` instead.
This also slightly changes behavior: Previously `SwfMovie::from_data`
errors were propagated as `FetchError` and `display_root_movie_download_failed_message`
was called, offering the user to sidestep CORS by opening the SWF
in a new tab. But that wouldn't help, obviously, because no network
error is involved. Now, these errors are propagated as `InvalidSwf`,
and `display_root_movie_download_failed_message` is not called.
`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.
If `gl.drawingBufferWidth` returns `0`, then a `clamp` in
`WebGlRenderBackend::set_viewport_dimensions` hits an assertion that
`1 <= self.gl.drawing_buffer_width()` is `false`. I was able to
reproduce this on Chrome by creating many dummy WebGL contexts until
Ruffle's one is lost, and then resize the Ruffle player, but this may
happen in other cases as well.
Fix this by allowing `renderbuffer_width` and `renderbuffer_height`
to be `0`. From basic testing, this seems harmless.
Previously, the offset table and code table offset were completely
ignored. But as it seems, Flash does look into these offsets in
order to avoid exceedingly reading glyph shapes. For now, avoid
exceedingly reading empty and 1-byte glyph shapes, and add debug
assertions that verify the correctness of the offset table and code
table offset, to help diagnosing related bugs in the future.
Resolving `_levelN` had some inconsistencies with Flash:
1. `_flash` can be a prefix too.
2. The level ID parsing cannot fail; non-digit characters are ignored,
the value wraps around at `i32::MAX`, and negative values are valid.
This logic is relevant also for the `GetUrl` and `GetUrl2` opcodes.
For now only add TODOs for this.