# Objective
- `README.md` is a common file that usually gives an overview of the
folder it is in.
- When on <https://crates.io>, `README.md` is rendered as the main
description.
- Many crates in this repository are lacking `README.md` files, which
makes it more difficult to understand their purpose.
<img width="1552" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/78ebf91d-b0c4-4b18-9874-365d6310640f">
- There are also a few inconsistencies with `README.md` files that this
PR and its follow-ups intend to fix.
## Solution
- Create a `README.md` file for all crates that do not have one.
- This file only contains the title of the crate (underscores removed,
proper capitalization, acronyms expanded) and the <https://shields.io>
badges.
- Remove the `readme` field in `Cargo.toml` for `bevy` and
`bevy_reflect`.
- This field is redundant because [Cargo automatically detects
`README.md`
files](https://doc.rust-lang.org/cargo/reference/manifest.html#the-readme-field).
The field is only there if you name it something else, like `INFO.md`.
- Fix capitalization of `bevy_utils`'s `README.md`.
- It was originally `Readme.md`, which is inconsistent with the rest of
the project.
- I created two commits renaming it to `README.md`, because Git appears
to be case-insensitive.
- Expand acronyms in title of `bevy_ptr` and `bevy_utils`.
- In the commit where I created all the new `README.md` files, I
preferred using expanded acronyms in the titles. (E.g. "Bevy Developer
Tools" instead of "Bevy Dev Tools".)
- This commit changes the title of existing `README.md` files to follow
the same scheme.
- I do not feel strongly about this change, please comment if you
disagree and I can revert it.
- Add <https://shields.io> badges to `bevy_time` and `bevy_transform`,
which are the only crates currently lacking them.
---
## Changelog
- Added `README.md` files to all crates missing it.
# Objective
- Fixes#13024.
## Solution
- Run `cargo clippy --target wasm32-unknown-unknown` until there are no
more errors.
- I recommend reviewing one commit at a time :)
---
## Changelog
- Fixed Clippy lints for `wasm32-unknown-unknown` target.
- Updated `bevy_transform`'s `README.md`.
# Objective
Related to #12981
Presently, there is a footgun where we allow non-normalized vectors to
be passed in the `axis` parameters of `Transform::rotate_axis` and
`Transform::rotate_local_axis`. These methods invoke
`Quat::from_axis_angle` which expects the vector to be normalized. This
PR aims to address this.
## Solution
Require `Dir3`-valued `axis` parameters for these functions so that the
vector's normalization can be enforced at type-level.
---
## Migration Guide
All calls to `Transform::rotate_axis` and `Transform::rotate_local_axis`
will need to be updated to use a `Dir3` for the `axis` parameter rather
than a `Vec3`. For a general input, this means calling `Dir3::new` and
handling the `Result`, but if the previous vector is already known to be
normalized, `Dir3::new_unchecked` can be called instead. Note that
literals like `Vec3::X` also have corresponding `Dir3` literals; e.g.
`Dir3::X`, `Dir3::NEG_Y` and so on.
---
## Discussion
This axis input is unambigiously a direction instead of a vector, and
that should probably be reflected and enforced by the function
signature. In previous cases where we used, e.g., `impl TryInto<Dir3>`,
the associated methods already implemented (and required!) additional
fall-back logic, since the input is conceptually more complicated than
merely specifying an axis. In this case, I think it's fairly
cut-and-dry, and I'm pretty sure these methods just predate our
direction types.
# Objective
- There are several redundant imports in the tests and examples that are
not caught by CI because additional flags need to be passed.
## Solution
- Run `cargo check --workspace --tests` and `cargo check --workspace
--examples`, then fix all warnings.
- Add `test-check` to CI, which will be run in the check-compiles job.
This should catch future warnings for tests. Examples are already
checked, but I'm not yet sure why they weren't caught.
## Discussion
- Should the `--tests` and `--examples` flags be added to CI, so this is
caught in the future?
- If so, #12818 will need to be merged first. It was also a warning
raised by checking the examples, but I chose to split off into a
separate PR.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
This is a necessary precursor to #9122 (this was split from that PR to
reduce the amount of code to review all at once).
Moving `!Send` resource ownership to `App` will make it unambiguously
`!Send`. `SubApp` must be `Send`, so it can't wrap `App`.
## Solution
Refactor `App` and `SubApp` to not have a recursive relationship. Since
`SubApp` no longer wraps `App`, once `!Send` resources are moved out of
`World` and into `App`, `SubApp` will become unambiguously `Send`.
There could be less code duplication between `App` and `SubApp`, but
that would break `App` method chaining.
## Changelog
- `SubApp` no longer wraps `App`.
- `App` fields are no longer publicly accessible.
- `App` can no longer be converted into a `SubApp`.
- Various methods now return references to a `SubApp` instead of an
`App`.
## Migration Guide
- To construct a sub-app, use `SubApp::new()`. `App` can no longer
convert into `SubApp`.
- If you implemented a trait for `App`, you may want to implement it for
`SubApp` as well.
- If you're accessing `app.world` directly, you now have to use
`app.world()` and `app.world_mut()`.
- `App::sub_app` now returns `&SubApp`.
- `App::sub_app_mut` now returns `&mut SubApp`.
- `App::get_sub_app` now returns `Option<&SubApp>.`
- `App::get_sub_app_mut` now returns `Option<&mut SubApp>.`
# Objective
Resolves#3824. `unsafe` code should be the exception, not the norm in
Rust. It's obviously needed for various use cases as it's interfacing
with platforms and essentially running the borrow checker at runtime in
the ECS, but the touted benefits of Bevy is that we are able to heavily
leverage Rust's safety, and we should be holding ourselves accountable
to that by minimizing our unsafe footprint.
## Solution
Deny `unsafe_code` workspace wide. Add explicit exceptions for the
following crates, and forbid it in almost all of the others.
* bevy_ecs - Obvious given how much unsafe is needed to achieve
performant results
* bevy_ptr - Works with raw pointers, even more low level than bevy_ecs.
* bevy_render - due to needing to integrate with wgpu
* bevy_window - due to needing to integrate with raw_window_handle
* bevy_utils - Several unsafe utilities used by bevy_ecs. Ideally moved
into bevy_ecs instead of made publicly usable.
* bevy_reflect - Required for the unsafe type casting it's doing.
* bevy_transform - for the parallel transform propagation
* bevy_gizmos - For the SystemParam impls it has.
* bevy_assets - To support reflection. Might not be required, not 100%
sure yet.
* bevy_mikktspace - due to being a conversion from a C library. Pending
safe rewrite.
* bevy_dynamic_plugin - Inherently unsafe due to the dynamic loading
nature.
Several uses of unsafe were rewritten, as they did not need to be using
them:
* bevy_text - a case of `Option::unchecked` could be rewritten as a
normal for loop and match instead of an iterator.
* bevy_color - the Pod/Zeroable implementations were replaceable with
bytemuck's derive macros.
# Objective
I found that some .rs files are unnecessarily executable.
Rust source files may start with a shebang-like statement `#!`, so let's
make sure they are not executable just in case.
Here is the result of the `find` commend that lists executable .rs files
as of main branch `86bd648`.
```console
$ find -name \*.rs -type f -executable
./crates/bevy_gizmos/src/lib.rs
./crates/bevy_tasks/src/lib.rs
./crates/bevy_time/src/lib.rs
./crates/bevy_transform/src/lib.rs
./src/lib.rs
```
It appears that the permissions of those files were originally 644, but
were unexpectedly changed to 755 by commit
52e3f2007b.
## Solution
Make them not executable by using this command;
`find -name \*.rs -type f -executable -exec chmod --verbose a-x -- {}
\+`
# Objective
Currently the built docs only shows the logo and favicon for the top
level `bevy` crate. This makes views like
https://docs.rs/bevy_ecs/latest/bevy_ecs/ look potentially unrelated to
the project at first glance.
## Solution
Reproduce the docs attributes for every crate that Bevy publishes.
Ideally this would be done with some workspace level Cargo.toml control,
but AFAICT, such support does not exist.
# Objective
Make `Transform` APIs more ergonomic by allowing users to pass `Dir3` as
an argument where a direction is needed. Fixes#12481.
## Solution
Accept `impl TryInto<Dir3>` instead of `Vec3` for direction/axis
arguments in `Transform` APIs
---
## Changelog
The following `Transform` methods now accept an `impl TryInto<Dir3>`
argument where they previously accepted directions as `Vec3`:
* `Transform::{look_to,looking_to}`
* `Transform::{look_at,looking_at}`
* `Transform::{align,aligned_by}`
## Migration Guide
This is not a breaking change since the arguments were previously `Vec3`
which already implements `TryInto<Dir3>`, and behavior is unchanged.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
# Objective
- Closes#11793
- Introduces a general API for aligning local coordinates of Transforms
with given vectors.
## Solution
- We introduce `Transform::align`, which allows a rotation to be
specified by four pieces of alignment data, as explained by the
documentation:
````rust
/// Rotates this [`Transform`] so that the `main_axis` vector, reinterpreted in local coordinates, points
/// in the given `main_direction`, while `secondary_axis` points towards `secondary_direction`.
///
/// For example, if a spaceship model has its nose pointing in the X-direction in its own local coordinates
/// and its dorsal fin pointing in the Y-direction, then `align(Vec3::X, v, Vec3::Y, w)` will make the spaceship's
/// nose point in the direction of `v`, while the dorsal fin does its best to point in the direction `w`.
///
/// More precisely, the [`Transform::rotation`] produced will be such that:
/// * applying it to `main_axis` results in `main_direction`
/// * applying it to `secondary_axis` produces a vector that lies in the half-plane generated by `main_direction` and
/// `secondary_direction` (with positive contribution by `secondary_direction`)
///
/// [`Transform::look_to`] is recovered, for instance, when `main_axis` is `Vec3::NEG_Z` (the [`Transform::forward`]
/// direction in the default orientation) and `secondary_axis` is `Vec3::Y` (the [`Transform::up`] direction in the default
/// orientation). (Failure cases may differ somewhat.)
///
/// In some cases a rotation cannot be constructed. Another axis will be picked in those cases:
/// * if `main_axis` or `main_direction` is zero, `Vec3::X` takes its place
/// * if `secondary_axis` or `secondary_direction` is zero, `Vec3::Y` takes its place
/// * if `main_axis` is parallel with `secondary_axis` or `main_direction` is parallel with `secondary_direction`,
/// a rotation is constructed which takes `main_axis` to `main_direction` along a great circle, ignoring the secondary
/// counterparts
///
/// Example
/// ```
/// # use bevy_math::{Vec3, Quat};
/// # use bevy_transform::components::Transform;
/// let mut t1 = Transform::IDENTITY;
/// let mut t2 = Transform::IDENTITY;
/// t1.align(Vec3::ZERO, Vec3::Z, Vec3::ZERO, Vec3::X);
/// t2.align(Vec3::X, Vec3::Z, Vec3::Y, Vec3::X);
/// assert_eq!(t1.rotation, t2.rotation);
///
/// t1.align(Vec3::X, Vec3::Z, Vec3::X, Vec3::Y);
/// assert_eq!(t1.rotation, Quat::from_rotation_arc(Vec3::X, Vec3::Z));
/// ```
pub fn align(
&mut self,
main_axis: Vec3,
main_direction: Vec3,
secondary_axis: Vec3,
secondary_direction: Vec3,
) { //... }
````
- We introduce `Transform::aligned_by`, the returning-Self version of
`align`:
````rust
pub fn aligned_by(
mut self,
main_axis: Vec3,
main_direction: Vec3,
secondary_axis: Vec3,
secondary_direction: Vec3,
) -> Self { //... }
````
- We introduce an example (examples/transforms/align.rs) that shows the
usage of this API. It is likely to be mathier than most other
`Transform` APIs, so when run, the example demonstrates what the API
does in space:
<img width="1440" alt="Screenshot 2024-03-12 at 11 01 19 AM"
src="https://github.com/bevyengine/bevy/assets/2975848/884b3cc3-cbd9-48ae-8f8c-49a677c59dfe">
---
## Changelog
- Added methods `align`, `aligned_by` to `Transform`.
- Added transforms/align.rs to examples.
---
## Discussion
### On the form of `align`
The original issue linked above suggests an API similar to that of the
existing `Transform::look_to` method:
````rust
pub fn align_to(&mut self, direction: Vec3, up: Vec3) { //... }
````
Not allowing an input axis of some sort that is to be aligned with
`direction` would not really solve the problem in the issue, since the
user could easily be in a scenario where they have to compose with
another rotation on their own (undesirable). This leads to something
like:
````rust
pub fn align_to(&mut self, axis: Vec3, direction: Vec3, up: Vec3) { //... }
````
However, this still has two problems:
- If the vector that the user wants to align is parallel to the Y-axis,
then the API basically does not work (we cannot fully specify a
rotation)
- More generally, it does not give the user the freedom to specify which
direction is to be treated as the local "up" direction, so it fails as a
general alignment API
Specifying both leads us to the present situation, with two local axis
inputs (`main_axis` and `secondary_axis`) and two target directions
(`main_direction` and `secondary_direction`). This might seem a little
cumbersome for general use, but for the time being I stand by the
decision not to expand further without prompting from users. I'll expand
on this below.
### Additional APIs?
Presently, this PR introduces only `align` and `aligned_by`. Other
potentially useful bundles of API surface arrange into a few different
categories:
1. Inferring direction from position, a la `Transform::look_at`, which
might look something like this:
````rust
pub fn align_at(&mut self, axis: Vec3, target: Vec3, up: Vec3) {
self.align(axis, target - self.translation, Vec3::Y, up);
}
````
(This is simple but still runs into issues when the user wants to point
the local Y-axis somewhere.)
2. Filling in some data for the user for common use-cases; e.g.:
````rust
pub fn align_x(&mut self, direction: Vec3, up: Vec3) {
self.align(Vec3::X, direction, Vec3::Y, up);
}
````
(Here, use of the `up` vector doesn't lose any generality, but it might
be less convenient to specify than something else. This does naturally
leave open the question of what `align_y` would look like if we provided
it.)
Morally speaking, I do think that the `up` business is more pertinent
when the intention is to work with cameras, which the `look_at` and
`look_to` APIs seem to cover pretty well. If that's the case, then I'm
not sure what the ideal shape for these API functions would be, since it
seems like a lot of input would have to be baked into the function
definitions. For some cases, this might not be the end of the world:
````rust
pub fn align_x_z(&mut self, direction: Vec3, weak_direction: Vec3) {
self.align(Vec3::X, direction, Vec3::Z, weak_direction);
}
````
(However, this is not symmetrical in x and z, so you'd still need six
API functions just to support the standard positive coordinate axes, and
if you support negative axes then things really start to balloon.)
The reasons that these are not actually produced in this PR are as
follows:
1. Without prompting from actual users in the wild, it is unknown to me
whether these additional APIs would actually see a lot of use. Extending
these to our users in the future would be trivial if we see there is a
demand for something specific from the above-mentioned categories.
2. As discussed above, there are so many permutations of these that
could be provided that trying to do so looks like it risks unduly
ballooning the API surface for this feature.
3. Finally, and most importantly, creating these helper functions in
user-space is trivial, since they all just involve specializing `align`
to particular inputs; e.g.:
````rust
fn align_ship(ship_transform: &mut Transform, nose_direction: Vec3, dorsal_direction: Vec3) {
ship_transform.align(Ship::NOSE, nose_direction, Ship::DORSAL, dorsal_direction);
}
````
With that in mind, I would prefer instead to focus on making the
documentation and examples for a thin API as clear as possible, so that
users can get a grip on the tool and specialize it for their own needs
when they feel the desire to do so.
### `Dir3`?
As in the case of `Transform::look_to` and `Transform::look_at`, the
inputs to this function are, morally speaking, *directions* rather than
vectors (actually, if we're being pedantic, the input is *really really*
a pair of orthonormal frames), so it's worth asking whether we should
really be using `Dir3` as inputs instead of `Vec3`. I opted for `Vec3`
for the following reasons:
1. Specifying a `Dir3` in user-space is just more annoying than
providing a `Vec3`. Even in the most basic cases (e.g. providing a
vector literal), you still have to do error handling or call an unsafe
unwrap in your function invocations.
2. The existing API mentioned above uses `Vec3`, so we are just adhering
to the same thing.
Of course, the use of `Vec3` has its own downsides; it can be argued
that the replacement of zero-vectors with fixed ones (which we do in
`Transform::align` as well as `Transform::look_to`) more-or-less amounts
to failing silently.
### Future steps
The question of additional APIs was addressed above. For me, the main
thing here to handle more immediately is actually just upstreaming this
API (or something similar and slightly mathier) to `glam::Quat`. The
reason that this would be desirable for users is that this API currently
only works with `Transform`s even though all it's actually doing is
specifying a rotation. Upstreaming to `glam::Quat`, properly done, could
buy a lot basically for free, since a number of `Transform` methods take
a rotation as an input. Using these together would require a little bit
of mathematical savvy, but it opens up some good things (e.g.
`Transform::rotate_around`).
# Objective
Fix missing `TextBundle` (and many others) which are present in the main
crate as default features but optional in the sub-crate. See:
- https://docs.rs/bevy/0.13.0/bevy/ui/node_bundles/index.html
- https://docs.rs/bevy_ui/0.13.0/bevy_ui/node_bundles/index.html
~~There are probably other instances in other crates that I could track
down, but maybe "all-features = true" should be used by default in all
sub-crates? Not sure.~~ (There were many.) I only noticed this because
rust-analyzer's "open docs" features takes me to the sub-crate, not the
main one.
## Solution
Add "all-features = true" to docs.rs metadata for crates that use
features.
## Changelog
### Changed
- Unified features documented on docs.rs between main crate and
sub-crates
# Objective
Fixes https://github.com/bevyengine/bevy/issues/11628
## Migration Guide
`Command` and `CommandQueue` have migrated from `bevy_ecs::system` to
`bevy_ecs::world`, so `use bevy_ecs::world::{Command, CommandQueue};`
when necessary.
# Objective
Split up from #12017, rename Bevy's direction types.
Currently, Bevy has the `Direction2d`, `Direction3d`, and `Direction3dA`
types, which provide a type-level guarantee that their contained vectors
remain normalized. They can be very useful for a lot of APIs for safety,
explicitness, and in some cases performance, as they can sometimes avoid
unnecessary normalizations.
However, many consider them to be inconvenient to use, and opt for
standard vector types like `Vec3` because of this. One reason is that
the direction type names are a bit long and can be annoying to write (of
course you can use autocomplete, but just typing `Vec3` is still nicer),
and in some intances, the extra characters can make formatting worse.
The naming is also inconsistent with Glam's shorter type names, and
results in names like `Direction3dA`, which (in my opinion) are
difficult to read and even a bit ugly.
This PR proposes renaming the types to `Dir2`, `Dir3`, and `Dir3A`.
These names are nice and easy to write, consistent with Glam, and work
well for variants like the SIMD aligned `Dir3A`. As a bonus, it can also
result in nicer formatting in a lot of cases, which can be seen from the
diff of this PR.
Some examples of what it looks like: (copied from #12017)
```rust
// Before
let ray_cast = RayCast2d::new(Vec2::ZERO, Direction2d::X, 5.0);
// After
let ray_cast = RayCast2d::new(Vec2::ZERO, Dir2::X, 5.0);
```
```rust
// Before (an example using Bevy XPBD)
let hit = spatial_query.cast_ray(
Vec3::ZERO,
Direction3d::X,
f32::MAX,
true,
SpatialQueryFilter::default(),
);
// After
let hit = spatial_query.cast_ray(
Vec3::ZERO,
Dir3::X,
f32::MAX,
true,
SpatialQueryFilter::default(),
);
```
```rust
// Before
self.circle(
Vec3::new(0.0, -2.0, 0.0),
Direction3d::Y,
5.0,
Color::TURQUOISE,
);
// After (formatting is collapsed in this case)
self.circle(Vec3::new(0.0, -2.0, 0.0), Dir3::Y, 5.0, Color::TURQUOISE);
```
## Solution
Rename `Direction2d`, `Direction3d`, and `Direction3dA` to `Dir2`,
`Dir3`, and `Dir3A`.
---
## Migration Guide
The `Direction2d` and `Direction3d` types have been renamed to `Dir2`
and `Dir3`.
## Additional Context
This has been brought up on the Discord a few times, and we had a small
[poll](https://discord.com/channels/691052431525675048/1203087353850364004/1212465038711984158)
on this. `Dir2`/`Dir3`/`Dir3A` was quite unanimously chosen as the best
option, but of course it was a very small poll and inconclusive, so
other opinions are certainly welcome too.
---------
Co-authored-by: IceSentry <c.giguere42@gmail.com>
# Objective
Split up from #12017, add an aligned version of `Direction3d` for SIMD,
and move direction types out of `primitives`.
## Solution
Add `Direction3dA` and move direction types into a new `direction`
module.
---
## Migration Guide
The `Direction2d`, `Direction3d`, and `InvalidDirectionError` types have
been moved out of `bevy::math::primitives`.
Before:
```rust
use bevy::math::primitives::Direction3d;
```
After:
```rust
use bevy::math::Direction3d;
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Taplo in CI is not running. The link used to download taplo doesn't
work anymore.
## Solution
- Compile taplo directly with cargo
- Improve docs a little
- Run taplo
---------
Co-authored-by: François <mockersf@gmail.com>
Fixes#12016.
Bump version after release
This PR has been auto-generated
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
Currently the `missing_docs` lint is allowed-by-default and enabled at
crate level when their documentations is complete (see #3492).
This PR proposes to inverse this logic by making `missing_docs`
warn-by-default and mark crates with imcomplete docs allowed.
## Solution
Makes `missing_docs` warn at workspace level and allowed at crate level
when the docs is imcomplete.
# Objective
Drawing a `Gizmos::circle` whose normal is derived from a Transform's
local axes now requires converting a Vec3 to a Direction3d and
unwrapping the result, and I think we shold move the conversion into
Bevy.
## Solution
We can make
`Transform::{left,right,up,down,forward,back,local_x,local_y,local_z}`
return a Direction3d, because they know that their results will be of
finite non-zero length (roughly 1.0).
---
## Changelog
`Transform::up()` and similar functions now return `Direction3d` instead
of `Vec3`.
## Migration Guide
Callers of `Transform::up()` and similar functions may have to
dereference the returned `Direction3d` to get to the inner `Vec3`.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
# Objective
It would be convenient to be able to call functions with `Commands` as a
parameter without having to move your own instance of `Commands`. Since
this struct is composed entirely of references, we can easily get an
owned instance of `Commands` by shortening the lifetime.
## Solution
Add `Commands::reborrow`, `EntiyCommands::reborrow`, and
`Deferred::reborrow`, which returns an owned version of themselves with
a shorter lifetime.
Remove unnecessary lifetimes from `EntityCommands`. The `'w` and `'s`
lifetimes only have to be separate for `Commands` because it's used as a
`SystemParam` -- this is not the case for `EntityCommands`.
---
## Changelog
Added `Commands::reborrow`. This is useful if you have `&mut Commands`
but need `Commands`. Also added `EntityCommands::reborrow` and
`Deferred:reborrow` which serve the same purpose.
## Migration Guide
The lifetimes for `EntityCommands` have been simplified.
```rust
// Before (Bevy 0.12)
struct MyStruct<'w, 's, 'a> {
commands: EntityCommands<'w, 's, 'a>,
}
// After (Bevy 0.13)
struct MyStruct<'a> {
commands: EntityCommands<'a>,
}
```
The method `EntityCommands::commands` now returns `Commands` rather than
`&mut Commands`.
```rust
// Before (Bevy 0.12)
let commands = entity_commands.commands();
commands.spawn(...);
// After (Bevy 0.13)
let mut commands = entity_commands.commands();
commands.spawn(...);
```
# Objective
- Fixes#11187
## Solution
- Rename the `AddChild` struct to `PushChild`
- Rename the `AddChildInPlace` struct to `PushChildInPlace`
## Migration Guide
The struct `AddChild` has been renamed to `PushChild`, and the struct
`AddChildInPlace` has been renamed to `PushChildInPlace`.
# Objective
`bevy_math` re-exports Glam, but doesn't have a feature for enabling
`approx` for it. Many projects (including some of Bevy's own crates)
need `approx`, and it'd be nice if you didn't have to manually add Glam
to specify the feature for it.
## Solution
Add an `approx` feature to `bevy_math`.
# Objective
There are a lot of doctests that are `ignore`d for no documented reason.
And that should be fixed.
## Solution
I searched the bevy repo with the regex ` ```[a-z,]*ignore ` in order to
find all `ignore`d doctests. For each one of the `ignore`d doctests, I
did the following steps:
1. Attempt to remove the `ignored` attribute while still passing the
test. I did this by adding hidden dummy structs and imports.
2. If step 1 doesn't work, attempt to replace the `ignored` attribute
with the `no_run` attribute while still passing the test.
3. If step 2 doesn't work, keep the `ignored` attribute but add
documentation for why the `ignored` attribute was added.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
- Make the implementation order consistent between all sources to fit
the order in the trait.
## Solution
- Change the implementation order.
# Objective
- Shorten paths by removing unnecessary prefixes
## Solution
- Remove the prefixes from many paths which do not need them. Finding
the paths was done automatically using built-in refactoring tools in
Jetbrains RustRover.
# Objective
Enables warning on `clippy::undocumented_unsafe_blocks` across the
workspace rather than only in `bevy_ecs`, `bevy_transform` and
`bevy_utils`. This adds a little awkwardness in a few areas of code that
have trivial safety or explain safety for multiple unsafe blocks with
one comment however automatically prevents these comments from being
missed.
## Solution
This adds `undocumented_unsafe_blocks = "warn"` to the workspace
`Cargo.toml` and fixes / adds a few missed safety comments. I also added
`#[allow(clippy::undocumented_unsafe_blocks)]` where the safety is
explained somewhere above.
There are a couple of safety comments I added I'm not 100% sure about in
`bevy_animation` and `bevy_render/src/view` and I'm not sure about the
use of `#[allow(clippy::undocumented_unsafe_blocks)]` compared to adding
comments like `// SAFETY: See above`.
# Objective
- Standardize fmt for toml files
## Solution
- Add [taplo](https://taplo.tamasfe.dev/) to CI (check for fmt and diff
for toml files), for context taplo is used by the most popular extension
in VScode [Even Better
TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml
- Add contribution section to explain toml fmt with taplo.
Now to pass CI you need to run `taplo fmt --option indent_string=" "` or
if you use vscode have the `Even Better TOML` extension with 4 spaces
for indent
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Sometimes it's very useful to know if a `Transform` contains any `NaN`
or infinite values. It's a bit boiler-plate heavy to check translation,
rotation and scale individually.
## Solution
- Add a new method `is_finite` that returns true if, and only if
translation, rotation and scale all are finite.
- It's a natural extension of `Quat::is_finite`, and `Vec3::is_finite`,
which return true if, and only if all their components' `is_finite()`
returns true.
---
## Changelog
- Added `Transform::is_finite`
# Objective
- Fix adding `#![allow(clippy::type_complexity)]` everywhere. like #9796
## Solution
- Use the new [lints] table that will land in 1.74
(https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#lints)
- inherit lint to the workspace, crates and examples.
```
[lints]
workspace = true
```
## Changelog
- Bump rust version to 1.74
- Enable lints table for the workspace
```toml
[workspace.lints.clippy]
type_complexity = "allow"
```
- Allow type complexity for all crates and examples
```toml
[lints]
workspace = true
```
---------
Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
Preparing next release
This PR has been auto-generated
---------
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
Align all error-like types to implement `Error`.
Fixes #10176
## Solution
- Derive `Error` on more types
- Refactor instances of manual implementations that could be derived
This adds thiserror as a dependency to bevy_transform, which might
increase compilation time -- but I don't know of any situation where you
might only use that but not any other crate that pulls in bevy_utils.
The `contributors` example has a `LoadContributorsError` type, but as
it's an example I have not updated it. Doing that would mean either
having a `use bevy_internal::utils::thiserror::Error;` in an example
file, or adding `thiserror` as a dev-dependency to the main `bevy`
crate.
---
## Changelog
- All `…Error` types now implement the `Error` trait
# Objective
Reduce code duplication and improve APIs of Bevy's [global
taskpools](https://github.com/bevyengine/bevy/blob/main/crates/bevy_tasks/src/usages.rs).
## Solution
- As all three of the global taskpools have identical implementations
and only differ in their identifiers, this PR moves the implementation
into a macro to reduce code duplication.
- The `init` method is renamed to `get_or_init` to more accurately
reflect what it really does.
- Add a new `try_get` method that just returns `None` when the pool is
uninitialized, to complement the other getter methods.
- Minor documentation improvements to accompany the above changes.
---
## Changelog
- Added a new `try_get` method to the global TaskPools
- The global TaskPools' `init` method has been renamed to `get_or_init`
for clarity
- Documentation improvements
## Migration Guide
- Uses of `ComputeTaskPool::init`, `AsyncComputeTaskPool::init` and
`IoTaskPool::init` should be changed to `::get_or_init`.
# Objective
Add a way to easily compute the up-to-date `GlobalTransform` of an
entity.
## Solution
Add the `TransformHelper`(Name pending) system parameter with the
`compute_global_transform` method that takes an `Entity` and returns a
`GlobalTransform` if successful.
## Changelog
- Added the `TransformHelper` system parameter for computing the
up-to-date `GlobalTransform` of an entity.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Noah <noahshomette@gmail.com>
# Objective
- Updates for rust 1.73
## Solution
- new doc check for `redundant_explicit_links`
- updated to text for compile fail tests
---
## Changelog
- updates for rust 1.73
# Objective
Rename RemovedComponents::iter/iter_with_id to read/read_with_id to make
it clear that it consume the data
Fixes#9755.
(It's my first pull request, if i've made any mistake, please let me
know)
## Solution
Refactor RemovedComponents::iter/iter_with_id to read/read_with_id
## Changelog
Refactor RemovedComponents::iter/iter_with_id to read/read_with_id
Deprecate RemovedComponents::iter/iter_with_id
Remove IntoIterator implementation
Update removal_detection example accordingly
---
## Migration Guide
Rename calls of RemovedComponents::iter/iter_with_id to
read/read_with_id
Replace IntoIterator iteration (&mut <RemovedComponents>) with .read()
---------
Co-authored-by: denshi_ika <mojang2824@gmail.com>
# Objective
- Fixes#9244.
## Solution
- Changed the `(Into)SystemSetConfigs` traits and structs be more like
the `(Into)SystemConfigs` traits and structs.
- Replaced uses of `IntoSystemSetConfig` with `IntoSystemSetConfigs`
- Added generic `ItemConfig` and `ItemConfigs` types.
- Changed `SystemConfig(s)` and `SystemSetConfig(s)` to be type aliases
to `ItemConfig(s)`.
- Added generic `process_configs` to `ScheduleGraph`.
- Changed `configure_sets_inner` and `add_systems_inner` to reuse
`process_configs`.
---
## Changelog
- Added `run_if` to `IntoSystemSetConfigs`
- Deprecated `Schedule::configure_set` and `App::configure_set`
- Removed `IntoSystemSetConfig`
## Migration Guide
- Use `App::configure_sets` instead of `App::configure_set`
- Use `Schedule::configure_sets` instead of `Schedule::configure_set`
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
I've been collecting some mistakes in the documentation and fixed them
---------
Co-authored-by: Emi <emanuel.boehm@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
# Objective
- Move schedule name into `Schedule` to allow the schedule name to be
used for errors and tracing in Schedule methods
- Fixes#9510
## Solution
- Move label onto `Schedule` and adjust api's on `World` and `Schedule`
to not pass explicit label where it makes sense to.
- add name to errors and tracing.
- `Schedule::new` now takes a label so either add the label or use
`Schedule::default` which uses a default label. `default` is mostly used
in doc examples and tests.
---
## Changelog
- move label onto `Schedule` to improve error message and logging for
schedules.
## Migration Guide
`Schedule::new` and `App::add_schedule`
```rust
// old
let schedule = Schedule::new();
app.add_schedule(MyLabel, schedule);
// new
let schedule = Schedule::new(MyLabel);
app.add_schedule(schedule);
```
if you aren't using a label and are using the schedule struct directly
you can use the default constructor.
```rust
// old
let schedule = Schedule::new();
schedule.run(world);
// new
let schedule = Schedule::default();
schedule.run(world);
```
`Schedules:insert`
```rust
// old
let schedule = Schedule::new();
schedules.insert(MyLabel, schedule);
// new
let schedule = Schedule::new(MyLabel);
schedules.insert(schedule);
```
`World::add_schedule`
```rust
// old
let schedule = Schedule::new();
world.add_schedule(MyLabel, schedule);
// new
let schedule = Schedule::new(MyLabel);
world.add_schedule(schedule);
```
# Objective
`sync_simple_transforms` only checks for removed parents and doesn't
filter for `Without<Parent>`, so it overwrites the `GlobalTransform` of
non-orphan entities that were orphaned and then reparented since the
last update.
Introduced by #7264
## Solution
Filter for `Without<Parent>`.
Fixes#9517, #9492
## Changelog
`sync_simple_transforms`:
* Added a `Without<Parent>` filter to the orphaned entities query.
# Objective
The `QueryParIter::for_each_mut` function is required when doing
parallel iteration with mutable queries.
This results in an unfortunate stutter:
`query.par_iter_mut().par_for_each_mut()` ('mut' is repeated).
## Solution
- Make `for_each` compatible with mutable queries, and deprecate
`for_each_mut`. In order to prevent `for_each` from being called
multiple times in parallel, we take ownership of the QueryParIter.
---
## Changelog
- `QueryParIter::for_each` is now compatible with mutable queries.
`for_each_mut` has been deprecated as it is now redundant.
## Migration Guide
The method `QueryParIter::for_each_mut` has been deprecated and is no
longer functional. Use `for_each` instead, which now supports mutable
queries.
```rust
// Before:
query.par_iter_mut().for_each_mut(|x| ...);
// After:
query.par_iter_mut().for_each(|x| ...);
```
The method `QueryParIter::for_each` now takes ownership of the
`QueryParIter`, rather than taking a shared reference.
```rust
// Before:
let par_iter = my_query.par_iter().batching_strategy(my_batching_strategy);
par_iter.for_each(|x| {
// ...Do stuff with x...
par_iter.for_each(|y| {
// ...Do nested stuff with y...
});
});
// After:
my_query.par_iter().batching_strategy(my_batching_strategy).for_each(|x| {
// ...Do stuff with x...
my_query.par_iter().batching_strategy(my_batching_strategy).for_each(|y| {
// ...Do nested stuff with y...
});
});
```
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
`GlobalTransform` after insertion will be updated only on `Transform` or
hierarchy change.
Fixes#9075
## Solution
Update `GlobalTransform` after insertion too.
---
## Changelog
- `GlobalTransform` is now updated not only on `Transform` or hierarchy
change, but also on insertion.
# 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
**This implementation is based on
https://github.com/bevyengine/rfcs/pull/59.**
---
Resolves#4597
Full details and motivation can be found in the RFC, but here's a brief
summary.
`FromReflect` is a very powerful and important trait within the
reflection API. It allows Dynamic types (e.g., `DynamicList`, etc.) to
be formed into Real ones (e.g., `Vec<i32>`, etc.).
This mainly comes into play concerning deserialization, where the
reflection deserializers both return a `Box<dyn Reflect>` that almost
always contain one of these Dynamic representations of a Real type. To
convert this to our Real type, we need to use `FromReflect`.
It also sneaks up in other ways. For example, it's a required bound for
`T` in `Vec<T>` so that `Vec<T>` as a whole can be made `FromReflect`.
It's also required by all fields of an enum as it's used as part of the
`Reflect::apply` implementation.
So in other words, much like `GetTypeRegistration` and `Typed`, it is
very much a core reflection trait.
The problem is that it is not currently treated like a core trait and is
not automatically derived alongside `Reflect`. This makes using it a bit
cumbersome and easy to forget.
## Solution
Automatically derive `FromReflect` when deriving `Reflect`.
Users can then choose to opt-out if needed using the
`#[reflect(from_reflect = false)]` attribute.
```rust
#[derive(Reflect)]
struct Foo;
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Bar;
fn test<T: FromReflect>(value: T) {}
test(Foo); // <-- OK
test(Bar); // <-- Panic! Bar does not implement trait `FromReflect`
```
#### `ReflectFromReflect`
This PR also automatically adds the `ReflectFromReflect` (introduced in
#6245) registration to the derived `GetTypeRegistration` impl— if the
type hasn't opted out of `FromReflect` of course.
<details>
<summary><h4>Improved Deserialization</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
And since we can do all the above, we might as well improve
deserialization. We can now choose to deserialize into a Dynamic type or
automatically convert it using `FromReflect` under the hood.
`[Un]TypedReflectDeserializer::new` will now perform the conversion and
return the `Box`'d Real type.
`[Un]TypedReflectDeserializer::new_dynamic` will work like what we have
now and simply return the `Box`'d Dynamic type.
```rust
// Returns the Real type
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
// Returns the Dynamic type
let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
```
</details>
---
## Changelog
* `FromReflect` is now automatically derived within the `Reflect` derive
macro
* This includes auto-registering `ReflectFromReflect` in the derived
`GetTypeRegistration` impl
* ~~Renamed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic`, respectively~~ **Descoped**
* ~~Changed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to automatically convert the
deserialized output using `FromReflect`~~ **Descoped**
## Migration Guide
* `FromReflect` is now automatically derived within the `Reflect` derive
macro. Items with both derives will need to remove the `FromReflect`
one.
```rust
// OLD
#[derive(Reflect, FromReflect)]
struct Foo;
// NEW
#[derive(Reflect)]
struct Foo;
```
If using a manual implementation of `FromReflect` and the `Reflect`
derive, users will need to opt-out of the automatic implementation.
```rust
// OLD
#[derive(Reflect)]
struct Foo;
impl FromReflect for Foo {/* ... */}
// NEW
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Foo;
impl FromReflect for Foo {/* ... */}
```
<details>
<summary><h4>Removed Migrations</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
* The reflect deserializers now perform a `FromReflect` conversion
internally. The expected output of `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` is no longer a Dynamic (e.g.,
`DynamicList`), but its Real counterpart (e.g., `Vec<i32>`).
```rust
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
// OLD
let output: DynamicStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
// NEW
let output: SomeStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
```
Alternatively, if this behavior isn't desired, use the
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic` methods instead:
```rust
// OLD
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
// NEW
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
```
</details>
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Better consistency with `add_systems`.
- Deprecating `add_plugin` in favor of a more powerful `add_plugins`.
- Allow passing `Plugin` to `add_plugins`.
- Allow passing tuples to `add_plugins`.
## Solution
- `App::add_plugins` now takes an `impl Plugins` parameter.
- `App::add_plugin` is deprecated.
- `Plugins` is a new sealed trait that is only implemented for `Plugin`,
`PluginGroup` and tuples over `Plugins`.
- All examples, benchmarks and tests are changed to use `add_plugins`,
using tuples where appropriate.
---
## Changelog
### Changed
- `App::add_plugins` now accepts all types that implement `Plugins`,
which is implemented for:
- Types that implement `Plugin`.
- Types that implement `PluginGroup`.
- Tuples (up to 16 elements) over types that implement `Plugins`.
- Deprecated `App::add_plugin` in favor of `App::add_plugins`.
## Migration Guide
- Replace `app.add_plugin(plugin)` calls with `app.add_plugins(plugin)`.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
Discovered that PointLight did not implement FromReflect. Adding
FromReflect where Reflect is used. I overreached and applied this rule
everywhere there was a Reflect without a FromReflect, except from where
the compiler wouldn't allow me.
Based from question: https://github.com/bevyengine/bevy/discussions/8774
## Solution
- Adding FromReflect where Reflect was already derived
## Notes
First PR I do in this ecosystem, so not sure if this is the usual
approach, that is, to touch many files at once.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Fixes#8811 .
## Solution
- Rename "write" method to "apply" in Command trait definition.
- Rename other implementations of command trait throughout bevy's code
base.
---
## Changelog
- Changed: `Command::write` has been changed to `Command::apply`
- Changed: `EntityCommand::write` has been changed to
`EntityCommand::apply`
## Migration Guide
- `Command::write` implementations need to be changed to implement
`Command::apply` instead. This is a mere name change, with no further
actions needed.
- `EntityCommand::write` implementations need to be changed to implement
`EntityCommand::apply` instead. This is a mere name change, with no
further actions needed.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>