CI-capable version of #9086
---------
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
Fix typos throughout the project.
## Solution
[`typos`](https://github.com/crate-ci/typos) project was used for
scanning, but no automatic corrections were applied. I checked
everything by hand before fixing.
Most of the changes are documentation/comments corrections. Also, there
are few trivial changes to code (variable name, pub(crate) function name
and a few error/panic messages).
## Unsolved
`bevy_reflect_derive` has
[typo](1b51053f19/crates/bevy_reflect/bevy_reflect_derive/src/type_path.rs (L76))
in enum variant name that I didn't fix. Enum is `pub(crate)`, so there
shouldn't be any trouble if fixed. However, code is tightly coupled with
macro usage, so I decided to leave it for more experienced contributor
just in case.
I created this manually as Github didn't want to run CI for the
workflow-generated PR. I'm guessing we didn't hit this in previous
releases because we used bors.
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
# Objective
- Improve speed of loading examples on the website
- Triggered by https://news.ycombinator.com/item?id=35996393
## Solution
- Use wasm-opt to optimize files for size. This reduces the files from
22mb to 13mb
- Cloudflare doesn't set the correct `Content-Type` header by default
for wasm files, add it manually. This enables wasm streaming and
compression, dropping the transfer to 3.9mb
The files with this script are deployed on
optimized.wasm-pages.pages.dev if you want to test, you can replace this
URL on a website deployed locally.
# Objective
Bevy code tends to make heavy use of the [newtype](
https://doc.rust-lang.org/rust-by-example/generics/new_types.html)
pattern, which is why we have a dedicated derive for
[`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html) and
[`DerefMut`](https://doc.rust-lang.org/std/ops/trait.DerefMut.html).
This derive works for any struct with a single field:
```rust
#[derive(Component, Deref, DerefMut)]
struct MyNewtype(usize);
```
One reason for the single-field limitation is to prevent confusion and
footguns related that would arise from allowing multi-field structs:
<table align="center">
<tr>
<th colspan="2">
Similar structs, different derefs
</th>
</tr>
<tr>
<td>
```rust
#[derive(Deref, DerefMut)]
struct MyStruct {
foo: usize, // <- Derefs usize
bar: String,
}
```
</td>
<td>
```rust
#[derive(Deref, DerefMut)]
struct MyStruct {
bar: String, // <- Derefs String
foo: usize,
}
```
</td>
</tr>
<tr>
<th colspan="2">
Why `.1`?
</th>
</tr>
<tr>
<td colspan="2">
```rust
#[derive(Deref, DerefMut)]
struct MyStruct(Vec<usize>, Vec<f32>);
let mut foo = MyStruct(vec![123], vec![1.23]);
// Why can we skip the `.0` here?
foo.push(456);
// But not here?
foo.1.push(4.56);
```
</td>
</tr>
</table>
However, there are certainly cases where it's useful to allow for
structs with multiple fields. Such as for structs with one "real" field
and one `PhantomData` to allow for generics:
```rust
#[derive(Deref, DerefMut)]
struct MyStruct<T>(
// We want use this field for the `Deref`/`DerefMut` impls
String,
// But we need this field so that we can make this struct generic
PhantomData<T>
);
// ERROR: Deref can only be derived for structs with a single field
// ERROR: DerefMut can only be derived for structs with a single field
```
Additionally, the possible confusion and footguns are mainly an issue
for newer Rust/Bevy users. Those familiar with `Deref` and `DerefMut`
understand what adding the derive really means and can anticipate its
behavior.
## Solution
Allow users to opt into multi-field `Deref`/`DerefMut` derives using a
`#[deref]` attribute:
```rust
#[derive(Deref, DerefMut)]
struct MyStruct<T>(
// Use this field for the `Deref`/`DerefMut` impls
#[deref] String,
// We can freely include any other field without a compile error
PhantomData<T>
);
```
This prevents the footgun pointed out in the first issue described in
the previous section, but it still leaves the possible confusion
surrounding `.0`-vs-`.#`. However, the idea is that by making this
behavior explicit with an attribute, users will be more aware of it and
can adapt appropriately.
---
## Changelog
- Added `#[deref]` attribute to `Deref` and `DerefMut` derives
# Objective
- Fix bad links in the WebGPU example page
## Solution
- Bevy website always add the trailing slash, keep the link relative by
removing the current folder from it
# Objective
- Replace the `example_showcase.sh` script
- Helper tool to prepare the example page on the website
## Solution
- Have a command to run all the examples: `cargo run -p example-showcase
-- run`
- Have a command to take screenshots of all examples: `cargo run -p
example-showcase -- run --screenshot`
- Have a command to build the markdown files for the website: `cargo run
-p example-showcase -- build-website-list --content-folder content`
- Have a command to build all the examples in wasm/WebGPU: `cargo run -p
example-showcase -- build-web-gpu-examples --content-folder webgpus`
(with `--website-hacks` to enable the hacks for the Bevy website: canvas
id, resizing and loading bar)
This is the first step to an improved example page (all examples marked
as wasm, uses the card layout, has screenshots, reuse name, category and
description from the metadata). As one of the goal is to have a page
with WebGPU examples before the official release, this is not touching
the example page for now but targeting a new one.
<img width="1912" alt="Screenshot 2023-05-06 at 17 16 25"
src="https://user-images.githubusercontent.com/8672791/236632744-4372c95f-c50a-4168-973f-349412548f33.png">
# Objective
- Support WebGPU
- alternative to #5027 that doesn't need any async / await
- fixes#8315
- Surprise fix#7318
## Solution
### For async renderer initialisation
- Update the plugin lifecycle:
- app builds the plugin
- calls `plugin.build`
- registers the plugin
- app starts the event loop
- event loop waits for `ready` of all registered plugins in the same
order
- returns `true` by default
- then call all `finish` then all `cleanup` in the same order as
registered
- then execute the schedule
In the case of the renderer, to avoid anything async:
- building the renderer plugin creates a detached task that will send
back the initialised renderer through a mutex in a resource
- `ready` will wait for the renderer to be present in the resource
- `finish` will take that renderer and place it in the expected
resources by other plugins
- other plugins (that expect the renderer to be available) `finish` are
called and they are able to set up their pipelines
- `cleanup` is called, only custom one is still for pipeline rendering
### For WebGPU support
- update the `build-wasm-example` script to support passing `--api
webgpu` that will build the example with WebGPU support
- feature for webgl2 was always enabled when building for wasm. it's now
in the default feature list and enabled on all platforms, so check for
this feature must also check that the target_arch is `wasm32`
---
## Migration Guide
- `Plugin::setup` has been renamed `Plugin::cleanup`
- `Plugin::finish` has been added, and plugins adding pipelines should
do it in this function instead of `Plugin::build`
```rust
// Before
impl Plugin for MyPlugin {
fn build(&self, app: &mut App) {
app.insert_resource::<MyResource>
.add_systems(Update, my_system);
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};
render_app
.init_resource::<RenderResourceNeedingDevice>()
.init_resource::<OtherRenderResource>();
}
}
// After
impl Plugin for MyPlugin {
fn build(&self, app: &mut App) {
app.insert_resource::<MyResource>
.add_systems(Update, my_system);
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};
render_app
.init_resource::<OtherRenderResource>();
}
fn finish(&self, app: &mut App) {
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};
render_app
.init_resource::<RenderResourceNeedingDevice>();
}
}
```
# Objective
Add a convenient immediate mode drawing API for visual debugging.
Fixes#5619
Alternative to #1625
Partial alternative to #5734
Based off https://github.com/Toqozz/bevy_debug_lines with some changes:
* Simultaneous support for 2D and 3D.
* Methods for basic shapes; circles, spheres, rectangles, boxes, etc.
* 2D methods.
* Removed durations. Seemed niche, and can be handled by users.
<details>
<summary>Performance</summary>
Stress tested using Bevy's recommended optimization settings for the dev
profile with the
following command.
```bash
cargo run --example many_debug_lines \
--config "profile.dev.package.\"*\".opt-level=3" \
--config "profile.dev.opt-level=1"
```
I dipped to 65-70 FPS at 300,000 lines
CPU: 3700x
RAM Speed: 3200 Mhz
GPU: 2070 super - probably not very relevant, mostly cpu/memory bound
</details>
<details>
<summary>Fancy bloom screenshot</summary>
![Screenshot_20230207_155033](https://user-images.githubusercontent.com/29694403/217291980-f1e0500e-7a14-4131-8c96-eaaaf52596ae.png)
</details>
## Changelog
* Added `GizmoPlugin`
* Added `Gizmos` system parameter for drawing lines and wireshapes.
### TODO
- [ ] Update changelog
- [x] Update performance numbers
- [x] Add credit to PR description
### Future work
- Cache rendering primitives instead of constructing them out of line
segments each frame.
- Support for drawing solid meshes
- Interactions. (See
[bevy_mod_gizmos](https://github.com/LiamGallagher737/bevy_mod_gizmos))
- Fancier line drawing. (See
[bevy_polyline](https://github.com/ForesightMiningSoftwareCorporation/bevy_polyline))
- Support for `RenderLayers`
- Display gizmos for a certain duration. Currently everything displays
for one frame (ie. immediate mode)
- Changing settings per drawn item like drawing on top or drawing to
different `RenderLayers`
Co-Authored By: @lassade <felipe.jorge.pereira@gmail.com>
Co-Authored By: @The5-1 <agaku@hotmail.de>
Co-Authored By: @Toqozz <toqoz@hotmail.com>
Co-Authored By: @nicopap <nico@nicopap.ch>
---------
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: IceSentry <c.giguere42@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
UIs created for Bevy cannot currently be made accessible. This PR aims to address that.
## Solution
Integrate AccessKit as a dependency, adding accessibility support to existing bevy_ui widgets.
## Changelog
### Added
* Integrate with and expose [AccessKit](https://accesskit.dev) for platform accessibility.
* Add `Label` for marking text specifically as a label for UI controls.
# Objective
- Fixes#1800, fixes#6984
- Alternative to #7196
- Ensure feature list is always up to date and that all are documented
- Help discovery of features
## Solution
- Use a template to update the cargo feature list
- Use the comment just above the feature declaration as the description
- Add the checks to CI
- Add the features to the base crate doc
# Objective
Fixes#5675. Replace `toml` with `toml_edit`
## Solution
Replace `toml` with `toml_edit`. This conveniently also removes the `serde` dependency from `bevy_macro_utils`, which may speed up cold compilation by removing the serde bottleneck from most of the macro crates in the engine.
# Objective
I noticed that running the following command didn't actually do anything:
```
cargo run -p ci -- bench-check
```
## Solution
Made it so that running `cargo run -p ci -- bench-check` actually runs a compile check on the `benches` directory.
# Objective
There isn't really a way to test that code using bevy_reflect compiles or doesn't compile for certain scenarios. This would be especially useful for macro-centric PRs like #6511 and #6042.
## Solution
Using `bevy_ecs_compile_fail_tests` as reference, added the `bevy_reflect_compile_fail_tests` crate.
Currently, this crate contains a very simple test case. This is so that we can get the basic foundation of this crate agreed upon and merged so that more tests can be added by other PRs.
### Open Questions
- [x] Should this be added to CI? (Answer: Yes)
---
## Changelog
- Added the `bevy_reflect_compile_fail_tests` crate for testing compilation errors
# Objective
- fix new clippy lints before they get stable and break CI
## Solution
- run `clippy --fix` to auto-fix machine-applicable lints
- silence `clippy::should_implement_trait` for `fn HandleId::default<T: Asset>`
## Changes
- always prefer `format!("{inline}")` over `format!("{}", not_inline)`
- prefer `Box::default` (or `Box::<T>::default` if necessary) over `Box::new(T::default())`
# Objective
Alternative to #6150
Dependabot's PR doesn't seem to break anything, but there are some deprecations that we might as well fix up.
## Solution
https://github.com/clap-rs/clap/blob/master/CHANGELOG.md#migrating
Update clap in `build-wasm-example` and `span-cmp`. Other tools don't use clap.
Remove references to `value_parser`. It's the default now.
Change `#[clap()]` to `#[arg()]`.
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Objective
Fixes https://github.com/bevyengine/bevy/issues/6063
## Solution
- Use `then_some(x)` instead of `then( || x)`.
- Updated error logs from `bevy_ecs_compile_fail_tests`.
## Migration Guide
From Rust 1.63 to 1.64, a new Clippy error was added; now one should use `then_some(x)` instead of `then( || x)`.
# Summary
This method strips a long type name like `bevy::render:📷:PerspectiveCameraBundle` down into the bare type name (`PerspectiveCameraBundle`). This is generally useful utility method, needed by #4299 and #5121.
As a result:
- This method was moved to `bevy_utils` for easier reuse.
- The legibility and robustness of this method has been significantly improved.
- Harder test cases have been added.
This change was split out of #4299 to unblock it and make merging / reviewing the rest of those changes easier.
## Changelog
- added `bevy_utils::get_short_name`, which strips the path from a type name for convenient display.
- removed the `TypeRegistry::get_short_name` method. Use the function in `bevy_utils` instead.
# Objective
- Have information about examples only in one place that can be used for the repo and for the website (and remove the need to keep a list of example to build for wasm in the website 75acb73040/generate-wasm-examples/generate_wasm_examples.sh (L92-L99))
## Solution
- Add metadata about examples in `Cargo.toml`
- Build the `examples/README.md` from a template using those metadata. I used tera as the template engine to use the same tech as the website.
- Make CI fail if an example is missing metadata, or if the readme file needs to be updated (the command to update it is displayed in the failed step in CI)
## Remaining To Do
- After the next release with this merged in, the website will be able to be updated to use those metadata too
- I would like to build the examples in wasm and make them available at http://dev-docs.bevyengine.org/ but that will require more design
- https://github.com/bevyengine/bevy-website/issues/299 for other ToDos
Co-authored-by: Readme <github-actions@github.com>
# Objective
- Fix CI
- relevant clap issue https://github.com/clap-rs/clap/issues/3822
## Solution
- slap `value_parser` on all the clap derives. This tells clap to use the default parser for the type.
# Objective
- Run examples in WASM in CI
- Fix#4817
## Solution
- on feature `bevy_ci_testing`
- add an extra log message before exiting
- when building for wasm, read CI config file at compile time
- add a simple [playwright](https://playwright.dev) test script that opens the browser then waits for the success log, and takes a screenshot
- add a CI job that runs the playwright test for Chromium and Firefox on one example (lighting) and save the screenshots
- Firefox screenshot is good (with some clusters visible)
- Chromium screenshot is gray, I don't know why but it's logging `GPU stall due to ReadPixels`
- Webkit is not enabled for now, to revisit once https://bugs.webkit.org/show_bug.cgi?id=234926 is fixed or worked around
- the CI job only runs on bors validation
example run: https://github.com/mockersf/bevy/actions/runs/2361673465. The screenshots can be downloaded
# Objective
Models can be produced that do not have vertex tangents but do have normal map textures. The tangents can be generated. There is a way that the vertex tangents can be generated to be exactly invertible to avoid introducing error when recreating the normals in the fragment shader.
## Solution
- After attempts to get https://github.com/gltf-rs/mikktspace to integrate simple glam changes and version bumps, and releases of that crate taking weeks / not being made (no offense intended to the authors/maintainers, bevy just has its own timelines and needs to take care of) it was decided to fork that repository. The following steps were taken:
- mikktspace was forked to https://github.com/bevyengine/mikktspace in order to preserve the repository's history in case the original is ever taken down
- The README in that repo was edited to add a note stating from where the repository was forked and explaining why
- The repo was locked for changes as its only purpose is historical
- The repo was integrated into the bevy repo using `git subtree add --prefix crates/bevy_mikktspace git@github.com:bevyengine/mikktspace.git master`
- In `bevy_mikktspace`:
- The travis configuration was removed
- `cargo fmt` was run
- The `Cargo.toml` was conformed to bevy's (just adding bevy to the keywords, changing the homepage and repository, changing the version to 0.7.0-dev - importantly the license is exactly the same)
- Remove the features, remove `nalgebra` entirely, only use `glam`, suppress clippy.
- This was necessary because our CI runs clippy with `--all-features` and the `nalgebra` and `glam` features are mutually exclusive, plus I don't want to modify this highly numerically-sensitive code just to appease clippy and diverge even more from upstream.
- Rebase https://github.com/bevyengine/bevy/pull/1795
- @jakobhellermann said it was fine to copy and paste but it ended up being almost exactly the same with just a couple of adjustments when validating correctness so I decided to actually rebase it and then build on top of it.
- Use the exact same fragment shader code to ensure correct normal mapping.
- Tested with both https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/NormalTangentMirrorTest which has vertex tangents and https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/NormalTangentTest which requires vertex tangent generation
Co-authored-by: alteous <alteous@outlook.com>
# Objective
- Add an `ExtractResourcePlugin` for convenience and consistency
## Solution
- Add an `ExtractResourcePlugin` similar to `ExtractComponentPlugin` but for ECS `Resource`s. The system that is executed simply clones the main world resource into a render world resource, if and only if the main world resource was either added or changed since the last execution of the system.
- Add an `ExtractResource` trait with a `fn extract_resource(res: &Self) -> Self` function. This is used by the `ExtractResourcePlugin` to extract the resource
- Add a derive macro for `ExtractResource` on a `Resource` with the `Clone` trait, that simply returns `res.clone()`
- Use `ExtractResourcePlugin` wherever both possible and appropriate
# Objective
Reduce the catch-all grab-bag of functionality in bevy_core by minimally splitting off time functionality into bevy_time. Functionality like that provided by #3002 would increase the complexity of bevy_time, so this is a good candidate for pulling into its own unit.
A step in addressing #2931 and splitting bevy_core into more specific locations.
## Solution
Pull the time module of bevy_core into a new crate, bevy_time.
# Migration guide
- Time related types (e.g. `Time`, `Timer`, `Stopwatch`, `FixedTimestep`, etc.) should be imported from `bevy::time::*` rather than `bevy::core::*`.
- If you were adding `CorePlugin` manually, you'll also want to add `TimePlugin` from `bevy::time`.
- The `bevy::core::CorePlugin::Time` system label is replaced with `bevy::time::TimeSystem`.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Have an easy way to compare spans between executions
## Solution
- Add a tool to compare spans from chrome traces
```bash
> cargo run --release -p spancmp -- --help
Compiling spancmp v0.1.0
Finished release [optimized] target(s) in 1.10s
Running `target/release/spancmp --help`
spancmp
USAGE:
spancmp [OPTIONS] <TRACE> [SECOND_TRACE]
ARGS:
<TRACE>
<SECOND_TRACE>
OPTIONS:
-h, --help Print help information
-p, --pattern <PATTERN> Filter spans by name matching the pattern
-t, --threshold <THRESHOLD> Filter spans that have an average shorther than the threshold
[default: 0]
```
for each span, it will display the count, minimum duration, average duration and max duration. It can be filtered by a pattern on the span name or by a minimum average duration.
just displaying a trace
![Screenshot 2022-04-28 at 21 56 21](https://user-images.githubusercontent.com/8672791/165835310-f465c6f2-9e6b-4808-803e-884b06e49292.png)
comparing two traces
![Screenshot 2022-04-28 at 21 56 55](https://user-images.githubusercontent.com/8672791/165835353-097d266b-a70c-41b8-a8c1-27804011dc97.png)
Co-authored-by: Robert Swain <robert.swain@gmail.com>
# Objective
The pointer types introduced in #3001 are useful not just in `bevy_ecs`, but also in crates like `bevy_reflect` (#4475) or even outside of bevy.
## Solution
Extract `Ptr<'a>`, `PtrMut<'a>`, `OwnedPtr<'a>`, `ThinSlicePtr<'a, T>` and `UnsafeCellDeref` from `bevy_ecs::ptr` into `bevy_ptr`.
**Note:** `bevy_ecs` still reexports the `bevy_ptr` as `bevy_ecs::ptr` so that crates like `bevy_transform` can use the `Bundle` derive without needing to depend on `bevy_ptr` themselves.
# Objective
- Original objective was to add doc build warning check to the ci local execution
- I somewhat deviated and changed other things...
## Solution
`cargo run -p ci` can now take more parameters:
* `format` - cargo fmt
* `clippy` - clippy
* `compile-fail` - bevy_ecs_compile_fail_tests tests
* `test` - tests but not doc tests and do not build examples
* `doc-test` - doc tests
* `doc-check` - doc build and warnings
* `bench-check` - check that benches build
* `example-check` - check that examples build
* `lints` - group - run lints and format and clippy
* `doc` - group - run doc-test and doc-check
* `compile` - group - run compile-fail and bench-check and example-check
* not providing a parameter will run everything
Ci is using those when possible:
* `build` jobs now don't run doc tests and don't build examples. it makes this job faster, but doc tests and examples are not built for each architecture target
* `ci` job doesn't run the `compile-fail` part but only format and clippy, taking less time
* `check-benches` becomes `check-compiles` and runs the `compile` tasks. It takes longer. I also fixed how it was using cache
* `check-doc` job is now independent and also run the doc tests, so it takes longer. I commented out the deadlinks check as it takes 2.5 minutes (to install) and doesn't work
# Objective
- Using the `cargo run -p ci` command locally is unreliable, as it does not run tests.
- This is particularly unreliable for doc tests, as they are not run as part of `cargo test`.
## Solution
- add more steps to the appropriate Rust file.
## Known Problems
This duplicates work done to run tests when run on Github. @mockersf, suggestions on if we care / how we can mitigate it?