# Objective
Improve code-gen for `QueryState::validate_world` and
`SystemState::validate_world`.
## Solution
* Move panics into separate, non-inlined functions, to reduce the code
size of the outer methods.
* Mark the panicking functions with `#[cold]` to help the compiler
optimize for the happy path.
* Mark the functions with `#[track_caller]` to make debugging easier.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Fix a performance regression in the "[bevy vs
pixi](https://github.com/SUPERCILEX/bevy-vs-pixi)" benchmark.
This benchmark seems to have a slightly pathological distribution of `z`
values -- Sprites are spawned with a random `z` value with a child
sprite at `f32::EPSILON` relative to the parent.
See discussion here:
https://github.com/bevyengine/bevy/issues/8100#issuecomment-1726978633
## Solution
Use `radsort` for sorting `Transparent2d` `PhaseItem`s.
Use random `z` values in bevymark to stress the phase sort. Add an
`--ordered-z` option to `bevymark` that uses the old behavior.
## Benchmarks
mac m1 max
| benchmark | fps before | fps after | diff |
| - | - | - | - |
| bevymark --waves 120 --per-wave 1000 --random-z | 42.16 | 47.06 | 🟩
+11.6% |
| bevymark --waves 120 --per-wave 1000 | 52.50 | 52.29 | 🟥 -0.4% |
| bevymark --waves 120 --per-wave 1000 --mode mesh2d --random-z | 9.64 |
10.24 | 🟩 +6.2% |
| bevymark --waves 120 --per-wave 1000 --mode mesh2d | 15.83 | 15.59 | 🟥
-1.5% |
| bevy-vs-pixi | 39.71 | 59.88 | 🟩 +50.1% |
## Discussion
It's possible that `TransparentUi` should also change. We could probably
use `slice::sort_unstable_by_key` with the current sort key though, as
its items are always sorted and unique. I'd prefer to follow up later to
look into that.
Here's a survey of sorts used by other `PhaseItem`s
#### slice::sort_by_key
`Transparent2d`, `TransparentUi`
#### radsort
`Opaque3d`, `AlphaMask3d`, `Transparent3d`, `Opaque3dPrepass`,
`AlphaMask3dPrepass`, `Shadow`
I also tried `slice::sort_unstable_by_key` with a compound sort key
including `Entity`, but it didn't seem as promising and I didn't test it
as thoroughly.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
# Objective
Some rendering system did heavy use of `if let`, and could be improved
by using `let else`.
## Solution
- Reduce rightward drift by using let-else over if-let
- Extract value-to-key mappings to their own functions so that the
system is less bloated, easier to understand
- Use a `let` binding instead of untupling in closure argument to reduce
indentation
## Note to reviewers
Enable the "no white space diff" for easier viewing.
In the "Files changed" view, click on the little cog right of the "Jump
to" text, on the row where the "Review changes" button is. then enable
the "Hide whitespace" checkbox and click reload.
# Objective
Rename the `num_font_atlases` method of `FontAtlasSet` to `len`.
All the function does is return the number of entries in its hashmap and
the unnatural naming only makes it harder to discover.
---
## Changelog
* Renamed the `num_font_atlases` method of `FontAtlasSet` to `len`.
## Migration Guide
The `num_font_atlases` method of `FontAtlasSet` has been renamed to
`len`.
# Objective
Occasionally, it is useful to pull `ComponentInfo` or
`ComponentDescriptor` out of the `Components` collection so that they
can be inspected without borrowing the whole `World`.
## Solution
Make `ComponentInfo` and `ComponentDescriptor` `Clone`, so that
reflection-heavy code can store them in a side table.
---
## Changelog
- Implement `Clone` for `ComponentInfo` and `ComponentDescriptor`
# Objective
- I spoke with some users in the ECS channel of bevy discord today and
they suggested that I implement a fallible form of .insert for
components.
- In my opinion, it would be nice to have a fallible .insert like
.try_insert (or to just make insert be fallible!) because it was causing
a lot of panics in my game. In my game, I am spawning terrain chunks and
despawning them in the Update loop. However, this was causing bevy_xpbd
to panic because it was trying to .insert some physics components on my
chunks and a race condition meant that its check to see if the entity
exists would pass but then the next execution step it would not exist
and would do an .insert and then panic. This means that there is no way
to avoid a panic with conditionals.
Luckily, bevy_xpbd does not care about inserting these components if the
entity is being deleted and so if there were a .try_insert, like this PR
provides it could use that instead in order to NOT panic.
( My interim solution for my own game has been to run the entity despawn
events in the Last schedule but really this is just a hack and I should
not be expected to manage the scheduling of despawns like this - it
should just be easy and simple. IF it just so happened that bevy_xpbd
ran .inserts in the Last schedule also, this would be an untenable soln
overall )
## Solution
- Describe the solution used to achieve the objective above.
Add a new command named TryInsert (entitycommands.try_insert) which
functions exactly like .insert except if the entity does not exist it
will not panic. Instead, it will log to info. This way, crates that are
attaching components in ways which they do not mind that the entity no
longer exists can just use try_insert instead of insert.
---
## Changelog
## Additional Thoughts
In my opinion, NOT panicing should really be the default and having an
.insert that does panic should be the odd edgecase but removing the
panic! from .insert seems a bit above my paygrade -- although i would
love to see it. My other thought is it would be good for .insert to
return an Option AND not panic but it seems it uses an event bus right
now so that seems to be impossible w the current architecture.
# Objective
- Fixes#9876
## Solution
- Reverted commit `5012a0fd57748ab6f146776368b4cf988bba1eaa` to restore
the previous default values for `OrthographicProjection`.
---
## Migration Guide
- Migration guide steps from #9537 should be removed for next release.
# Objective
- WSL documentation was out-of-date and potentially misleading. The
release of WSLg makes a lot of stuff easier
## Solution
- Just updating docs for now
## NB
I haven't been able to get a full end-to-end GPU on WSL test going yet,
but plan to update this documentation again once I have more of a grasp
on that
# Objective
Fix a typo introduced by #9497. While drafting the PR, the type was
originally called `VisibleInHierarchy` before I renamed it to
`InheritedVisibility`, but this field got left behind due to a typo.
# Objective
- When adding/removing bindings in large binding lists, git would
generate very difficult-to-read diffs
## Solution
- Move the `@group(X) @binding(Y)` into the same line as the binding
type declaration
# Objective
- `check_visibility` system in `bevy_render` had an
`Option<&NoFrustumCulling>` that could be replaced by `Has`, which is
theoretically faster and semantically more correct.
- It also had some awkward indenting due to very large closure argument
lists.
- Some of the tests could be written more concisely
## Solution
Use `Has`, move the tuple destructuring in a `let` binding, create a
function for the tests.
## Note to reviewers
Enable the "no white space diff" in the diff viewer to have a more
meaningful diff in the `check_visibility` system.
In the "Files changed" view, click on the little cog right of the "Jump
to" text, on the row where the "Review changes" button is. then enable
the "Hide whitespace" checkbox and click reload.
---
## Migration Guide
- The `check_visibility` system's `Option<&NoFrustumCulling>` parameter
has been replaced by `Has<NoFrustumCulling>`, if you were calling it
manually, you should change the type to match it
---------
Co-authored-by: Rob Parrett <robparrett@gmail.com>
# Objective
Currently, in bevy, it's valid to do `Query<&mut Foo, Changed<Foo>>`.
This assumes that `filter_fetch` and `fetch` are mutually exclusive,
because of the mutable reference to the tick that `Mut<Foo>` implies and
the reference that `Changed<Foo>` implies. However nothing guarantees
that.
## Solution
Documenting this assumption as a safety invariant is the least thing.
# Objective
`single_threaded_task_pool` emitted a warning:
```
warning: use of `default` to create a unit struct
--> crates/bevy_tasks/src/single_threaded_task_pool.rs:22:25
|
22 | Self(PhantomData::default())
| ^^^^^^^^^^^ help: remove this call to `default`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs
= note: `#[warn(clippy::default_constructed_unit_structs)]` on by default
```
## Solution
fix the lint
I'm adopting this ~~child~~ PR.
# Objective
- Working with exclusive world access is not always easy: in many cases,
a standard system or three is more ergonomic to write, and more
modularly maintainable.
- For small, one-off tasks (commonly handled with scripting), running an
event-reader system incurs a small but flat overhead cost and muddies
the schedule.
- Certain forms of logic (e.g. turn-based games) want very fine-grained
linear and/or branching control over logic.
- SystemState is not automatically cached, and so performance can suffer
and change detection breaks.
- Fixes https://github.com/bevyengine/bevy/issues/2192.
- Partial workaround for https://github.com/bevyengine/bevy/issues/279.
## Solution
- Adds a SystemRegistry resource to the World, which stores initialized
systems keyed by their SystemSet.
- Allows users to call world.run_system(my_system) and
commands.run_system(my_system), without re-initializing or losing state
(essential for change detection).
- Add a Callback type to enable convenient use of dynamic one shot
systems and reduce the mental overhead of working with Box<dyn
SystemSet>.
- Allow users to run systems based on their SystemSet, enabling more
complex user-made abstractions.
## Future work
- Parameterized one-shot systems would improve reusability and bring
them closer to events and commands. The API could be something like
run_system_with_input(my_system, my_input) and use the In SystemParam.
- We should evaluate the unification of commands and one-shot systems
since they are two different ways to run logic on demand over a World.
### Prior attempts
- https://github.com/bevyengine/bevy/pull/2234
- https://github.com/bevyengine/bevy/pull/2417
- https://github.com/bevyengine/bevy/pull/4090
- https://github.com/bevyengine/bevy/pull/7999
This PR continues the work done in
https://github.com/bevyengine/bevy/pull/7999.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
Co-authored-by: Aevyrie <aevyrie@gmail.com>
Co-authored-by: Alejandro Pascual Pozo <alejandro.pascual.pozo@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Dmytro Banin <banind@cs.washington.edu>
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Make `bevy_ui` "root" nodes more intuitive to use/style by:
- Removing the implicit flexbox styling (such as stretch alignment) that
is applied to them, and replacing it with more intuitive CSS Grid
styling (notably with stretch alignment disabled in both axes).
- Making root nodes layout independently of each other. Instead of there
being a single implicit "viewport" node that all root nodes are children
of, there is now an implicit "viewport" node *per root node*. And layout
of each tree is computed separately.
## Solution
- Remove the global implicit viewport node, and instead create an
implicit viewport node for each user-specified root node.
- Keep track of both the user-specified root nodes and the implicit
viewport nodes in a separate `Vec`.
- Use the window's size as the `available_space` parameter to
`Taffy.compute_layout` rather than setting it on the implicit viewport
node (and set the viewport to `height: 100%; width: 100%` to make this
"just work").
---
## Changelog
- Bevy UI now lays out root nodes independently of each other in
separate layout contexts.
- The implicit viewport node (which contains each user-specified root
node) is now `Display::Grid` with `align_items` and `justify_items` both
set to `Start`.
## Migration Guide
- Bevy UI now lays out root nodes independently of each other in
separate layout contexts. If you were relying on your root nodes being
able to affect each other's layouts, then you may need to wrap them in a
single root node.
- The implicit viewport node (which contains each user-specified root
node) is now `Display::Grid` with `align_items` and `justify_items` both
set to `Start`. You may need to add `height: Val::Percent(100.)` to your
root nodes if you were previously relying on being implicitly set.
# Objective
- When initializing the renderer, Bevy currently create a detached task
- This is needed on wasm but not on native
## Solution
- Don't create a detached task on native but block on the future
# Objective
Make the output of this example repeatable so it can be utilized by
automated screenshot diffing.
## Solution
- Use a seeded RNG for the random colors
- Offset the meshes slightly in z so they don't intersect each other at
the extents of their animations.
# Objective
Fix these
```
-- rotate_cube and move_cube
conflict on: ["bevy_transform::components::transform::Transform", "transform::CubeState"]
-- rotate_cube and scale_down_sphere_proportional_to_cube_travel_distance
conflict on: ["bevy_transform::components::transform::Transform", "transform::CubeState"]
-- move_cube and scale_down_sphere_proportional_to_cube_travel_distance
conflict on: ["bevy_transform::components::transform::Transform", "transform::CubeState"]
```
The three systems in this example depend on the results of the others.
This leads to minor but detectable differences in output between runs by
automated screenshot diffing depending on the order of the schedule.
We don't necessarily need to be able to do this for **every** example,
but I think this is a case where fixing it is easy / maybe the right
thing to do anyway.
## Solution
Chain the three systems
# Objective
Replace instances of
```rust
for x in collection.iter{_mut}() {
```
with
```rust
for x in &{mut} collection {
```
This also changes CI to no longer suppress this lint. Note that since
this lint only shows up when using clippy in pedantic mode, it was
probably unnecessary to suppress this lint in the first place.
# Objective
- When reading API docs and seeing a reference to `ComponentId`, it
isn't immediately clear how to get one from your `Component`. It could
be made to be more clear.
## Solution
- Improve cross-linking of docs about `ComponentId`
# Objective
`no_archetype` benchmark group results were very noisy
## Solution
Use the `SingeThreaded` executor.
On my machine, this makes the `no_archetype` bench group 20 to 30 times
faster. Meaning that most of the runtime was accounted by the
multithreaded scheduler. ie: the benchmark was not testing system
archetype update, but the overhead of multithreaded scheduling.
With this change, the benchmark results are more meaningful.
The add_archetypes function is also simplified.
# Objective
The default division for a `usize` rounds down which means the batch
sizes were too small when the `max_size` isn't exactly divisible by the
batch count.
## Solution
Changing the division to round up fixes this which can dramatically
improve performance when using `par_iter`.
I created a small example to proof this out and measured some results. I
don't know if it's worth committing this permanently so I left it out of
the PR for now.
```rust
use std::{thread, time::Duration};
use bevy::{
prelude::*,
window::{PresentMode, WindowPlugin},
};
fn main() {
App::new()
.add_plugins((DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync,
..default()
}),
..default()
}),))
.add_systems(Startup, spawn)
.add_systems(Update, update_counts)
.run();
}
#[derive(Component, Default, Debug, Clone, Reflect)]
pub struct Count(u32);
fn spawn(mut commands: Commands) {
// Worst case
let tasks = bevy::tasks::available_parallelism() * 5 - 1;
// Best case
// let tasks = bevy::tasks::available_parallelism() * 5 + 1;
for _ in 0..tasks {
commands.spawn(Count(0));
}
}
// changing the bounds of the text will cause a recomputation
fn update_counts(mut count_query: Query<&mut Count>) {
count_query.par_iter_mut().for_each(|mut count| {
count.0 += 1;
thread::sleep(Duration::from_millis(10))
});
}
```
## Results
I ran this four times, with and without the change, with best case
(should favour the old maths) and worst case (should favour the new
maths) task numbers.
### Worst case
Before the change the batches were 9 on each thread, plus the 5
remainder ran on one of the threads in addition. With the change its 10
on each thread apart from one which has 9. The results show a decrease
from ~140ms to ~100ms which matches what you would expect from the maths
(`10 * 10ms` vs `(9 + 4) * 10ms`).
![Screenshot from 2023-09-14
20-24-36](https://github.com/bevyengine/bevy/assets/1353401/82099ee4-83a8-47f4-bb6b-944f1e87a818)
### Best case
Before the change the batches were 10 on each thread, plus the 1
remainder ran on one of the threads in addition. With the change its 11
on each thread apart from one which has 5. The results slightly favour
the new change but are basically identical as the total time is
determined by the worse case which is `11 * 10ms` for both tests.
![Screenshot from 2023-09-14
20-48-51](https://github.com/bevyengine/bevy/assets/1353401/4532211d-ab36-435b-b864-56af3370d90e)
# Objective
according to
[khronos](https://github.com/KhronosGroup/glTF/issues/1697), gltf nodes
with inverted scales should invert the winding order of the mesh data.
this is to allow negative scale to be used for mirrored geometry.
## Solution
in the gltf loader, create a separate material with `cull_mode` set to
`Face::Front` when the node scale is negative.
note/alternatives:
this applies for nodes where the scale is negative at gltf import time.
that seems like enough for the mentioned use case of mirrored geometry.
it doesn't help when scales dynamically go negative at runtime, but you
can always set double sided in that case.
i don't think there's any practical difference between using front-face
culling and setting a clockwise winding order explicitly, but winding
order is supported by wgpu so we could add the field to
StandardMaterial/StandardMaterialKey and set it directly on the pipeline
descriptor if there's a reason to. it wouldn't help with dynamic scale
adjustments anyway, and would still require a separate material.
fixes#4738, probably fixes#7901.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
The reasoning is similar to #8687.
I'm building a dynamic query. Currently, I store the ReflectFromPtr in
my dynamic `Fetch` type.
[See relevant
code](97ba68ae1e/src/fetches.rs (L14-L17))
However, `ReflectFromPtr` is:
- 16 bytes for TypeId
- 8 bytes for the non-mutable function pointer
- 8 bytes for the mutable function pointer
It's a lot, it adds 32 bytes to my base `Fetch` which is only
`ComponendId` (8 bytes) for a total of 40 bytes.
I only need one function per fetch, reducing the total dynamic fetch
size to 16 bytes.
Since I'm querying the components by the ComponendId associated with the
function pointer I'm using, I don't need the TypeId, it's a redundant
check.
In fact, I've difficulties coming up with situations where checking the
TypeId beforehand is relevant. So to me, if ReflectFromPtr makes sense
as a public API, exposing the function pointers also makes sense.
## Solution
- Make the fields public through methods.
---
## Changelog
- Add `from_ptr` and `from_ptr_mut` methods to `ReflectFromPtr` to
access the underlying function pointers
- `ReflectFromPtr::as_reflect_ptr` is now `ReflectFromPtr::as_reflect`
- `ReflectFromPtr::as_reflect_ptr_mut` is now
`ReflectFromPtr::as_reflect_mut`
## Migration guide
- `ReflectFromPtr::as_reflect_ptr` is now `ReflectFromPtr::as_reflect`
- `ReflectFromPtr::as_reflect_ptr_mut` is now
`ReflectFromPtr::as_reflect_mut`
# Objective
If you remove a `ContentSize` component from a Bevy UI entity and then
replace it `ui_layout_system` will remove the measure func from the
internal Taffy layout tree but no new measure func will be generated to
replace it since it's the widget systems that are responsible for
creating their respective measure funcs not `ui_layout_system`. The
widget systems only perform a measure func update on changes to a widget
entity's content. This means that until its content is changed in some
way, no content will be displayed by the node.
### Example
This example spawns a text node which disappears after a few moments
once its `ContentSize` component is replaced.
```rust
use bevy::prelude::*;
use bevy::ui::ContentSize;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, delayed_replacement)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
commands.spawn(
TextBundle::from_section(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
TextStyle::default(),
)
);
}
// Waits a few frames to make sure the font is loaded and the text's glyph layout has been generated.
fn delayed_replacement(mut commands: Commands, mut count: Local<usize>, query: Query<Entity, With<Style>>) {
*count += 1;
if *count == 10 {
for item in query.iter() {
commands
.entity(item)
.remove::<ContentSize>()
.insert(ContentSize::default());
}
}
}
```
## Solution
Perform `ui_layout_system`'s `ContentSize` removal detection and
resolution first, before the measure func updates.
Then in the widget systems, generate a new `Measure` when a
`ContentSize` component is added to a widget entity.
## Changelog
* `measure_text_system`, `update_image_content_size_system` and
`update_atlas_content_size_system` generate a new `Measure` when a
`ContentSize` component is added.
# Objective
- There are errors when building for WebGPU, since Assets V2 PR
```
error[E0432]: unresolved import `file_id::get_file_id`
--> /Users/francoismockers/.cargo/registry/src/index.crates.io-6f17d22bba15001f/notify-debouncer-full-0.2.0/src/cache.rs:6:15
|
6 | use file_id::{get_file_id, FileId};
| ^^^^^^^^^^^ no `get_file_id` in the root
|
note: found an item that was configured out
--> /Users/francoismockers/.cargo/registry/src/index.crates.io-6f17d22bba15001f/file-id-0.1.0/src/lib.rs:41:8
|
41 | pub fn get_file_id(path: impl AsRef<Path>) -> io::Result<FileId> {
| ^^^^^^^^^^^
= note: the item is gated behind the `unix` feature
note: found an item that was configured out
--> /Users/francoismockers/.cargo/registry/src/index.crates.io-6f17d22bba15001f/file-id-0.1.0/src/lib.rs:54:8
|
54 | pub fn get_file_id(path: impl AsRef<Path>) -> io::Result<FileId> {
| ^^^^^^^^^^^
= note: the item is gated behind the `windows` feature
For more information about this error, try `rustc --explain E0432`.
error: could not compile `notify-debouncer-full` (lib) due to previous error
```
## Solution
- Don't enable feature `filesystem_watcher` in WebGPU as it can't work
anyway
# Objective
mikktspace tangent generation requires mesh indices, and currently fails
when they are not present. we can just generate them instead.
## Solution
generate the indices.
# Objective
`Val`'s natural place is in the `geometry` module with `UiRect`, not in
`ui_node` with the components.
## Solution
Move `Val` into `geometry`.
# 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#9787
## Solution
~~"serialize" feature enables "bevy_asset" now~~
"serialize" feature no longer enables the optional "bevy_scene" feature
if it's not enabled from elsewhere (thanks to @mockersf)
# Objective
The rename is confusing. Each time I import `TypeRegistry` I have to
think at least 10 seconds about how to import it. And I've been working
a lot with bevy reflect, which multiplies the papercut.
In my crates, you can find lots of:
```rust
use bevy::reflect::{TypeRegistryInternal as TypeRegistry};
```
When I "go to definition" on `TypeRegistry` I get to `TypeRegistryArc`.
And when I mean `TypeRegistry` in my function signature, 100% of the
time I mean `TypeRegistry`, not the arc wrapper.
Rust has borrowing, and most use-cases of the TypeRegistry accepts
borrow of the registry, with no need to mutate it.
`TypeRegistryInternal` is also confusing. In bevy crates, it doesn't
exist. The bevy crate documentation often refers to `TypeRegistry` and
link to `TypeRegistryInternal`. It only exists in the bevy re-exports.
It makes it hard to understand which names qualifies which types.
## Solution
Remove the rename, keep the type names as they are in `bevy_reflect`
---
## Changelog
- Remove `TypeRegistry` and `TypeRegistryArc` renames from bevy
`bevy_reflect` re-exports.
## Migration Guide
- `TypeRegistry` as re-exported by the wrapper `bevy` crate is now
`TypeRegistryArc`
- `TypeRegistryInternal` as re-exported by the wrapper `bevy` crate is
now `TypeRegistry`
This should have been removed in
8a9f475edb when the rest of the references
to / usages of `clippy::manual-strip` were removed. It was originally
needed in the long ago past when supporting Rust 1.45 was a concern.
# Objective
- Docs on linting should match the actual current practice.
- Docs currently mention `-A clippy::manual-strip` which hasn't been
needed in a long time.
## Solution
- Remove reference to `-A clippy::manual-strip`.
# Objective
When using `set_if_neq`, sometimes you'd like to know if the new value
was different from the old value so that you can perform some additional
branching.
## Solution
Return a bool from this function, which indicates whether or not the
value was overwritten.
---
## Changelog
* `DetectChangesMut::set_if_neq` now returns a boolean indicating
whether or not the value was changed.
## Migration Guide
The trait method `DetectChangesMut::set_if_neq` now returns a boolean
value indicating whether or not the value was changed. If you were
implementing this function manually, you must now return `true` if the
value was overwritten and `false` if the value was not.
# Objective
I noticed this while testing #9733.
It's not causing any problems, but we shouldn't teach users to scale 2d
stuff in z.
## Solution
Only scale in x and y.
# Objective
- Compile all targets without warnings about unused doc comments.
## Solution
- Turn unused doc comments into regular comments. Doc comments aren't
supported on expressions, so they can just be regular comments.
# Objective
Fix#9747
## Solution
Linkers don't like what we're doing with CowArc (I'm guessing it has
something to do with `?Sized`). Weirdly the `Reflect` derive on
`AssetPath` doesn't fail, despite `CowArc` not implementing `Reflect`.
To resolve this, we manually implement "reflect value" for
`AssetPath<'static>`. It sadly cannot use `impl_reflect_value` because
that macro doesn't support static lifetimes.
---------
Co-authored-by: Martin Dickopp <martin@zero-based.org>
# Objective
Add tests for `ui_layout_system` and `UiSurface` to the
`bevy_ui::Layout` module.
## Solution
Spawn a dummy window entity with `Window` and `PrimaryWindow` components
so that `ui_layout_system` can run in a test without a window present.
---
## Changelog
Added tests to the `bevy_ui::layout` module.