# Objective
It seems the behavior of field attributes was accidentally broken at
some point. Take the following code:
```rust
#[derive(Reflect)]
struct Foo {
#[reflect(ignore, default)]
value: usize
}
```
The above code should simply mark `value` as ignored and specify a
default behavior. However, what this actually does is discard both.
That's especially a problem when we don't want the field to be be given
a `Reflect` or `FromReflect` bound (which is why we ignore it in the
first place).
This only happens when the attributes are combined into one. The
following code works properly:
```rust
#[derive(Reflect)]
struct Foo {
#[reflect(ignore)]
#[reflect(default)]
value: usize
}
```
## Solution
Cleaned up the field attribute parsing logic to support combined field
attributes.
---
## Changelog
- Fixed a bug where `Reflect` derive attributes on fields are not able
to be combined into a single attribute
# Objective
- Follow up to #8887
- The parsing code in `bevy_reflect/src/path/mod.rs` could also do with
some cleanup
## Solution
- Create the `parse.rs` module, move all parsing code to this module
- The parsing errors also now keep track of the whole parsed string, and
are much more fine-grained
### Detailed changes
- Move `PathParser` to `parse.rs` submodule
- Rename `token_to_access` to `access_following` (yep, goes from 132
lines to 16)
- Move parsing tests into the `parse.rs` file
# Objective
The doc comment for `text_system` is not quite correct. It implies that
a new `TextLayoutInfo` is generated on changes to `Text` and `Style`.
While changes to those components might indirectly trigger a
regeneration of the text layout, `text_system` itself only queries for
changes to `Node`
Also added details to `measure_text_system`'s doc comments explaining
how it reacts to changes.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
- `bevy_tasks` emits warnings under certain conditions
When I run `cargo clippy -p bevy_tasks` the warning doesn't show up,
while if I run it with `cargo clippy -p bevy_asset` the warning shows
up.
## Solution
- Fix the warnings.
## Longer term solution
We should probably fix CI so that those warnings do not slip through.
But that's not the goal of this PR.
# Objective
This doc comment for the `set` method of `ContentSize`:
```
Set a `Measure` for this function
```
doesn't seem to make sense, `ContentSize` is not a function.
# Solution
Replace it.
# Objective
When an `AudioSink` is removed from an entity, the audio player will
automatically start any `AudioSource` still attached, which normally is
the one used to start playback in the first place.
## Solution
Long story short, the default behavior is restarting the audio, and this
commit documents that.
---
## Changelog
Fixed documentation on `AudioSink` to clarify removal behavior.
# Objective
shader defs associated with a shader via `load_internal_asset!` or
`Shader::from_xxx_with_defs` were being accidentally ignored for
top-level shaders.
## Solution
include the defs for top level shaders.
# Objective
- Fixes#9114
## Solution
Inside `ScheduleGraph::build_schedule()` the variable `node_count =
self.systems.len() + self.system_sets.len()` is used to calculate the
indices for the `reachable` bitset derived from `self.hierarchy.graph`.
However, the number of nodes inside `self.hierarchy.graph` does not
always correspond to `self.systems.len() + self.system_sets.len()` when
`ambiguous_with` is used, because an ambiguous set is added to
`system_sets` (because we need an `NodeId` for the ambiguity graph)
without adding a node to `self.hierarchy`.
In this PR, we rename `node_count` to the more descriptive name
`hg_node_count` and set it to `self.hierarchy.graph.node_count()`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Fixes#9113
## Solution
disable `multi-threaded` default feature
## Migration Guide
The `multi-threaded` feature in `bevy_ecs` and `bevy_tasks` is no longer
enabled by default. However, this remains a default feature for the
umbrella `bevy` crate. If you depend on `bevy_ecs` or `bevy_tasks`
directly, you should consider enabling this to allow systems to run in
parallel.
Fixes#5856. Fixes#8080. Fixes#9040.
# Objective
We need to limit the update rate of games whose windows are not visible
(minimized or completely occluded). Compositors typically ignore the
VSync settings of windows that aren't visible. That, combined with the
lack of rendering work, results in a scenario where an app becomes
completely CPU-bound and starts updating without limit.
There are currently three update modes.
- `Continuous` updates an app as often as possible.
- `Reactive` updates when new window or device events have appeared, a
timer expires, or a redraw is requested.
- `ReactiveLowPower` is the same as `Reactive` except it ignores device
events (e.g. general mouse movement).
The problem is that the default "game" settings are set to `Contiuous`
even when no windows are visible.
### More Context
- https://github.com/libsdl-org/SDL/issues/1871
- https://github.com/glfw/glfw/issues/680
- https://github.com/godotengine/godot/issues/19741
- https://github.com/godotengine/godot/issues/64708
## Solution
Change the default "unfocused" `UpdateMode` for games to
`ReactiveLowPower` just like desktop apps. This way, even when the
window is occluded, the app still updates at a sensible rate or if
something about the window changes. I chose 20Hz arbitrarily.
# Objective
The `lifetimeless` module has been a source of confusion for bevy users
for a while now.
## Solution
Add a couple paragraph explaining that, yes, you can use one of the type
alias safely, without ever leaking any memory.
Redo of #7590 since I messed up my branch.
# Objective
- Revise docs.
- Refactor event loop code a little bit to make it easier to follow.
## Solution
- Do the above.
---
### Migration Guide
- `UpdateMode::Reactive { max_wait: .. }` -> `UpdateMode::Reactive {
wait: .. }`
- `UpdateMode::ReactiveLowPower { max_wait: .. }` ->
`UpdateMode::ReactiveLowPower { wait: .. }`
---------
Co-authored-by: Sélène Amanita <134181069+Selene-Amanita@users.noreply.github.com>
# Objective
Remove the `With<Parent>` query filter from the `parent_node_query`
parameter of the `bevy_ui::render::extract_uinode_borders` function.
This is a bug, the query is only used to retrieve the size of the
current node's parent. We don't care if that parent node has a `Parent`
or not.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
- Fixes#9138
## Solution
- Calling `Camera2dBundle::default()` will now result in a
`Camera2dBundle` with `Vec3::ZERO` transform, `far` value of `1000.` and
`near` value of `-1000.`.
- This will enable the rendering of 2d entities in negative z space by
default.
- I did not modify `new_with_far` as moving the camera to `Vec3::ZERO`
in that function will cause entities in the positive z space to become
hidden without further changes. And the further changes cannot be
applied without it being a breaking change.
# Objective
Glam 0.24 added new glam types (```I64Vec``` and ```U64Vec```). However
these are not reflectable unlike the other glam types
## Solution
Implement reflect for these new types
---
## Changelog
Implements reflect with the impl_reflect_struct macro on ```I64Vec2```,
```I64Vec3```, ```I64Vec4```, ```U64Vec2```, ```U64Vec3```, and
```U64Vec4``` types
# Objective
- Repeat in `Gizmos` that they are drawned in immediate mode, which is
said at the module level but not here, and detail what it means.
- Clarify for every method of `Gizmos` that they should be called for
every frame.
- Clarify which methods belong to 3D or 2D space (kinda obvious for 2D
but still)
The first time I used gizmos I didn't understand how they work and was
confused as to why nothing showed up.
---------
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- In bevy_polyline, we discovered an issue that happens when line width
is smaller than 1.0 and using perspective. It would sometimes end up
negative or NaN. I'm not entirely sure _why_ it happens.
## Solution
- Make sure the width doesn't go below 0 before multiplying it with the
alpha
# Notes
Here's a link to the bevy_polyline issue
https://github.com/ForesightMiningSoftwareCorporation/bevy_polyline/issues/46
I'm not sure if the solution is correct but it solved the issue in my
testing.
Co-authored-by: François <mockersf@gmail.com>
# Objective
This PR continues https://github.com/bevyengine/bevy/pull/8885
It aims to improve the `Mesh` documentation in the following ways:
- Put everything at the "top level" instead of the "impl".
- Explain better what is a Mesh, how it can be created, and that it can
be edited.
- Explain it can be used with a `Material`, and mention
`StandardMaterial`, `PbrBundle`, `ColorMaterial`, and
`ColorMesh2dBundle` since those cover most cases
- Mention the glTF/Bevy vocabulary discrepancy for "Mesh"
- Add an image for the example
- Various nitpicky modifications
## Note
- The image I added is 90.3ko which I think is small enough?
- Since rustdoc doesn't allow cross-reference not in dependencies of a
subcrate [yet](https://github.com/rust-lang/rust/issues/74481), I have a
lot of backtick references that are not links :(
- Since rustdoc doesn't allow linking to code in the crate (?) I put
link to github directly.
- Since rustdoc doesn't allow embed images in doc
[yet](https://github.com/rust-lang/rust/issues/32104), maybe
[soon](https://github.com/rust-lang/rfcs/pull/3397), I had to put only a
link to the image. I don't think it's worth adding
[embed_doc_image](https://docs.rs/embed-doc-image/latest/embed_doc_image/)
as a dependency for this.
# Objective
- Fix shader_material_glsl example
## Solution
- Expose the `PER_OBJECT_BUFFER_BATCH_SIZE` shader def through the
default `MeshPipeline` specialization.
- Make use of it in the `custom_material.vert` shader to access the mesh
binding.
---
## Changelog
- Added: Exposed the `PER_OBJECT_BUFFER_BATCH_SIZE` shader def through
the default `MeshPipeline` specialization to use in custom shaders not
using bevy_pbr::mesh_bindings that still want to use the mesh binding in
some way.
# Objective
- The `path` module was getting fairly large.
- The code in `AccessRef::read_element` and mut equivalent was very
complex and difficult to understand.
- The `ReflectPathError` had a lot of variants, and was difficult to
read.
## Solution
- Split the file in two, `access` now has its own module
- Rewrite the `read_element` methods, they were ~200 lines long, they
are now ~70 lines long — I didn't change any of the logic. It's really
just the same code, but error handling is separated.
- Split the `ReflectPathError` error
- Merge `AccessRef` and `Access`
- A few other changes that aim to reduce code complexity
### Fully detailed change list
- `Display` impl of `ParsedPath` now includes prefix dots — this allows
simplifying its implementation, and IMO `.path.to.field` is a better way
to express a "path" than `path.to.field` which could suggest we are
reading the `to` field of a variable named `path`
- Add a test to check that dot prefixes and other are correctly parsed —
Until now, no test contained a prefixing dot
- Merge `Access` and `AccessRef`, using a `Cow<'a, str>`. Generated code
seems to agree with this decision (`ParsedPath::parse` sheds 5% of
instructions)
- Remove `Access::as_ref` since there is no such thing as an `AccessRef`
anymore.
- Rename `AccessRef::to_owned` into `AccessRef::into_owned()` since it
takes ownership of `self` now.
- Add a `parse_static` that doesn't allocate new strings for named
fields!
- Add a section about path reflection in the `bevy_reflect` crate root
doc — I saw a few people that weren't aware of path reflection, so I
thought it was pertinent to add it to the root doc
- a lot of nits
- rename `index` to `offset` when it refers to offset in the path string
— There is no more confusion with the other kind of indices in this
context, also it's a common naming convention for parsing.
- Make a dedicated enum for parsing errors
- rename the `read_element` methods to `element` — shorter, but also
`read_element_mut` was a fairly poor name
- The error values now not only contain the expected type but also the
actual type.
- Remove lifetimes that could be inferred from the `GetPath` trait
methods.
---
## Change log
- Added the `ParsedPath::parse_static` method, avoids allocating when
parsing `&'static str`.
## Migration Guide
If you were matching on the `Err(ReflectPathError)` value returned by
`GetPath` and `ParsedPath` methods, now only the parse-related errors
and the offset are publicly accessible. You can always use the
`fmt::Display` to get a clear error message, but if you need
programmatic access to the error types, please open an issue.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
- attempt to clarify with better docstrings the default behaviour of
WindowPlugin and the component type it accepts.
# Objective
- I'm new to Rust and Bevy, I got a bit confused about how to customise
some window parameters (title, height, width etc) and while the docs do
show the struct code for that field `Option<Window>` I was a bit of a
doofus and skipped that to read the docstring entry for `primary_window`
and then the `Window` component directly which aren't linked together.
This is a minor improvement which I think will help in-case others, like
me, have a doofus moment.
---------
Co-authored-by: Sélène Amanita <134181069+Selene-Amanita@users.noreply.github.com>
# Objective
This PR updates the name of the enum variant used in the docs for
`OrthographicProjection`.
## Solution
- Change the outdated 'WindowScale` to `WindowSize`.
# Objective
- Reduce the number of rebindings to enable batching of draw commands
## Solution
- Use the new `GpuArrayBuffer` for `MeshUniform` data to store all
`MeshUniform` data in arrays within fewer bindings
- Sort opaque/alpha mask prepass, opaque/alpha mask main, and shadow
phases also by the batch per-object data binding dynamic offset to
improve performance on WebGL2.
---
## Changelog
- Changed: Per-object `MeshUniform` data is now managed by
`GpuArrayBuffer` as arrays in buffers that need to be indexed into.
## Migration Guide
Accessing the `model` member of an individual mesh object's shader
`Mesh` struct the old way where each `MeshUniform` was stored at its own
dynamic offset:
```rust
struct Vertex {
@location(0) position: vec3<f32>,
};
fn vertex(vertex: Vertex) -> VertexOutput {
var out: VertexOutput;
out.clip_position = mesh_position_local_to_clip(
mesh.model,
vec4<f32>(vertex.position, 1.0)
);
return out;
}
```
The new way where one needs to index into the array of `Mesh`es for the
batch:
```rust
struct Vertex {
@builtin(instance_index) instance_index: u32,
@location(0) position: vec3<f32>,
};
fn vertex(vertex: Vertex) -> VertexOutput {
var out: VertexOutput;
out.clip_position = mesh_position_local_to_clip(
mesh[vertex.instance_index].model,
vec4<f32>(vertex.position, 1.0)
);
return out;
}
```
Note that using the instance_index is the default way to pass the
per-object index into the shader, but if you wish to do custom rendering
approaches you can pass it in however you like.
---------
Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
Co-authored-by: Elabajaba <Elabajaba@users.noreply.github.com>
# Objective
My attempt at implementing #7515
## Solution
Added struct `Pitch` and implemented on it `Source` trait.
## Changelog
### Added
- File pitch.rs to bevy_audio crate
- Struct `Pitch` and type aliases for `AudioSourceBundle<Pitch>` and
`SpatialAudioSourceBundle<Pitch>`
- New example showing how to use `PitchBundle`
### Changed
- `AudioPlugin` now adds system for `Pitch` audio
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
The previous formatting didn't render as you'd expect, with 'For CSS
Grid containers' getting adopted by the prior bullet point. Rather than
fixing that directly I opted for a slight reformatting for consistency
with other fields, notably left/right/top/bottom.
# Objective
Fixes#9298 - Default window title leaks "bevy" context
## Solution
I just replaced the literal string "Bevy App" with "App" in Window's
Default trait implementation.
# Objective
Cloning a `WorldQuery` type's "fetch" struct was made unsafe in #5593,
by adding the `unsafe fn clone_fetch` to `WorldQuery`. However, as that
method's documentation explains, it is not the right place to put the
safety invariant:
> While calling this method on its own cannot cause UB it is marked
`unsafe` as the caller must ensure that the returned value is not used
in any way that would cause two `QueryItem<Self>` for the same
`archetype_index` or `table_row` to be alive at the same time.
You can clone a fetch struct all you want and it will never cause
undefined behavior -- in order for something to go wrong, you need to
improperly call `WorldQuery::fetch` with it (which is marked unsafe).
Additionally, making it unsafe to clone a fetch struct does not even
prevent undefined behavior, since there are other ways to incorrectly
use a fetch struct. For example, you could just call fetch more than
once for the same entity, which is not currently forbidden by any
documented invariants.
## Solution
Document a safety invariant on `WorldQuery::fetch` that requires the
caller to not create aliased `WorldQueryItem`s for mutable types. Remove
the `clone_fetch` function, and add the bound `Fetch: Clone` instead.
---
## Changelog
- Removed the associated function `WorldQuery::clone_fetch`, and added a
`Clone` bound to `WorldQuery::Fetch`.
## Migration Guide
### `fetch` invariants
The function `WorldQuery::fetch` has had the following safety invariant
added:
> If this type does not implement `ReadOnlyWorldQuery`, then the caller
must ensure that it is impossible for more than one `Self::Item` to
exist for the same entity at any given time.
This invariant was always required for soundness, but was previously
undocumented. If you called this function manually anywhere, you should
check to make sure that this invariant is not violated.
### Removed `clone_fetch`
The function `WorldQuery::clone_fetch` has been removed. The associated
type `WorldQuery::Fetch` now has the bound `Clone`.
Before:
```rust
struct MyFetch<'w> { ... }
unsafe impl WorldQuery for MyQuery {
...
type Fetch<'w> = MyFetch<'w>
unsafe fn clone_fetch<'w>(fetch: &Self::Fetch<'w>) -> Self::Fetch<'w> {
MyFetch {
field1: fetch.field1,
field2: fetch.field2.clone(),
...
}
}
}
```
After:
```rust
#[derive(Clone)]
struct MyFetch<'w> { ... }
unsafe impl WorldQuery for MyQuery {
...
type Fetch<'w> = MyFetch<'w>;
}
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Fixes https://github.com/bevyengine/bevy/issues/9234
re-breaks: The issues that were linked in #9169
## Solution
Revert the PR that broke tonemapping/postprocessing/etc.
Any passes that are post msaa resolve need to use the main textures, not
the msaa texture.
## Changelog
Idk what to put here since it's a revert.
# Objective
Fixes#9097
## Solution
Reorder the `ExtractSchedule` so that the `extract_text_uinodes` and
`extract_uinode_borders` systems are run after `extract_atlas_uinodes`.
## Changelog
`bevy_ui::render`:
* Added the `ExtractAtlasNode` variant to `RenderUiSystem`.
* Changed `ExtractSchedule` so that `extract_uinode_borders` and
`extract_text_uinodes` run after `extract_atlas_uinodes`.
This is not used directly within the rendering code.
# Objective
- Remove extraneous dependency on `wgpu-hal` as it is not used.
## Solution
- The dependency has been removed and should have no externally visible
impact.
# 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...
});
});
```
# Objective
Fixes#9121
Context:
- `ImageTextureLoader` depends on `RenderDevice` to work out which
compressed image formats it can support
- `RenderDevice` is initialised by `RenderPlugin`
- https://github.com/bevyengine/bevy/pull/8336 made `RenderPlugin`
initialisation async
- This caused `RenderDevice` to be missing at the time of
`ImageTextureLoader` initialisation, which in turn meant UASTC encoded
ktx2 textures were being converted to unsupported formats, and thus
caused panics
## Solution
- Delay `ImageTextureLoader` initialisation
---
## Changelog
- Moved `ImageTextureLoader` initialisation from `ImagePlugin::build()`
to `ImagePlugin::finish()`
- Default to `CompressedImageFormats::NONE` if `RenderDevice` resource
is missing
---------
Co-authored-by: 66OJ66 <hi0obxud@anonaddy.me>
### **Adopted #6430**
# Objective
`MutUntyped` is the untyped variant of `Mut<T>` that stores a `PtrMut`
instead of a `&mut T`. Working with a `MutUntyped` is a bit annoying,
because as soon you want to use the ptr e.g. as a `&mut dyn Reflect` you
cannot use a type like `Mut<dyn Reflect>` but instead need to carry
around a `&mut dyn Reflect` and a `impl FnMut()` to mark the value as
changed.
## Solution
* Provide a method `map_unchanged` to turn a `MutUntyped` into a
`Mut<T>` by mapping the `PtrMut<'a>` to a `&'a mut T`
This can be used like this:
```rust
// SAFETY: ptr is of type `u8`
let val: Mut<u8> = mut_untyped.map_unchanged(|ptr| unsafe { ptr.deref_mut::<u8>() });
// SAFETY: from the context it is known that `ReflectFromPtr` was made for the type of the `MutUntyped`
let val: Mut<dyn Reflect> = mut_untyped.map_unchanged(|ptr| unsafe { reflect_from_ptr.as_reflect_ptr_mut(ptr) });
```
Note that nothing prevents you from doing
```rust
mut_untyped.map_unchanged(|ptr| &mut ());
```
or using any other mutable reference you can get, but IMO that is fine
since that will only result in a `Mut` that will dereference to that
value and mark the original value as changed. The lifetimes here prevent
anything bad from happening.
## Alternatives
1. Make `Ticks` public and provide a method to get construct a `Mut`
from `Ticks` and `&mut T`. More powerful and more easy to misuse.
2. Do nothing. People can still do everything they want, but they need
to pass (`&mut dyn Reflect, impl FnMut() + '_)` around instead of
`Mut<dyn Reflect>`
## Changelog
- add `MutUntyped::map_unchanged` to turn a `MutUntyped` into its typed
counterpart
---------
Co-authored-by: Jakob Hellermann <jakob.hellermann@protonmail.com>
Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
# Objective
Fix#8936.
## Solution
Stop using `unwrap` in the core pipelined rendering logic flow.
Separately also scoped the `sub app` span to just running the render app
instead of including the blocking send.
Current unknowns: should we use `std::panic::catch_unwind` around
running the render app? Other engine threads use it defensively, but
we're letting it bubble up here, and a user-created panic could cause a
deadlock if it kills the thread.
---
## Changelog
Fixed: Pipelined rendering should no longer have spurious panics upon
app exit.
# Objective
Implements #9082 but with an option to toggle minimize and close buttons
too.
## Solution
- Added an `enabled_buttons` member to the `Window` struct through which
users can enable or disable specific window control buttons.
---
## Changelog
- Added an `enabled_buttons` member to the `Window` struct through which
users can enable or disable specific window control buttons.
- Added a new system to the `window_settings` example which demonstrates
the toggling functionality.
---
## Migration guide
- Added an `enabled_buttons` member to the `Window` struct through which
users can enable or disable specific window control buttons.
# Objective
Currently the panic message if a duplicate plugin is added isn't really
helpful or at least can be made more useful if it includes the location
where the plugin was added a second time.
## Solution
Add `track_caller` to `add_plugins` and it's called dependencies.
# Objective
This attempts to make the new IRect and URect structs in bevy_math more
similar to the existing Rect struct.
## Solution
Add reflect implementations for IRect and URect, since one already
exists for Rect.
# Objective
- #8960 isn't optimal for very distinct AABB colors, it can be improved
## Solution
We want a function that maps sequential values (entities concurrently
living in a scene _usually_ have ids that are sequential) into very
different colors (the hue component of the color, to be specific)
What we are looking for is a [so-called "low discrepancy"
sequence](https://en.wikipedia.org/wiki/Low-discrepancy_sequence). ie: a
function `f` such as for integers in a given range (eg: 101, 102, 103…),
`f(i)` returns a rational number in the [0..1] range, such as `|f(i) -
f(i±1)| ≈ 0.5` (maximum difference of images for neighboring preimages)
AHash is a good random hasher, but it has relatively high discrepancy,
so we need something else.
Known good low discrepancy sequences are:
#### The [Van Der Corput
sequence](https://en.wikipedia.org/wiki/Van_der_Corput_sequence)
<details><summary>Rust implementation</summary>
```rust
fn van_der_corput(bits: u64) -> f32 {
let leading_zeros = if bits == 0 { 0 } else { bits.leading_zeros() };
let nominator = bits.reverse_bits() >> leading_zeros;
let denominator = bits.next_power_of_two();
nominator as f32 / denominator as f32
}
```
</details>
#### The [Gold Kronecker
sequence](https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/)
<details><summary>Rust implementation</summary>
Note that the implementation suggested in the linked post assumes
floats, we have integers
```rust
fn gold_kronecker(bits: u64) -> f32 {
const U64_MAX_F: f32 = u64::MAX as f32;
// (u64::MAX / Φ) rounded down
const FRAC_U64MAX_GOLDEN_RATIO: u64 = 11400714819323198485;
bits.wrapping_mul(FRAC_U64MAX_GOLDEN_RATIO) as f32 / U64_MAX_F
}
```
</details>
### Comparison of the sequences
So they are both pretty good. Both only have a single (!) division and
two `u32 as f32` conversions.
- Kronecker is resilient to regular sequence (eg: 100, 102, 104, 106)
while this kills Van Der Corput (consider that potentially one entity
out of two spawned might be a mesh)
I made a small app to compare the two sequences, available at:
https://gist.github.com/nicopap/5dd9bd6700c6a9a9cf90c9199941883e
At the top, we have Van Der Corput, at the bottom we have the Gold
Kronecker. In the video, we spawn a vertical line at the position on
screen where the x coordinate is the image of the sequence. The
preimages are 1,2,3,4,… The ideal algorithm would always have the
largest possible gap between each line (imagine the screen x coordinate
as the color hue):
https://github.com/bevyengine/bevy/assets/26321040/349aa8f8-f669-43ba-9842-f9a46945e25c
Here, we repeat the experiment, but with with `entity.to_bits()` instead
of a sequence:
https://github.com/bevyengine/bevy/assets/26321040/516cea27-7135-4daa-a4e7-edfd1781d119
Notice how Van Der Corput tend to bunch the lines on a single side of
the screen. This is because we always skip odd-numbered entities.
Gold Kronecker seems always worse than Van Der Corput, but it is
resilient to finicky stuff like entity indices being multiples of a
number rather than purely sequential, so I prefer it over Van Der
Corput, since we can't really predict how distributed the entity indices
will be.
### Chosen implementation
You'll notice this PR's implementation is not the Golden ratio-based
Kronecker sequence as described in
[tueoqs](https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/).
Why?
tueoqs R function multiplies a rational/float and takes the fractional
part of the result `(x/Φ) % 1`. We start with an integer `u32`. So
instead of converting into float and dividing by Φ (mod 1) we directly
divide by Φ as integer (mod 2³²) both operations are equivalent, the
integer division (which is actually a multiplication by `u32::MAX / Φ`)
is probably faster.
## Acknowledgements
- `inspi` on discord linked me to
https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
and the wikipedia article.
- [this blog
post](https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/)
for the idea of multiplying the `u32` rather than the `f32`.
- `nakedible` for suggesting the `index()` over `to_bits()` which
considerably reduces generated code (goes from 50 to 11 instructions)
# Objective
- Add a type for uploading a Rust `Vec<T>` to a GPU `array<T>`.
- Makes progress towards https://github.com/bevyengine/bevy/issues/89.
## Solution
- Port @superdump's `BatchedUniformBuffer` to bevy main, as a fallback
for WebGL2, which doesn't support storage buffers.
- Rather than getting an `array<T>` in a shader, you get an `array<T,
N>`, and have to rebind every N elements via dynamic offsets.
- Add `GpuArrayBuffer` to abstract over
`StorageBuffer<Vec<T>>`/`BatchedUniformBuffer`.
## Future Work
Add a shader macro kinda thing to abstract over the following
automatically:
https://github.com/bevyengine/bevy/pull/8204#pullrequestreview-1396911727
---
## Changelog
* Added `GpuArrayBuffer`, `GpuComponentArrayBufferPlugin`,
`GpuArrayBufferable`, and `GpuArrayBufferIndex` types.
* Added `DynamicUniformBuffer::new_with_alignment()`.
---------
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com>
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
Co-authored-by: Vincent <9408210+konsolas@users.noreply.github.com>
Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
# Objective
Fixes#9200
Switches ()'s to []'s when talking about the optional `_mut` suffix in
the ECS Query Struct page to have more idiomatic docs.
## Solution
Replace `()` with `[]` in appropriate doc pages.
When building Bevy using Bazel, you don't need a 'Cargo.toml'... except
Bevy requires it currently. Hopefully this can help illuminate the
requirement.
# Objective
I recently started exploring Bazel and Buck2. Currently Bazel has some
great advantages over Cargo for me and I was pretty happy to find that
things generally work quite well!
Once I added a target to my test project that depended on bevy but
didn't use Cargo, I didn't create a Cargo.toml file for it and things
appeared to work, but as soon as I went to derive from Component the
build failed with the cryptic error:
```
ERROR: /Users/photex/workspaces/personal/mb-rogue/scratch/BUILD:24:12: Compiling Rust bin hello_bevy (0 files) failed: (Exit 1): process_wrapper failed: error executing command (from target //scratch:hello_bevy) bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/rules_rust/util/process_wrapper/process_wrapper --arg-file ... (remaining 312 arguments skipped)
error: proc-macro derive panicked
--> scratch/hello_bevy.rs:5:10
|
5 | #[derive(Component)]
| ^^^^^^^^^
|
= help: message: called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }
error: proc-macro derive panicked
--> scratch/hello_bevy.rs:8:10
|
8 | #[derive(Component)]
| ^^^^^^^^^
|
= help: message: called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }
```
## Solution
After poking around I realized that the proc macros in Bevy all use
bevy_macro_utils::BevyManifest, which was attempting to load a Cargo
manifest that doesn't exist.
This PR doesn't address the Cargo requirement (I'd love to see if there
was a way to support more than Cargo transparently), but it *does*
replace some calls to unwrap with expect and hopefully the error
messages will be more helpful for other folks like me hoping to pat down
a new trail:
```
ERROR: /Users/photex/workspaces/personal/mb-rogue/scratch/BUILD:23:12: Compiling Rust bin hello_bevy (0 files) failed: (Exit 1): process_wrapper failed: error executing command (from target //scratch:hello_bevy) bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/rules_rust/util/process_wrapper/process_wrapper --arg-file ... (remaining 312 arguments skipped)
error: proc-macro derive panicked
--> scratch/hello_bevy.rs:5:10
|
5 | #[derive(Component)]
| ^^^^^^^^^
|
= help: message: Unable to read cargo manifest: /private/var/tmp/_bazel_photex/135f23dc56826c24d6c3c9f6b688b2fe/execroot/__main__/scratch/Cargo.toml: Os { code: 2, kind: NotFound, message: "No such file or directory" }
error: proc-macro derive panicked
--> scratch/hello_bevy.rs:8:10
|
8 | #[derive(Component)]
| ^^^^^^^^^
|
= help: message: Unable to read cargo manifest: /private/var/tmp/_bazel_photex/135f23dc56826c24d6c3c9f6b688b2fe/execroot/__main__/scratch/Cargo.toml: Os { code: 2, kind: NotFound, message: "No such file or directory" }
```
Co-authored-by: Chip Collier <chip.collier@avid.com>
# Objective
Fixes#8894Fixes#7944
## Solution
The UI pipeline's `MultisampleState::count` is set to 1 whereas the
`MultisampleState::count` for the camera's ViewTarget is taken from the
`Msaa` resource, and corruption occurs when these two values are
different.
This PR solves the problem by setting `MultisampleState::count` for the
UI pipeline to the value from the Msaa resource too.
I don't know much about Bevy's rendering internals or graphics hardware,
so maybe there is a better solution than this. UI MSAA was probably
disabled for a good reason (performance?).
## Changelog
* Enabled multisampling for the UI pipeline.
# Objective
AssetPath shader imports check if the shader is added using the path
without quotes. this causes them to be re-added even if already present,
which can cause previous dependents to get unloaded leading to a
"missing import" error.
## Solution
fix the module name of AssetPath shaders used for checking if it's
already added to correctly use the quoted name.
# Objective
In
[`AssetLoader::load()`](https://docs.rs/bevy/0.11.0/bevy/asset/trait.AssetLoader.html#tymethod.load),
I have an
[`AssetPath`](https://docs.rs/bevy/0.11.0/bevy/asset/struct.AssetPath.html)
to a dependency asset.
I get a handle to this dependency asset using
[`LoadContext::get_handle()`](https://docs.rs/bevy/0.11.0/bevy/asset/struct.LoadContext.html#method.get_handle)
passing the `AssetPath`. But I also need to pass this `AssetPath` to
[`LoadedAsset::with_dependency()`](https://docs.rs/bevy/0.11.0/bevy/asset/struct.LoadedAsset.html#method.with_dependency)
later.
The current solution for this problem is either use `clone()`, but
`AssetPath` may contains owned data.
```rust
let dependency_path: AssetPath = _;
let dependency = load_context.get_handle(dependency_path.clone());
// ...
load_context.set_default_asset(LoadedAsset::new(my_asset).with_dependency(dependency_path));
```
Or to use `AssetPathId::from(&path)` which is a bit verbose.
```rust
let dependency_path: AssetPath = _;
let dependency = load_context.get_handle(AssetPathId::from(&dependency_path));
// ...
load_context.set_default_asset(LoadedAsset::new(my_asset).with_dependency(dependency_path));
```
Ideal solution (introduced by this PR) is to pass a reference to
`get_handle()`.
```rust
let dependency_path: AssetPath = _;
let dependency = load_context.get_handle(&dependency_path);
// ...
load_context.set_default_asset(LoadedAsset::new(my_asset).with_dependency(dependency_path));
```
## Solution
Implement `From<&AssetPath>` for `HandleId`
---
## Changelog
- Added: `HandleId` can be build from a reference to `AssetPath`.
# Objective
Continue #7867 now that we have URect #7984
- Return `URect` instead of `(UVec2, UVec2)` in
`Camera::physical_viewport_rect`
- Add `URect` and `IRect` to prelude
## Changelog
- Changed `Camera::physical_viewport_rect` return type from `(UVec2,
UVec2)` to `URect`
- `URect` and `IRect` were added to prelude
## Migration Guide
Before:
```rust
fn view_physical_camera_rect(camera_query: Query<&Camera>) {
let camera = camera_query.single();
let Some((min, max)) = camera.physical_viewport_rect() else { return };
dbg!(min, max);
}
```
After:
```rust
fn view_physical_camera_rect(camera_query: Query<&Camera>) {
let camera = camera_query.single();
let Some(URect { min, max }) = camera.physical_viewport_rect() else { return };
dbg!(min, max);
}
```
# Objective
Gizmos are intended to draw over everything but for some reason I set
the sort key to `0` during #8427 :v
I didn't catch this mistake because it still draws over sprites with a Z
translation of `0`.
## Solution
Set the sort key to `f32::INFINITY`.
# Objective
Some of the conversion methods on the new rect types introduced in #7984
have misleading names.
## Solution
Rename all methods returning an `IRect` to `as_irect` and all methods
returning a `URect` to `as_urect`.
## Migration Guide
Replace uses of the old method names with the new method names.
# Objective
In my application, I'm manually wrapping the built-in Bevy loaders with
a wrapper loader that stores some metadata before calling into the inner
Bevy loader. This worked for the glTF loader in Bevy 0.10, but in Bevy
0.11 it became impossible to do this because the glTF loader became
unconstructible outside Bevy due to the new private fields within it.
It's now in fact impossible to get a reference to a GltfLoader at all
from outside Bevy, because the only way to construct a GltfLoader is to
add the GltfPlugin to an App, and the GltfPlugin only hands out
references to its GltfLoader to the asset server, which provides no
public access to the loaders it manages.
## Solution
This commit fixes the problem by adding a public `new` method to allow
manual construction of a glTF loader.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
In both Text2d and Bevy UI text because of incorrect text size and
alignment calculations if a block of text has empty leading lines then
those lines are ignored. Also, depending on the font size when leading
empty lines are ignored the same number of lines of text can go missing
from the bottom of the text block.
## Example (from murtaugh on discord)
```rust
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
let text = "\nfirst line\nsecond line\nthird line\n";
commands.spawn(TextBundle {
text: Text::from_section(
text.to_string(),
TextStyle {
font_size: 60.0,
color: Color::YELLOW,
..Default::default()
},
),
style: Style {
position_type: PositionType::Absolute,
..Default::default()
},
background_color: BackgroundColor(Color::RED),
..Default::default()
});
}
```
![](https://cdn.discordapp.com/attachments/1128294384954257499/1128295142072254525/image.png)
## Solution
`TextPipeline::queue_text`,
`TextMeasureInfo::compute_size_from_section_texts` and
`GlyphBrush::process_glyphs` each have a nearly duplicate section of
code that calculates the minimum bounds around a list of text sections.
The first two functions don't apply any rounding, but `process_glyphs`
also floors all the values. It seems like this difference can cause
conflicts where the text gets incorrectly shaped.
Also when Bevy computes the text bounds it chooses the smallest possible
rect that fits all the glyphs, ignoring white space. The glyphs are then
realigned vertically so the first glyph is on the top line. Any empty
leading lines are missed.
This PR adds a function `compute_text_bounds` that replaces the
duplicate code, so the text bounds are rounded the same way by each
function. Also, since Bevy doesn't use `ab_glyph` to control vertical
alignment, the minimum y bound is just always set to 0 which ensures no
leading empty lines will be missed.
There is another problem in that trailing empty lines are also ignored,
but that's more difficult to deal with and much less important than the
other issues, so I'll leave it for another PR.
<img width="462" alt="fixed_text_align_bounds"
src="https://github.com/bevyengine/bevy/assets/27962798/85e32e2c-d68f-4677-8e87-38e27ade4487">
---
## Changelog
Added a new function `compute_text_bounds` to the `glyph_brush` module
that replaces the text size and bounds calculations in
`TextPipeline::queue_text`,
`TextMeasureInfo::compute_size_from_section_texts` and
`GlyphBrush::process_glyphs`. The text bounds are calculated identically
in each function and the minimum y bound is not derived from the glyphs
but is always set to 0.
# Objective
`ExtractedUiNodes` is cleared by the `extract_uinodes` function during
the extraction schedule. Because the Bevy UI renderer uses a painters
algorithm, this makes it impossible for users to create a custom
extraction function that adds items for a node to be drawn behind the
rectangle added by `extract_uniodes`.
## Solution
Drain `ExtractedUiNodes` in `prepare_ui_nodes` instead, after the
extraction schedule has finished.
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
fixes#8911, #7712
## Solution
Rounding was added to Taffy which fixed issue #7712.
The implementation uses the f32 `round` method which rounds ties
(fractional part is a half) away from zero. Issue #8911 occurs when a
node's min and max bounds on either axis are "ties" and zero is between
them. Then the bounds are rounded away from each other, and the node
grows by a pixel. This alone shouldn't cause the node to expand
continuously, but I think there is some interaction with the way Taffy
recomputes a layout from its cached data that I didn't identify.
This PR fixes#8911 by first disabling Taffy's internal rounding and
using an alternative rounding function that rounds ties up.
Then, instead of rounding the values of the internal layout tree as
Taffy's built-in rounding does, we leave those values unmodified and
only the values stored in the components are rounded. This requires
walking the tree for the UI node geometry update rather than iterating
through a query.
Because the component values are regenerated each update, that should
mean that UI updates are idempotent (ish) now and make the growing node
behaviour seen in issue #8911 impossible.
I expected a performance regression, but it's an improvement on main:
```
cargo run --profile stress-test --features trace_tracy --example many_buttons
```
<img width="461" alt="ui-rounding-fix-compare"
src="https://github.com/bevyengine/bevy/assets/27962798/914bfd50-e18a-4642-b262-fafa69005432">
I guess it makes sense to do the rounding together with the node size
and position updates.
---
## Changelog
`bevy_ui::layout`:
* Taffy's built-in rounding is disabled and rounding is now performed by
`ui_layout_system`.
* Instead of rounding the values of the internal layout tree as Taffy's
built-in rounding does, we leave those values unmodified and only the
values stored in the components are rounded. This requires walking the
tree for the UI node geometry update rather than iterating through a
query. Because the component values are regenerated each update, that
should mean that UI updates are idempotent now and make the growing node
behaviour seen in issue #8911 impossible.
* Added two helper functions `round_ties_up` and
`round_layout_coordinates`.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This pull request is mutually exclusive with #9066.
# Objective
Complete the initialization of the plugin in `ScheduleRunnerPlugin`.
## Solution
Wait for asynchronous tasks to complete, then `App::finish` and
`App::cleanup` in the runner function.
# Objective
Fixes#6689.
## Solution
Add `single-threaded` as an optional non-default feature to `bevy_ecs`
and `bevy_tasks` that:
- disable the `ParallelExecutor` as a default runner
- disables the multi-threaded `TaskPool`
- internally replace `QueryParIter::for_each` calls with
`Query::for_each`.
Removed the `Mutex` and `Arc` usage in the single-threaded task pool.
![image](https://user-images.githubusercontent.com/3137680/202833253-dd2d520f-75e6-4c7b-be2d-5ce1523cbd38.png)
## Future Work/TODO
Create type aliases for `Mutex`, `Arc` that change to single-threaaded
equivalents where possible.
---
## Changelog
Added: Optional default feature `multi-theaded` to that enables
multithreaded parallelism in the engine. Disabling it disables all
multithreading in exchange for higher single threaded performance. Does
nothing on WASM targets.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- accesskit_unix is not optional anymore
## Solution
- Enable `async-io` feature of `accesskit_winit` only when
`accesskit_unix` is enabled
# Objective
Improve the `bevy_audio` API to make it more user-friendly and
ECS-idiomatic. This PR is a first-pass at addressing some of the most
obvious (to me) problems. In the interest of keeping the scope small,
further improvements can be done in future PRs.
The current `bevy_audio` API is very clunky to work with, due to how it
(ab)uses bevy assets to represent audio sinks.
The user needs to write a lot of boilerplate (accessing
`Res<Assets<AudioSink>>`) and deal with a lot of cognitive overhead
(worry about strong vs. weak handles, etc.) in order to control audio
playback.
Audio playback is initiated via a centralized `Audio` resource, which
makes it difficult to keep track of many different sounds playing in a
typical game.
Further, everything carries a generic type parameter for the sound
source type, making it difficult to mix custom sound sources (such as
procedurally generated audio or unofficial formats) with regular audio
assets.
Let's fix these issues.
## Solution
Refactor `bevy_audio` to a more idiomatic ECS API. Remove the `Audio`
resource. Do everything via entities and components instead.
Audio playback data is now stored in components:
- `PlaybackSettings`, `SpatialSettings`, `Handle<AudioSource>` are now
components. The user inserts them to tell Bevy to play a sound and
configure the initial playback parameters.
- `AudioSink`, `SpatialAudioSink` are now components instead of special
magical "asset" types. They are inserted by Bevy when it actually begins
playing the sound, and can be queried for by the user in order to
control the sound during playback.
Bundles: `AudioBundle` and `SpatialAudioBundle` are available to make it
easy for users to play sounds. Spawn an entity with one of these bundles
(or insert them to a complex entity alongside other stuff) to play a
sound.
Each entity represents a sound to be played.
There is also a new "auto-despawn" feature (activated using
`PlaybackSettings`), which, if enabled, tells Bevy to despawn entities
when the sink playback finishes. This allows for "fire-and-forget" sound
playback. Users can simply
spawn entities whenever they want to play sounds and not have to worry
about leaking memory.
## Unsolved Questions
I think the current design is *fine*. I'd be happy for it to be merged.
It has some possibly-surprising usability pitfalls, but I think it is
still much better than the old `bevy_audio`. Here are some discussion
questions for things that we could further improve. I'm undecided on
these questions, which is why I didn't implement them. We should decide
which of these should be addressed in this PR, and what should be left
for future PRs. Or if they should be addressed at all.
### What happens when sounds start playing?
Currently, the audio sink components are inserted and the bundle
components are kept. Should Bevy remove the bundle components? Something
else?
The current design allows an entity to be reused for playing the same
sound with the same parameters repeatedly. This is a niche use case I'd
like to be supported, but if we have to give it up for a simpler design,
I'd be fine with that.
### What happens if users remove any of the components themselves?
As described above, currently, entities can be reused. Removing the
audio sink causes it to be "detached" (I kept the old `Drop` impl), so
the sound keeps playing. However, if the audio bundle components are not
removed, Bevy will detect this entity as a "queued" sound entity again
(has the bundle compoenents, without a sink component), just like before
playing the sound the first time, and start playing the sound again.
This behavior might be surprising? Should we do something different?
### Should mutations to `PlaybackSettings` be applied to the audio sink?
We currently do not do that. `PlaybackSettings` is just for the initial
settings when the sound starts playing. This is clearly documented.
Do we want to keep this behavior, or do we want to allow users to use
`PlaybackSettings` instead of `AudioSink`/`SpatialAudioSink` to control
sounds during playback too?
I think I prefer for them to be kept separate. It is not a bad mental
model once you understand it, and it is documented.
### Should `AudioSink` and `SpatialAudioSink` be unified into a single
component type?
They provide a similar API (via the `AudioSinkPlayback` trait) and it
might be annoying for users to have to deal with both of them. The
unification could be done using an enum that is matched on internally by
the methods. Spatial audio has extra features, so this might make it
harder to access. I think we shouldn't.
### Automatic synchronization of spatial sound properties from
Transforms?
Should Bevy automatically apply changes to Transforms to spatial audio
entities? How do we distinguish between listener and emitter? Which one
does the transform represent? Where should the other one come from?
Alternatively, leave this problem for now, and address it in a future
PR. Or do nothing, and let users deal with it, as shown in the
`spatial_audio_2d` and `spatial_audio_3d` examples.
---
## Changelog
Added:
- `AudioBundle`/`SpatialAudioBundle`, add them to entities to play
sounds.
Removed:
- The `Audio` resource.
- `AudioOutput` is no longer `pub`.
Changed:
- `AudioSink`, `SpatialAudioSink` are now components instead of assets.
## Migration Guide
// TODO: write a more detailed migration guide, after the "unsolved
questions" are answered and this PR is finalized.
Before:
```rust
/// Need to store handles somewhere
#[derive(Resource)]
struct MyMusic {
sink: Handle<AudioSink>,
}
fn play_music(
asset_server: Res<AssetServer>,
audio: Res<Audio>,
audio_sinks: Res<Assets<AudioSink>>,
mut commands: Commands,
) {
let weak_handle = audio.play_with_settings(
asset_server.load("music.ogg"),
PlaybackSettings::LOOP.with_volume(0.5),
);
// upgrade to strong handle and store it
commands.insert_resource(MyMusic {
sink: audio_sinks.get_handle(weak_handle),
});
}
fn toggle_pause_music(
audio_sinks: Res<Assets<AudioSink>>,
mymusic: Option<Res<MyMusic>>,
) {
if let Some(mymusic) = &mymusic {
if let Some(sink) = audio_sinks.get(&mymusic.sink) {
sink.toggle();
}
}
}
```
Now:
```rust
/// Marker component for our music entity
#[derive(Component)]
struct MyMusic;
fn play_music(
mut commands: Commands,
asset_server: Res<AssetServer>,
) {
commands.spawn((
AudioBundle::from_audio_source(asset_server.load("music.ogg"))
.with_settings(PlaybackSettings::LOOP.with_volume(0.5)),
MyMusic,
));
}
fn toggle_pause_music(
// `AudioSink` will be inserted by Bevy when the audio starts playing
query_music: Query<&AudioSink, With<MyMusic>>,
) {
if let Ok(sink) = query.get_single() {
sink.toggle();
}
}
```
# Objective
`accesskit` and `accesskit_winit` need to be upgraded.
## Solution
Upgrade `accesskit` and `accesskit_winit`.
---
## Changelog
### Changed
* Upgrade accesskit to v0.11.
* Upgrade accesskit_winit to v0.14.
# Objective
Currently, `DynamicScene`s extract all components listed in the given
(or the world's) type registry. This acts as a quasi-filter of sorts.
However, it can be troublesome to use effectively and lacks decent
control.
For example, say you need to serialize only the following component over
the network:
```rust
#[derive(Reflect, Component, Default)]
#[reflect(Component)]
struct NPC {
name: Option<String>
}
```
To do this, you'd need to:
1. Create a new `AppTypeRegistry`
2. Register `NPC`
3. Register `Option<String>`
If we skip Step 3, then the entire scene might fail to serialize as
`Option<String>` requires registration.
Not only is this annoying and easy to forget, but it can leave users
with an impossible task: serializing a third-party type that contains
private types.
Generally, the third-party crate will register their private types
within a plugin so the user doesn't need to do it themselves. However,
this means we are now unable to serialize _just_ that type— we're forced
to allow everything!
## Solution
Add the `SceneFilter` enum for filtering components to extract.
This filter can be used to optionally allow or deny entire sets of
components/resources. With the `DynamicSceneBuilder`, users have more
control over how their `DynamicScene`s are built.
To only serialize a subset of components, use the `allow` method:
```rust
let scene = builder
.allow::<ComponentA>()
.allow::<ComponentB>()
.extract_entity(entity)
.build();
```
To serialize everything _but_ a subset of components, use the `deny`
method:
```rust
let scene = builder
.deny::<ComponentA>()
.deny::<ComponentB>()
.extract_entity(entity)
.build();
```
Or create a custom filter:
```rust
let components = HashSet::from([type_id]);
let filter = SceneFilter::Allowlist(components);
// let filter = SceneFilter::Denylist(components);
let scene = builder
.with_filter(Some(filter))
.extract_entity(entity)
.build();
```
Similar operations exist for resources:
<details>
<summary>View Resource Methods</summary>
To only serialize a subset of resources, use the `allow_resource`
method:
```rust
let scene = builder
.allow_resource::<ResourceA>()
.extract_resources()
.build();
```
To serialize everything _but_ a subset of resources, use the
`deny_resource` method:
```rust
let scene = builder
.deny_resource::<ResourceA>()
.extract_resources()
.build();
```
Or create a custom filter:
```rust
let resources = HashSet::from([type_id]);
let filter = SceneFilter::Allowlist(resources);
// let filter = SceneFilter::Denylist(resources);
let scene = builder
.with_resource_filter(Some(filter))
.extract_resources()
.build();
```
</details>
### Open Questions
- [x] ~~`allow` and `deny` are mutually exclusive. Currently, they
overwrite each other. Should this instead be a panic?~~ Took @soqb's
suggestion and made it so that the opposing method simply removes that
type from the list.
- [x] ~~`DynamicSceneBuilder` extracts entity data as soon as
`extract_entity`/`extract_entities` is called. Should this behavior
instead be moved to the `build` method to prevent ordering mixups (e.g.
`.allow::<Foo>().extract_entity(entity)` vs
`.extract_entity(entity).allow::<Foo>()`)? The tradeoff would be
iterating over the given entities twice: once at extraction and again at
build.~~ Based on the feedback from @Testare it sounds like it might be
better to just keep the current functionality (if anything we can open a
separate PR that adds deferred methods for extraction, so the
choice/performance hit is up to the user).
- [ ] An alternative might be to remove the filter from
`DynamicSceneBuilder` and have it as a separate parameter to the
extraction methods (either in the existing ones or as added
`extract_entity_with_filter`-type methods). Is this preferable?
- [x] ~~Should we include constructors that include common types to
allow/deny? For example, a `SceneFilter::standard_allowlist` that
includes things like `Parent` and `Children`?~~ Consensus suggests we
should. I may split this out into a followup PR, though.
- [x] ~~Should we add the ability to remove types from the filter
regardless of whether an allowlist or denylist (e.g.
`filter.remove::<Foo>()`)?~~ See the first list item
- [x] ~~Should `SceneFilter` be an enum? Would it make more sense as a
struct that contains an `is_denylist` boolean?~~ With the added
`SceneFilter::None` state (replacing the need to wrap in an `Option` or
rely on an empty `Denylist`), it seems an enum is better suited now
- [x] ~~Bikeshed: Do we like the naming convention? Should we instead
use `include`/`exclude` terminology?~~ Sounds like we're sticking with
`allow`/`deny`!
- [x] ~~Does this feature need a new example? Do we simply include it in
the existing one (maybe even as a comment?)? Should this be done in a
followup PR instead?~~ Example will be added in a followup PR
### Followup Tasks
- [ ] Add a dedicated `SceneFilter` example
- [ ] Possibly add default types to the filter (e.g. deny things like
`ComputedVisibility`, allow `Parent`, etc)
---
## Changelog
- Added the `SceneFilter` enum for filtering components and resources
when building a `DynamicScene`
- Added methods:
- `DynamicSceneBuilder::with_filter`
- `DynamicSceneBuilder::allow`
- `DynamicSceneBuilder::deny`
- `DynamicSceneBuilder::allow_all`
- `DynamicSceneBuilder::deny_all`
- `DynamicSceneBuilder::with_resource_filter`
- `DynamicSceneBuilder::allow_resource`
- `DynamicSceneBuilder::deny_resource`
- `DynamicSceneBuilder::allow_all_resources`
- `DynamicSceneBuilder::deny_all_resources`
- Removed methods:
- `DynamicSceneBuilder::from_world_with_type_registry`
- `DynamicScene::from_scene` and `DynamicScene::from_world` no longer
require an `AppTypeRegistry` reference
## Migration Guide
- `DynamicScene::from_scene` and `DynamicScene::from_world` no longer
require an `AppTypeRegistry` reference:
```rust
// OLD
let registry = world.resource::<AppTypeRegistry>();
let dynamic_scene = DynamicScene::from_world(&world, registry);
// let dynamic_scene = DynamicScene::from_scene(&scene, registry);
// NEW
let dynamic_scene = DynamicScene::from_world(&world);
// let dynamic_scene = DynamicScene::from_scene(&scene);
```
- Removed `DynamicSceneBuilder::from_world_with_type_registry`. Now the
registry is automatically taken from the given world:
```rust
// OLD
let registry = world.resource::<AppTypeRegistry>();
let builder = DynamicSceneBuilder::from_world_with_type_registry(&world,
registry);
// NEW
let builder = DynamicSceneBuilder::from_world(&world);
```
# Objective
After the UI layout is computed when the coordinates are converted back
from physical coordinates to logical coordinates the `UiScale` is
ignored. This results in a confusing situation where we have two
different systems of logical coordinates.
Example:
```rust
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
}
fn setup(mut commands: Commands, mut ui_scale: ResMut<UiScale>) {
ui_scale.scale = 4.;
commands.spawn(Camera2dBundle::default());
commands.spawn(NodeBundle {
style: Style {
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
width: Val::Percent(100.),
..Default::default()
},
..Default::default()
})
.with_children(|builder| {
builder.spawn(NodeBundle {
style: Style {
width: Val::Px(100.),
height: Val::Px(100.),
..Default::default()
},
background_color: Color::MAROON.into(),
..Default::default()
}).with_children(|builder| {
builder.spawn(TextBundle::from_section("", TextStyle::default());
});
});
}
fn update(
mut text_query: Query<(&mut Text, &Parent)>,
node_query: Query<Ref<Node>>,
) {
for (mut text, parent) in text_query.iter_mut() {
let node = node_query.get(parent.get()).unwrap();
if node.is_changed() {
text.sections[0].value = format!("size: {}", node.size());
}
}
}
```
result:
![Bevy App 30_05_2023
16_54_32](https://github.com/bevyengine/bevy/assets/27962798/a5ecbf31-0a12-4669-87df-b0c32f058732)
We asked for a 100x100 UI node but the Node's size is multiplied by the
value of `UiScale` to give a logical size of 400x400.
## Solution
Divide the output physical coordinates by `UiScale` in
`ui_layout_system` and multiply the logical viewport size by `UiScale`
when creating the projection matrix for the UI's `ExtractedView` in
`extract_default_ui_camera_view`.
---
## Changelog
* The UI layout's physical coordinates are divided by both the window
scale factor and `UiScale` when converting them back to logical
coordinates. The logical size of Ui nodes now matches the values given
to their size constraints.
* Multiply the logical viewport size by `UiScale` before creating the
projection matrix for the UI's `ExtractedView` in
`extract_default_ui_camera_view`.
* In `ui_focus_system` the cursor position returned from `Window` is
divided by `UiScale`.
* Added a scale factor parameter to `Node::physical_size` and
`Node::physical_rect`.
* The example `viewport_debug` now uses a `UiScale` of 2. to ensure that
viewport coordinates are working correctly with a non-unit `UiScale`.
## Migration Guide
Physical UI coordinates are now divided by both the `UiScale` and the
window's scale factor to compute the logical sizes and positions of UI
nodes.
This ensures that UI Node size and position values, held by the `Node`
and `GlobalTransform` components, conform to the same logical coordinate
system as the style constraints from which they are derived,
irrespective of the current `scale_factor` and `UiScale`.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Fixes#8630.
## Solution
Since a camera's view and projection matrices are modified during
`PostUpdate` in `camera_system` and `propagate_transforms`, it is fine
to move `update_previous_view_projections` from `Update` to `PreUpdate`.
Doing so adds consistence with `update_mesh_previous_global_transforms`
and allows systems in `Update` to use `PreviousViewProjection` correctly
without explicit ordering.
# Objective
I'm creating an iOS game and had to find a way to persist game state
when the application is terminated. This required listening to the
[`applicationWillTerminate()`
method](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623111-applicationwillterminate),
but I cannot do so myself anymore since `winit` already set up a
delegate to listen for it, and there can be only one delegate.
So I had to move up the stack and try to respond to one of the events
from `winit` instead. It appears `winit` fires two events that could
serve my purpose: `WindowEvent::Destroyed` and `Event::LoopDestroyed`.
It seemed to me the former might be slightly more generally useful, and
I also found a past discussion that suggested it would be appropriate
for Bevy to have a `WindowDestroyed` event:
https://github.com/bevyengine/bevy/pull/5589#discussion_r942811021
## Solution
- I've added the `WindowDestroyed` event, which fires when `winit` fires
`WindowEvent::Destroyed`.
---
## Changelog
### Added
- Introduced a new `WindowDestroyed` event type. It is used to indicate
a window has been destroyed by the windowing system.
# Objective
bevy_render currently has a dependency on a random older version of
once_cell which is not used anywhere.
## Solution
Remove the dependency
## Changelog
N/A
## Migration Guide
N/A
# Objective
- Remove need to call `.get()` on two ticks to compare them for
equality.
## Solution
- Derive `Eq` and `PartialEq`.
---
## Changelog
> `Tick` now implements `Eq` and `PartialEq`
# Objective
- Fix#8984
### Solution
- Address compilation errors
I admit: I did sneak it an unrelated mini-refactor. of the
`measurment.rs` module. it seemed to me that directly importing `taffy`
types helped reduce a lot of boilerplate, so I did it.
# Objective
The bounding box colors are from bevy_gizmo are randomized between app
runs. This can get confusing for users.
## Solution
Use a fixed seed with `RandomState::with_seeds` rather than initializing
a `AHash`.
The random number was chose so that the first few colors are clearly
distinct.
According to the `RandomState::hash_one` documentation, it's also
faster.
![bevy_bounding_box_colors_2023-07-03](https://github.com/bevyengine/bevy/assets/26321040/676f0389-d00e-4edd-bd77-1fbf73a3d9fa)
---
## Changelog
* bevy_gizmo: Keep a consistent color for AABBs of identical entities
between runs
# Objective
Since 10f5c92, shadows were broken for models with morph target.
When #5703 was merged, the morph target code in `render/mesh.wgsl` was
correctly updated to use the new import syntax. However, similar code
exists in `prepass/prepass.wgsl`, but it was never update. (the reason
code is duplicated is that the `Vertex` struct is different for both
files).
## Solution
Update the code, so that shadows render correctly with morph targets.
# Objective
Fixes https://github.com/bevyengine/bevy/issues/8925
## Solution
~~Clamp the bad values.~~
Normalize the prepass normals when we get them in the `prepass_normal()`
function.
## More Info
The issue is that NdotV is sometimes very slightly greater than 1 (maybe
FP rounding issues?), which caused `F_Schlick()` to return NANs in
`pow(1.0 - NdotV, 5.0)` (call stack looked like`pbr()` ->
`directional_light()` -> `Fd_Burley()` -> `F_Schlick()`)
# Objective
Since 10f5c92, parallax mapping was broken.
When #5703 was merged, the change from `in.uv` to `uv` in the pbr shader
was reverted. So the shader would use the wrong coordinate to sample the
various textures.
## Solution
We revert to using the correct uv.
# Objective
Followup bugfix for #5703. Without this we get the following error when
CAS (Contrast Adaptive Sharpening) is enabled:
```
2023-06-29T01:31:23.829331Z ERROR bevy_render::render_resource::pipeline_cache: failed to process shader:
error: unknown type: 'FullscreenVertexOutput'
┌─ crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/robust_contrast_adaptive_sharpening.wgsl:63:17
│
63 │ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
│ ^^^^^^^^^^^^^^^^^^^^^^ unknown type
│
= unknown type: 'FullscreenVertexOutput'
```
@robtfm I wouldn't expect this to fail. I was under the impression the
`#import bevy_core_pipeline::fullscreen_vertex_shader` would pull
"everything" from that file into this one?
# Objective
- This fixes a crash when loading shaders, when running an Adreno GPU
and using WebGL mode.
- Fixes#8506
- Fixes#8047
## Solution
- The shader pbr_functions.wgsl, will fail in apply_fog function, trying
to access values that are null on Adreno chipsets using WebGL, these
devices are commonly found in android handheld devices.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: François <mockersf@gmail.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
Title. This is necessary in order to update
[`bevy-trait-query`](https://crates.io/crates/bevy-trait-query) to Bevy
0.11.
---
## Changelog
Added the unsafe function `UnsafeWorldCell::storages`, which provides
unchecked access to the internal data stores of a `World`.
Added `GizmoConfig::render_layers`, which will ensure Gizmos are only
rendered on cameras that can see those `RenderLayers`.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
Relax unnecessary type restrictions on `App.runner` function.
## Solution
Changed the type of `App.runner` from `Fn(App)` to `FnOnce(App)`.
# Objective
#5703 caused the normal prepass to fail as the prepass uses
`pbr_functions::apply_normal_mapping`, which uses
`mesh_view_bindings::view` to determine mip bias, which conflicts with
`prepass_bindings::view`.
## Solution
pass the mip bias to the `apply_normal_mapping` function explicitly.
# Objective
Currently `App::edit_schedule` takes in `impl FnMut(&mut Schedule)`, but
it calls the function only once. It is probably the intention has been
to have it take `FnOnce` instead.
## Solution
- Relax the parameter to take `FnOnce` instead of `FnMut`
# Objective
- There was a deadlock discovered in the implementation of
`bevy_reflect::utility::GenericTypeCell`, when called on a recursive
type, e.g. `Vec<Vec<VariableCurve>>`
## Solution
- Drop the lock before calling the initialisation function, and then
pick it up again afterwards.
## Additional Context
- [Discussed on
Discord](https://discord.com/channels/691052431525675048/1002362493634629796/1122706835284185108)
# Objective
operate on naga IR directly to improve handling of shader modules.
- give codespan reporting into imported modules
- allow glsl to be used from wgsl and vice-versa
the ultimate objective is to make it possible to
- provide user hooks for core shader functions (to modify light
behaviour within the standard pbr pipeline, for example)
- make automatic binding slot allocation possible
but ... since this is already big, adds some value and (i think) is at
feature parity with the existing code, i wanted to push this now.
## Solution
i made a crate called naga_oil (https://github.com/robtfm/naga_oil -
unpublished for now, could be part of bevy) which manages modules by
- building each module independantly to naga IR
- creating "header" files for each supported language, which are used to
build dependent modules/shaders
- make final shaders by combining the shader IR with the IR for imported
modules
then integrated this into bevy, replacing some of the existing shader
processing stuff. also reworked examples to reflect this.
## Migration Guide
shaders that don't use `#import` directives should work without changes.
the most notable user-facing difference is that imported
functions/variables/etc need to be qualified at point of use, and
there's no "leakage" of visible stuff into your shader scope from the
imports of your imports, so if you used things imported by your imports,
you now need to import them directly and qualify them.
the current strategy of including/'spreading' `mesh_vertex_output`
directly into a struct doesn't work any more, so these need to be
modified as per the examples (e.g. color_material.wgsl, or many others).
mesh data is assumed to be in bindgroup 2 by default, if mesh data is
bound into bindgroup 1 instead then the shader def `MESH_BINDGROUP_1`
needs to be added to the pipeline shader_defs.
# Objective
Currently when `UntypedReflectDeserializerVisitor` deserializes a
`Box<dyn Reflect>` it only considers the first entry of the map,
silently ignoring any additional entries. For example the following RON
data:
```json
{
"f32": 1.23,
"u32": 1,
}
```
is successfully deserialized as a `f32`, completly ignoring the `"u32":
1` part.
## Solution
`UntypedReflectDeserializerVisitor` was changed to check if any other
key could be deserialized, and in that case returns an error.
---
## Changelog
`UntypedReflectDeserializer` now errors on malformed inputs instead of
silently disgarding additional data.
## Migration Guide
If you were deserializing `Box<dyn Reflect>` values with multiple
entries (i.e. entries other than `"type": { /* fields */ }`) you should
remove them or deserialization will fail.
# Objective
`World::entity`, `World::entity_mut` and `Commands::entity` should be
marked with `track_caller` to display where (in user code) the call with
the invalid `Entity` was made. `Commands::entity` already has the
attibute, but it does nothing due to the call to `unwrap_or_else`.
## Solution
- Apply the `track_caller` attribute to the `World::entity_mut` and
`World::entity`.
- Remove the call to `unwrap_or_else` which makes the `track_caller`
attribute useless (because `unwrap_or_else` is not `track_caller`
itself). The avoid eager evaluation of the panicking branch it is never
inlined.
---------
Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
# Objective
`color_from_entity` uses the poor man's hash to get a fixed random color
for an entity.
While the poor man's hash is succinct, it has a tendency to clump. As a
result, bevy_gizmos has a tendency to re-use very similar colors for
different entities.
This is bad, we would want non-similar colors that take the whole range
of possible hues. This way, each bevy_gizmos aabb gizmo is easy to
identify.
## Solution
AHash is a nice and fast hash that just so happen to be available to
use, so we use it.
# Objective
In Bevy 10.1 and before, the only way to enable text wrapping was to set
a local `Val::Px` width constraint on the text node itself.
`Val::Percent` constraints and constraints on the text node's ancestors
did nothing.
#7779 fixed those problems. But perversely displaying unwrapped text is
really difficult now, and requires users to nest each `TextBundle` in a
`NodeBundle` and apply `min_width` and `max_width` constraints. Some
constructions may even need more than one layer of nesting. I've seen
several people already who have really struggled with this when porting
their projects to main in advance of 0.11.
## Solution
Add a `NoWrap` variant to the `BreakLineOn` enum.
If `NoWrap` is set, ignore any constraints on the width for the text and
call `TextPipeline::queue_text` with a width bound of `f32::INFINITY`.
---
## Changelog
* Added a `NoWrap` variant to the `BreakLineOn` enum.
* If `NoWrap` is set, any constraints on the width for the text are
ignored and `TextPipeline::queue_text` is called with a width bound of
`f32::INFINITY`.
* Changed the `size` field of `FixedMeasure` to `pub`. This shouldn't
have been private, it was always intended to have `pub` visibility.
* Added a `with_no_wrap` method to `TextBundle`.
## Migration Guide
`bevy_text::text::BreakLineOn` has a new variant `NoWrap` that disables
text wrapping for the `Text`.
Text wrapping can also be disabled using the `with_no_wrap` method of
`TextBundle`.
# Objective
- Fix this error to be able to run UI examples in WebGPU
```
1 error(s) generated while compiling the shader:
:31:18 error: integral user-defined vertex outputs must have a flat interpolation attribute
@location(3) mode: u32,
^^^^
:36:1 note: while analyzing entry point 'vertex'
fn vertex(
^^
```
It was introduce in #8793
## Solution
- Add `@interpolate(flat)` to the `mode` field
# Objective
In Bevy main, the unconstrained size of an `ImageBundle` or
`AtlasImageBundle` UI node is based solely on the size of its texture
and doesn't change with window scale factor or `UiScale`.
## Solution
* The size field of each `ImageMeasure` should be multiplied by the
current combined scale factor.
* Each `ImageMeasure` should be updated when the combined scale factor
is changed.
## Example:
```rust
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(UiScale { scale: 1.5 })
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2dBundle::default());
commands.spawn(NodeBundle {
style: Style {
// The size of the "bevy_logo_dark.png" texture is 520x130 pixels
width: Val::Px(520.),
height: Val::Px(130.),
..Default::default()
},
background_color: Color::RED.into(),
..Default::default()
});
commands
.spawn(ImageBundle {
style: Style {
position_type: PositionType::Absolute,
..Default::default()
},
image: UiImage::new(asset_server.load("bevy_logo_dark.png")),
..Default::default()
});
}
```
The red node is given a size with the same dimensions as the texture. So
we would expect the texture to fill the node exactly.
* Result with Bevy main branch bb59509d44:
<img width="400" alt="image-size-broke"
src="https://github.com/bevyengine/bevy/assets/27962798/19fd927d-ecc5-49a7-be05-c121a8df163f">
* Result with this PR (and Bevy 0.10.1):
<img width="400" alt="image-size-fixed"
src="https://github.com/bevyengine/bevy/assets/27962798/40b47820-5f2d-408f-88ef-9e2beb9c92a0">
---
## Changelog
`bevy_ui::widget::image`
* Update all `ImageMeasure`s on changes to the window scale factor or
`UiScale`.
* Multiply `ImageMeasure::size` by the window scale factor and
`UiScale`.
## Migration Guide
# Objective
- Change despawn descendants to return self (#8883).
## Solution
- Change function signature `despawn_descendants` under trait
`DespawnRecursiveExt`.
- Add single extra test `spawn_children_after_despawn_descendants` (May
be unnecessary)
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Partially address #5504. Fix#4278. Provide "whole entity" access in
queries. This can be useful when you don't know at compile time what
you're accessing (i.e. reflection via `ReflectComponent`).
## Solution
Implement `WorldQuery` for `EntityRef`.
- This provides read-only access to the entire entity, and supports
anything that `EntityRef` can normally do.
- It matches all archetypes and tables and will densely iterate when
possible.
- It marks all of the ArchetypeComponentIds of a matched archetype as
read.
- Adding it to a query will cause it to panic if used in conjunction
with any other mutable access.
- Expanded the docs on Query to advertise this feature.
- Added tests to ensure the panics were working as intended.
- Added `EntityRef` to the ECS prelude.
To make this safe, `EntityRef::world` was removed as it gave potential
`UnsafeCell`-like access to other parts of the `World` including aliased
mutable access to the components it would otherwise read safely.
## Performance
Not great beyond the additional parallelization opportunity over
exclusive systems. The `EntityRef` is fetched from `Entities` like any
other call to `World::entity`, which can be very random access heavy.
This could be simplified if `ArchetypeRow` is available in
`WorldQuery::fetch`'s arguments, but that's likely not something we
should optimize for.
## Future work
An equivalent API where it gives mutable access to all components on a
entity can be done with a scoped version of `EntityMut` where it does
not provide `&mut World` access nor allow for structural changes to the
entity is feasible as well. This could be done as a safe alternative to
exclusive system when structural mutation isn't required or the target
set of entities is scoped.
---
## Changelog
Added: `Access::has_any_write`
Added: `EntityRef` now implements `WorldQuery`. Allows read-only access
to the entire entity, incompatible with any other mutable access, can be
mixed with `With`/`Without` filters for more targeted use.
Added: `EntityRef` to `bevy::ecs::prelude`.
Removed: `EntityRef::world`
## Migration Guide
TODO
---------
Co-authored-by: Carter Weinberg <weinbergcarter@gmail.com>
Co-authored-by: Jakob Hellermann <jakob.hellermann@protonmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Closes#7323
- Reduce texture blurriness for TAA
## Solution
- Add a `MipBias` component and view uniform.
- Switch material `textureSample()` calls to `textureSampleBias()`.
- Add a `-1.0` bias to TAA.
---
## Changelog
- Added `MipBias` camera component, mostly for internal use.
---------
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Add morph targets to `bevy_pbr` (closes#5756) & load them from glTF
- Supersedes #3722
- Fixes#6814
[Morph targets][1] (also known as shape interpolation, shape keys, or
blend shapes) allow animating individual vertices with fine grained
controls. This is typically used for facial expressions. By specifying
multiple poses as vertex offset, and providing a set of weight of each
pose, it is possible to define surprisingly realistic transitions
between poses. Blending between multiple poses also allow composition.
Morph targets are part of the [gltf standard][2] and are a feature of
Unity and Unreal, and babylone.js, it is only natural to implement them
in bevy.
## Solution
This implementation of morph targets uses a 3d texture where each pixel
is a component of an animated attribute. Each layer is a different
target. We use a 2d texture for each target, because the number of
attribute×components×animated vertices is expected to always exceed the
maximum pixel row size limit of webGL2. It copies fairly closely the way
skinning is implemented on the CPU side, while on the GPU side, the
shader morph target implementation is a relatively trivial detail.
We add an optional `morph_texture` to the `Mesh` struct. The
`morph_texture` is built through a method that accepts an iterator over
attribute buffers.
The `MorphWeights` component, user-accessible, controls the blend of
poses used by mesh instances (so that multiple copy of the same mesh may
have different weights), all the weights are uploaded to a uniform
buffer of 256 `f32`. We limit to 16 poses per mesh, and a total of 256
poses.
More literature:
* Old babylone.js implementation (vertex attribute-based):
https://www.eternalcoding.com/dev-log-1-morph-targets/
* Babylone.js implementation (similar to ours):
https://www.youtube.com/watch?v=LBPRmGgU0PE
* GPU gems 3:
https://developer.nvidia.com/gpugems/gpugems3/part-i-geometry/chapter-3-directx-10-blend-shapes-breaking-limits
* Development discord thread
https://discord.com/channels/691052431525675048/1083325980615114772https://user-images.githubusercontent.com/26321040/231181046-3bca2ab2-d4d9-472e-8098-639f1871ce2e.mp4https://github.com/bevyengine/bevy/assets/26321040/d2a0c544-0ef8-45cf-9f99-8c3792f5a258
## Acknowledgements
* Thanks to `storytold` for sponsoring the feature
* Thanks to `superdump` and `james7132` for guidance and help figuring
out stuff
## Future work
- Handling of less and more attributes (eg: animated uv, animated
arbitrary attributes)
- Dynamic pose allocation (so that zero-weighted poses aren't uploaded
to GPU for example, enables much more total poses)
- Better animation API, see #8357
----
## Changelog
- Add morph targets to bevy meshes
- Support up to 64 poses per mesh of individually up to 116508 vertices,
animation currently strictly limited to the position, normal and tangent
attributes.
- Load a morph target using `Mesh::set_morph_targets`
- Add `VisitMorphTargets` and `VisitMorphAttributes` traits to
`bevy_render`, this allows defining morph targets (a fairly complex and
nested data structure) through iterators (ie: single copy instead of
passing around buffers), see documentation of those traits for details
- Add `MorphWeights` component exported by `bevy_render`
- `MorphWeights` control mesh's morph target weights, blending between
various poses defined as morph targets.
- `MorphWeights` are directly inherited by direct children (single level
of hierarchy) of an entity. This allows controlling several mesh
primitives through a unique entity _as per GLTF spec_.
- Add `MorphTargetNames` component, naming each indices of loaded morph
targets.
- Load morph targets weights and buffers in `bevy_gltf`
- handle morph targets animations in `bevy_animation` (previously, it
was a `warn!` log)
- Add the `MorphStressTest.gltf` asset for morph targets testing, taken
from the glTF samples repo, CC0.
- Add morph target manipulation to `scene_viewer`
- Separate the animation code in `scene_viewer` from the rest of the
code, reducing `#[cfg(feature)]` noise
- Add the `morph_targets.rs` example to show off how to manipulate morph
targets, loading `MorpStressTest.gltf`
## Migration Guide
- (very specialized, unlikely to be touched by 3rd parties)
- `MeshPipeline` now has a single `mesh_layouts` field rather than
separate `mesh_layout` and `skinned_mesh_layout` fields. You should
handle all possible mesh bind group layouts in your implementation
- You should also handle properly the new `MORPH_TARGETS` shader def and
mesh pipeline key. A new function is exposed to make this easier:
`setup_moprh_and_skinning_defs`
- The `MeshBindGroup` is now `MeshBindGroups`, cached bind groups are
now accessed through the `get` method.
[1]: https://en.wikipedia.org/wiki/Morph_target_animation
[2]:
https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#morph-targets
---------
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
Fix#8908.
## Solution
Assign the vertex buffers twice with a single item offset instead of
setting the array_stride lower than the vertex layout's size for
linestrips.
# Objective
Improve the documentation relating to windows, and update the parts that
have not been updated since version 0.8.
Version 0.9 introduced `Window` as a component, before that
`WindowDescriptor` (which would become `Window` later) was used to store
information about how a window will be created. Since version 0.9, from
my understanding, this information will also be synchronised with the
current state of the window, and can be used to modify this state.
However, some of the documentation has not been updated to reflect that,
here is an example:
https://docs.rs/bevy/0.8.0/bevy/window/enum.WindowMode.html /
https://docs.rs/bevy/latest/bevy/window/enum.WindowMode.html (notice
that the verb "Creates" is still there).
This PR aims at improving the documentation relating to windows.
## Solution
- Change "will" for "should" when relevant, "should" implies that the
information should in both direction (from the window state to the
`Window` component and vice-versa) and can be used to get and set, will
implies it is only used to set a state.
- Remove references to "creation" or be more clear about it.
- Reference back the `Window` component for most of its sub-structs.
- Clarify what needs to be clarified
- A lot of other minor changes, including fixing the link to W3schools
in `bevy_winit`
## Warning
Please note that my knowledge about how winit and bevy_winit work is
limited and some of the informations I added in the doc may be
inaccurate. A person who knows better how it works should review some of
my claims, in particular:
- How fullscreen works:
https://github.com/bevyengine/bevy/pull/8858#discussion_r1232413155
- How WindowResolution / sizes work:
https://github.com/bevyengine/bevy/pull/8858#discussion_r1233010719
- What happens when `WindowPosition` is set to `Centered` or
`Automatic`. From my understanding of the code, it should always be set
back to `At`, but is it really the case? For example [when creating the
window](https://github.com/bevyengine/bevy/blob/main/crates/bevy_winit/src/winit_windows.rs#L74),
or when [a `WindowEvent::Moved` is
triggered](https://github.com/bevyengine/bevy/blob/main/crates/bevy_winit/src/lib.rs#L602)
or when [Centered/Automatic by the code after the window is
created](https://github.com/bevyengine/bevy/blob/main/crates/bevy_winit/src/system.rs#L243),
am I missing some cases and do the codes I linked do that in all of
them?
- Are there any field in the `Window` component that can't be used to
modify the state of the window, only at creation?
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Jerome Humbert <djeedai@gmail.com>
# Objective
- Fix the AsBindGroup texture attribute visibility flag parsing
- This appears to have been caused by a syn crate update which then the
visibility code got updated
- Also I noticed that by default the vertex and fragment flags were on,
so visibility(compute) would actually make the texture visible to
vertex, fragment and compute shaders, I fixed this too
## Solution
- Update flag parsing to use MetaList.parse_nested_meta function, which
loads the flags into a Vec then loop through those flags
- Change initial visibility flags to use VisibilityFlags::default()
rather than VisibilityFlags::vertex_fragment()
# Objective
`prepare_uinodes` creates a new `UiBatch` whenever the texture changes,
when most often it's just queuing untextured quads. Instead of switching
textures, we can reduce the number of batches generated significantly by
adding a condition to the fragment shader so that it only multiplies by
the `textureSample` value when drawing a textured quad.
# Solution
Add a `mode` field to `UiVertex`.
In `prepare_uinodes` set `mode` to 0 if the quad is textured or 1 if
untextured.
Add a condition to the fragment shader that only multiplies by the
`color` value from `textureSample` if `mode` is set to 1.
---
## Changelog
* Added a `mode` field to `UiVertex`, and added an extra `u32` vertex
attribute to the shader and vertex buffer layout.
* In `prepare_uinodes` mode is set to 0 for the vertices of textured
quads, and 1 if untextured.
* Added a condition to the fragment shader in `ui.wgsl` that only
multiplies by the `color` value from `textureSample` if the mode is
equal to 0.
# Objective
- Fixes#8645
## Solution
Cascaded shadow maps use a technique commonly called shadow pancaking to
enhance shadow map resolution by restricting the orthographic projection
used in creating the shadow maps to the frustum slice for the cascade.
The implication of this restriction is that shadow casters can be closer
than the near plane of the projection volume.
Prior to this PR, we address clamp the depth of the prepass vertex
output to ensure that these shadow casters do not get clipped, resulting
in shadow loss. However, a flaw / bug of the prior approach is that the
depth that gets written to the shadow map isn't quite correct - the
depth was previously derived by interpolated the clamped clip position,
resulting in depths that are further than they should be. This creates
artifacts that are particularly noticeable when a very 'long' object
intersects the near plane close to perpendicularly.
The fix in this PR is to propagate the unclamped depth to the prepass
fragment shader and use that depth value directly.
A complementary solution would be to use
[DEPTH_CLIP_CONTROL](https://docs.rs/wgpu/latest/wgpu/struct.Features.html#associatedconstant.DEPTH_CLIP_CONTROL)
to request `unclipped_depth`. However due to the relatively low support
of the feature on Vulkan (I believe it's ~38%), I went with this
solution for now to get the broadest fix out first.
---
## Changelog
- Fixed: Shadows from directional lights were sometimes incorrectly
omitted when the shadow caster was partially out of view.
---------
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
- Fix broken normals when the NormalPrepass is enabled
## Solution
- Don't use the normal prepass for the world_normal
- Only loadthe normal prepass
- when msaa is disabled
- for opaque or alpha mask meshes and only for use it for N not
world_normal
# Objective
- Use `AppTypeRegistry` on API defined in `bevy_ecs`
(https://github.com/bevyengine/bevy/pull/8895#discussion_r1234748418)
A lot of the API on `Reflect` depends on a registry. When it comes to
the ECS. We should use `AppTypeRegistry` in the general case.
This is however impossible in `bevy_ecs`, since `AppTypeRegistry` is
defined in `bevy_app`.
## Solution
- Move `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`
- Still add the resource in the `App` plugin, since bevy_ecs itself
doesn't know of plugins
Note that `bevy_ecs` is a dependency of `bevy_app`, so nothing
revolutionary happens.
## Alternative
- Define the API as a trait in `bevy_app` over `bevy_ecs`. (though this
prevents us from using bevy_ecs internals)
- Do not rely on `AppTypeRegistry` for the API in question, requring
users to extract themselves the resource and pass it to the API methods.
---
## Changelog
- Moved `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`
## Migration Guide
- If you were **not** using a `prelude::*` to import `AppTypeRegistry`,
you should update your imports:
```diff
- use bevy::app::AppTypeRegistry;
+ use bevy::ecs::reflect::AppTypeRegistry
```
# Objective
The "bevy_text" feature attributes for the `PrimaryWindow`, `Window` and
`TextureAtlas` imports in `bevy_ui::render` are used by non-text systems
(`extract_uinode_borders` and `extract_atlas_uinodes`) and need to be
removed.
For those who wish to be able to `#[reflect]` stuff using the `Uuid`
type
I'm very unfamiliar with the codebase, so please tell me if I'm missing
something
# Objective
- Providing a "noob-friendly" example since not many people are
proficient in 3D modeling / rendering concepts.
## Solution
- Adding more information to the example, with an explanation.
~~~~
_Thanks to Nocta on discord for helping out when I didn't understand the
subject well._
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
- `bevy_log` writes logs to `stdout` (with ANSI formatting), which gets
in the way with program output and complicates parsing.
- Closes#8869
## Solution
- Change `bevy_log` to write to `stderr` instead of `stdout`
---
## Changelog
Changed:
- Logs write to `stderr` rather than `stdout` on desktop targets
## Migration Guide
- Capture logs from `stderr` instead of from `stdout`
- Use `2> output.log` on the command line to save `stderr` to a file
# Objective
Add a get_unclamped method to
[Axis](https://docs.rs/bevy/0.10.1/bevy/input/struct.Axis.html) to allow
it to be used in cases where being able to get a precise relative
movement is important. For example, camera zoom with the mouse wheel.
This would make it possible for libraries like leafwing input manager to
leverage `Axis` for mouse motion and mouse wheel axis mapping. I tried
to use it my PR here
https://github.com/Leafwing-Studios/leafwing-input-manager/pull/346 but
will likely have to revert that and read the mouse wheel events for now
which is what prompted this PR.
## Solution
Instead of clamping the axis value when it is set, it now stores the raw
value and clamps it in the `get` method. This allows a simple
get_unclamped method that just returns the raw value.
## Changelog
- Added a get_unclamped method to Axis that can return values outside of
-1.0 to 1.0
# Objective
Fixes#6920
## Solution
From the issue discussion:
> From looking at the `AsBindGroup` derive macro implementation, the
fallback image's `TextureView` is used when the binding's
`Option<Handle<Image>>` is `None`. Because this relies on already having
a view that matches the desired binding dimensions, I think the solution
will require creating a separate `GpuImage` for each possible
`TextureViewDimension`.
---
## Changelog
Users can now rely on `FallbackImage` to work with a texture binding of
any dimension.
# Objective
- Document android code that is currently causing clippy warnings due to
not being documented
## Solution
- Document the two previously undocumented items
# Objective
`WorldQuery::Fetch` is a type used to optimize the implementation of
queries. These types are hidden and not intended to be outside of the
engine, so there is no need to provide type aliases to make it easier to
refer to them. If a user absolutely needs to refer to one of these
types, they can always just refer to the associated type directly.
## Solution
Deprecate these type aliases.
---
## Changelog
- Deprecated the type aliases `QueryFetch` and `ROQueryFetch`.
## Migration Guide
The type aliases `bevy_ecs::query::QueryFetch` and `ROQueryFetch` have
been deprecated. If you need to refer to a `WorldQuery` struct's fetch
type, refer to the associated type defined on `WorldQuery` directly:
```rust
// Before:
type MyFetch<'w> = QueryFetch<'w, MyQuery>;
type MyFetchReadOnly<'w> = ROQueryFetch<'w, MyQuery>;
// After:
type MyFetch<'w> = <MyQuery as WorldQuery>::Fetch;
type MyFetchReadOnly<'w> = <<MyQuery as WorldQuery>::ReadOnly as WorldQuery>::Fetch;
```
# Objective
This adds support for using texture atlas sprites in UI. From
discussions today in the ui-dev discord it seems this is a much wanted
feature.
This was previously attempted in #5070 by @ManevilleF however that was
blocked #5103. This work can be easily modified to support #5103 changes
after that merges.
## Solution
I created a new UI bundle that reuses the existing texture atlas
infrastructure. I create a new atlas image component to prevent it from
being drawn by the existing non-UI systems and to remove unused
parameters.
In extract I added new system to calculate the required values for the
texture atlas image, this extracts into the same resource as the
existing UI Image and Text components.
This should have minimal performance impact because if texture atlas is
not present then the exact same code path is followed. Also there should
be no unintended behavior changes because without the new components the
existing systems write the extract same resulting data.
I also added an example showing the sprite working and a system to
advance the animation on space bar presses.
Naming is hard and I would accept any feedback on the bundle name!
---
## Changelog
> Added TextureAtlasImageBundle
---------
Co-authored-by: ickshonpe <david.curthoys@googlemail.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
`ParsedPath` does not need to be mut to access a field of a `Reflect`.
Be that access mutable or not. Yet `element_mut` requires a mutable
borrow on `self`.
## Solution
- Make `element_mut` take a `&self` over a `&mut self`.
#8887 fixes this, but this is a major limitation in the API and I'd
rather see it merged before 0.11.
---
## Changelog
- `ParsedPath::element_mut` and `ParsedPath::reflect_element_mut` now
accept a non-mutable `ParsedPath` (only the accessed `Reflect` needs to
be mutable)
# Objective
- Implementing reflection for Cow<'static, [T]>
- Hopefully fixes#7429
## Solution
- Implementing Reflect, Typed, GetTypeRegistration, and FromReflect for
Cow<'static, [T]>
---
## Notes
I have not used bevy_reflection much yet, so I may not fully understand
all the use cases. This is also my first attempt at contributing, so I
would appreciate any feedback or recommendations for changes. I tried to
add cases for using Cow<'static, str> and Cow<'static, [u8]> to some of
the bevy_reflect tests, but I can't guarantee those tests are
comprehensive enough.
---------
Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Repetitively fetching ReflectResource and ReflectComponent from the
TypeRegistry is costly.
We want to access the underlying `fn`s. to do so, we expose the
`ReflectResourceFns` and `ReflectComponentFns` stored in ReflectResource
and ReflectComponent.
---
## Changelog
- Add the `fn_pointers` methods to `ReflectResource` and
`ReflectComponent` returning the underlying `ReflectResourceFns` and
`ReflectComponentFns`
# Objective
Make the UI code more concise.
## Solution
Add two utility methods to make manipulating `UiRect` from code more
concise:
- `UiRect::px()` create a new `UiRect` like the `new()` function, but
with values in logical pixels directly.
- `UiRect::percent()` is similar, with values as percentages.
This saves a lot of typing and makes UI code more compact while
retaining readability.
---
## Changelog
### Added
Added two new constructors `UiRect::px()` and `UiRect::percent()` to
create a new `UiRect` from values directly specified in logical pixels
and percentages, respectively. The argument order is the same as
`UiRect::new()`, but avoids having to repeat `Val::Px` and
`Val::Percent`, respectively.
# Objective
- Fixes#7811
## Solution
- I added `Has<T>` (and `HasFetch<T>` ) and implemented `WorldQuery`,
`ReadonlyWorldQuery`, and `ArchetypeFilter` it
- I also added documentation with an example and a unit test
I believe I've done everything right but this is my first contribution
and I'm not an ECS expert so someone who is should probably check my
implementation. I based it on what `Or<With<T>,>`, would do. The only
difference is that `Has` does not update component access - adding `Has`
to a query should never affect whether or not it is disjoint with
another query *I think*.
---
## Changelog
## Added
- Added `Has<T>` WorldQuery to find out whether or not an entity has a
particular component.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
# Objective
We can currently set `camera.target` to either an `Image` or `Window`.
For OpenXR & WebXR we need to be able to render to a `TextureView`.
This partially addresses #115 as with the addition we can create
internal and external xr crates.
## Solution
A `TextureView` item is added to the `RenderTarget` enum. It holds an id
which is looked up by a `ManualTextureViews` resource, much like how
`Assets<Image>` works.
I believe this approach was first used by @kcking in their [xr
fork](eb39afd51b/crates/bevy_render/src/camera/camera.rs (L322)).
The only change is that a `u32` is used to index the textures as
`FromReflect` does not support `uuid` and I don't know how to implement
that.
---
## Changelog
### Added
Render: Added `RenderTarget::TextureView` as a `camera.target` option,
enabling rendering directly to a `TextureView`.
## Migration Guide
References to the `RenderTarget` enum will need to handle the additional
field, ie in `match` statements.
---
## Comments
- The [wgpu
work](c039a74884)
done by @expenses allows us to create framebuffer texture views from
`wgpu v0.15, bevy 0.10`.
- I got the WebXR techniques from the [xr
fork](https://github.com/dekuraan/xr-bevy) by @dekuraan.
- I have tested this with a wip [external webxr
crate](018e22bb06/crates/bevy_webxr/src/bevy_utils/xr_render.rs (L50))
on an Oculus Quest 2.
![Screenshot 2023-03-11
230651](https://user-images.githubusercontent.com/25616826/224483696-c176c06f-a806-4abe-a494-b2e096ac96b7.png)
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: Paul Hansen <mail@paul.rs>
# Objective
- Cleanup the `reflect.rs` file in `bevy_ecs`, it's very large and can
get difficult to navigate
## Solution
- Split the file into 3 modules, re-export the types in the
`reflect/mod.rs` to keep a perfectly identical API.
- Add **internal** architecture doc explaining how `ReflectComponent`
works. Note that this doc is internal only, since `component.rs` is not
exposed publicly.
### Tips to reviewers
To review this change properly, you need to compare it to the previous
version of `reflect.rs`. The diff from this PR does not help at all!
What you will need to do is compare `reflect.rs` individually with each
newly created file.
Here is how I did it:
- Adding my fork as remote `git remote add nicopap
https://github.com/nicopap/bevy.git`
- Checkout out the branch `git checkout nicopap/split_ecs_reflect`
- Checkout the old `reflect.rs` by running `git checkout HEAD~1 --
crates/bevy_ecs/src/reflect.rs`
- Compare the old with the new with `git diff --no-index
crates/bevy_ecs/src/reflect.rs crates/bevy_ecs/src/reflect/component.rs`
You could also concatenate everything into a single file and compare
against it:
- `cat
crates/bevy_ecs/src/reflect/{component,resource,map_entities,mod}.rs >
new_reflect.rs`
- `git diff --no-index crates/bevy_ecs/src/reflect.rs new_reflect.rs`
# Objective
Fix https://github.com/bevyengine/bevy/issues/1018 (Textures on the
`Plane` shape appear flipped).
This bug have been around for a very long time apparently, I tested it
was still there (see test code bellow) and sure enough, this image:
![test](https://github.com/bevyengine/bevy/assets/134181069/4cda7cf8-57d9-4677-91f5-02240d1e79b1)
... is flipped vertically when used as a texture on a plane (in main,
0.10.1 and 0.9):
![image](https://github.com/bevyengine/bevy/assets/134181069/0db4f52a-51af-4041-9c45-7bfe1f08b0cc)
I'm pretty confused because this bug is so easy to fix, it has been
around for so long, it is easy to encounter, and PRs touching this code
still didn't fix it: https://github.com/bevyengine/bevy/pull/7546 To the
point where I'm wondering if it's actually intended. If it is, please
explain why and this PR can be changed to "mention that in the doc".
## Solution
Fix the UV mapping on the Plane shape
Here is how it looks after the PR
![image](https://github.com/bevyengine/bevy/assets/134181069/e07ce641-3de8-4da3-a4f3-95a6054c86d7)
## Test code
```rust
use bevy::{
prelude::*,
};
fn main () {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
}
fn setup(
mut commands: Commands,
assets: ResMut<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0., 3., 0.).looking_at(Vec3::ZERO, Vec3::NEG_Z),
..default()
});
let mesh = meshes.add(Mesh::from(shape::Plane::default()));
let texture_image = assets.load("test.png");
let material = materials.add(StandardMaterial {
base_color_texture: Some(texture_image),
..default()
});
commands.spawn(PbrBundle {
mesh,
material,
..default()
});
}
```
## Changelog
Fix textures on `Plane` shapes being flipped vertically.
## Migration Guide
Flip the textures you use on `Plane` shapes.
# Objective
Resolves#7558.
Systems that are known to never modify the world implement the trait
`ReadOnlySystem`. This is a perfect place to add a safe API for running
a system with a shared reference to a World.
---
## Changelog
- Added the trait method `ReadOnlySystem::run_readonly`, which allows a
system to be run using `&World`.
# Objective
- The function `QueryParIter::for_each_unchecked` is a footgun: the only
ways to use it soundly can be done in safe code using `for_each` or
`for_each_mut`. See [this discussion on
discord](https://discord.com/channels/691052431525675048/749335865876021248/1118642977275924583).
## Solution
- Make `for_each_unchecked` private.
---
## Changelog
- Removed `QueryParIter::for_each_unchecked`. All use-cases of this
method were either unsound or doable in safe code using `for_each` or
`for_each_mut`.
## Migration Guide
The method `QueryParIter::for_each_unchecked` has been removed -- use
`for_each` or `for_each_mut` instead. If your use case can not be
achieved using either of these, then your code was likely unsound.
If you have a use-case for `for_each_unchecked` that you believe is
sound, please [open an
issue](https://github.com/bevyengine/bevy/issues/new/choose).
# Objective
`ComponentIdFor` is a type that gives you access to a component's
`ComponentId` in a system. It is currently awkward to use, since it must
be wrapped in a `Local<>` to be used.
## Solution
Make `ComponentIdFor` a proper SystemParam.
---
## Changelog
- Refactored the type `ComponentIdFor` in order to simplify how it is
used.
## Migration Guide
The type `ComponentIdFor<T>` now implements `SystemParam` instead of
`FromWorld` -- this means it should be used as the parameter for a
system directly instead of being used in a `Local`.
```rust
// Before:
fn my_system(
component_id: Local<ComponentIdFor<MyComponent>>,
) {
let component_id = **component_id;
}
// After:
fn my_system(
component_id: ComponentIdFor<MyComponent>,
) {
let component_id = component_id.get();
}
```
# Objective
Follow-up to #6404 and #8292.
Mutating the world through a shared reference is surprising, and it
makes the meaning of `&World` unclear: sometimes it gives read-only
access to the entire world, and sometimes it gives interior mutable
access to only part of it.
This is an up-to-date version of #6972.
## Solution
Use `UnsafeWorldCell` for all interior mutability. Now, `&World`
*always* gives you read-only access to the entire world.
---
## Changelog
TODO - do we still care about changelogs?
## Migration Guide
Mutating any world data using `&World` is now considered unsound -- the
type `UnsafeWorldCell` must be used to achieve interior mutability. The
following methods now accept `UnsafeWorldCell` instead of `&World`:
- `QueryState`: `get_unchecked`, `iter_unchecked`,
`iter_combinations_unchecked`, `for_each_unchecked`,
`get_single_unchecked`, `get_single_unchecked_manual`.
- `SystemState`: `get_unchecked_manual`
```rust
let mut world = World::new();
let mut query = world.query::<&mut T>();
// Before:
let t1 = query.get_unchecked(&world, entity_1);
let t2 = query.get_unchecked(&world, entity_2);
// After:
let world_cell = world.as_unsafe_world_cell();
let t1 = query.get_unchecked(world_cell, entity_1);
let t2 = query.get_unchecked(world_cell, entity_2);
```
The methods `QueryState::validate_world` and
`SystemState::matches_world` now take a `WorldId` instead of `&World`:
```rust
// Before:
query_state.validate_world(&world);
// After:
query_state.validate_world(world.id());
```
The methods `QueryState::update_archetypes` and
`SystemState::update_archetypes` now take `UnsafeWorldCell` instead of
`&World`:
```rust
// Before:
query_state.update_archetypes(&world);
// After:
query_state.update_archetypes(world.as_unsafe_world_cell_readonly());
```
# Objective
Implement borders for UI nodes.
Relevant discussion: #7785
Related: #5924, #3991
<img width="283" alt="borders"
src="https://user-images.githubusercontent.com/27962798/220968899-7661d5ec-6f5b-4b0f-af29-bf9af02259b5.PNG">
## Solution
Add an extraction function to draw the borders.
---
Can only do one colour rectangular borders due to the limitations of the
Bevy UI renderer.
Maybe it can be combined with #3991 eventually to add curved border
support.
## Changelog
* Added a component `BorderColor`.
* Added the `extract_uinode_borders` system to the UI Render App.
* Added the UI example `borders`
---------
Co-authored-by: Nico Burns <nico@nicoburns.com>
# Objective
The method `UnsafeWorldCell::read_change_tick` was renamed in #8588, but
I forgot to update a usage of this method in a doctest.
## Solution
Update the method call.
# Objective
To mirror the `Ref` added as `WorldQuery`, and the `Mut` in
`EntityMut::get_mut`, we add `EntityRef::get_ref`, which retrieves `T`
with tick information, but *immutably*.
## Solution
- Add the method in question, also add it to`UnsafeEntityCell` since
this seems to be the best way of getting that information.
Also update/add safety comments to neighboring code.
---
## Changelog
- Add `EntityRef::get_ref` to get an `Option<Ref<T>>` from `EntityRef`
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
The method `QueryState::par_iter` does not currently force the query to
be read-only. This means you can unsoundly mutate a world through an
immutable reference in safe code.
```rust
fn bad_system(world: &World, mut query: Local<QueryState<&mut T>>) {
query.par_iter(world).for_each_mut(|mut x| *x = unsoundness);
}
```
## Solution
Use read-only versions of the `WorldQuery` types.
---
## Migration Guide
The function `QueryState::par_iter` now forces any world accesses to be
read-only, similar to how `QueryState::iter` works. Any code that
previously mutated the world using this method was *unsound*. If you
need to mutate the world, use `par_iter_mut` instead.
# Objective
Make a combined system cloneable if both systems are cloneable on their
own. This is necessary for using chained conditions (e.g
`cond1.and_then(cond2)`) with `distributive_run_if()`.
## Solution
Implement `Clone` for `CombinatorSystem<Func, A, B>` where `A, B:
Clone`.
# Objective
- Fixes#8782
## Solution
- Call `init_resource` on `register_diagnostic` so that a
`DiagnosticStore` gets initialized if it does not exist.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
The `extract` function is given the main app world, and the subapp, not
vice versa as the comment would lead us to believe.
## Solution
Fix the doc.
# Objective
- Rename the `render::primitives::Plane` struct as to not confuse it
with `bevy_render::mesh::shape::Plane`
- Fixes https://github.com/bevyengine/bevy/issues/8730
## Solution
- Refactor the `render::primitives::Plane` struct to
`render::primitives::HalfSpace`
- Modify documentation to reflect this change
## Changelog
- Renamed `Plane` to `HalfSpace` to more accurately represent it's use
- Renamed `planes` member in `Frustum` to `half_spaces` to reflect
changes
## Migration Guide
- `Plane` has been renamed to `HalfSpace`
- `planes` member in `Frustum` has been renamed to `half_spaces`
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
# Objective
When browsing the bevy source code to try and learn about
`bevy_core_pipeline`, I noticed that the `DrawFunctions` resources,
`sort_phase_system`s and texture preparation for the `Opaque3d` and
`AlphaMask3d` phase items are all set up in `bevy_core_pipeline`, while
the `Opaque3dPrepass` and `AlphaMask3dPrepass` phase items are only
*declared* in `bevy_core_pipeline`, and actually registered properly
with the renderer in `bevy_pbr`.
This means that, if I am trying to make crate that replaces `bevy_pbr`,
I need to make sure I manually fix this unfinished setup the same way
that `bevy_pbr` does. Worse, it means that if I try to use the
`PrepassNode` `bevy_core_pipeline` adds *without* fixing this, the
engine will simply crash because the `DrawFunctions<T>` resources cannot
be accessed.
The only advantage I can think of for bevy doing it this way is an
ambiguous performance save due to the prepass render phases not being
present unless you are using prepass materials with PBR.
## Solution
I have moved the registration of `DrawFunctions<T>`,
`sort_phase_system::<T>`, camera `RenderPhase` extraction, and texture
preparation for prepass's phase items into `bevy_core_pipeline`
alongside the equivalent code that sets up the `Opaque3d`, `AlphaMask3d`
and `Transparent3d` phase items.
Am open to tweaking this to improve the performance impact of prepass
things being around if the app doesn't use them if needed.
I've tested that the `shader_prepass` example still works with this
change.
# Objective
EntityRef::get_change_ticks mentions that ComponentTicks is useful to
create change detection for your own runtime.
However, ComponentTicks doesn't even expose enough data to create
something that implements DetectChanges. Specifically, we need to be
able to extract the last change tick.
## Solution
We add a method to get the last change tick. We also add a method to get
the added tick.
## Changelog
- Add `last_changed_tick` and `added_tick` to `ComponentTicks`
# 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>
# Objective
- I can't map unsized type using `Ref::map` (for example `dyn Reflect`)
## Solution
- Allow unsized types (this is possible because `Ref` stores a reference
to `T`)
# Objective
`QueryState` exposes a `get_manual` and `iter_manual` method. However,
there is now `iter_many_manual`.
`iter_many_manual` is useful when you have a `&World` (eg: the `world`
in a `Scene`) and want to run a query several times on it (eg:
iteratively navigate a hierarchy by calling `iter_many` on `Children`
component).
`iter_many`'s need for a `&mut World` makes the API much less flexible.
The exclusive access pattern requires doing some very funky dance and
excludes a category of algorithms for hierarchy traversal.
## Solution
- Add a `iter_many_manual` method to `QueryState`
### Alternative
My current workaround is to use `get_manual`. However, this doesn't
benefit from the optimizations on `QueryManyIter`.
---
## Changelog
- Add a `iter_many_manual` method to `QueryState`
# Objective
Title.
---------
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
`Ref` is a useful way of accessing change detection data.
However, unlike `Mut`, it doesn't expose a constructor or even a way to
go from `Ref<A>` to `Ref<B>`.
Such methods could be useful, for example, to 3rd party crates that want
to expose change detection information in a clean way.
My use case is to map a `Ref<T>` into a `Ref<dyn Reflect>`, and keep
change detection info to avoid running expansive routines.
## Solution
We add the `new` and `map` methods. Since similar methods exist on `Mut`
where they are much more footgunny to use, I judged that it was
acceptable to create such methods.
## Workaround
Currently, it's not possible to create/project `Ref`s. One can define
their own `Ref` and implement `ChangeDetection` on it. One would then
use `ChangeTrackers` to populate the custom `Ref` with tick data.
---
## Changelog
- Added the `Ref::map` and `Ref::new` methods for more ergonomic `Ref`s
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
- Some reflect components weren't properly registered.
## Solution
- We register them
- I also sorted the register lines in `Plugin::build` in `bevy_ui`
### Note
How I did I find them:
- I picked up the list of `Component`s from the `Component` trait page
in rustdoc.
- Then I tried to register all of them. Removing the registration when
it doesn't implement `Reflect` to pass compilation.
- Then I added `app.register_type_data::<T, Foo>()`, for all Reflect
components. It panics if `T` is not registered.
- I repeated the last line N times until bevy stopped panicking at
startup
---
## Changelog
- Register the following components: `PrimaryWindow` `Fxaa`
`FogSettings` `NotShadowCaster` `NotShadowReceiver` `CalculatedClip`
`RelativeCursorPosition`
`AlphaMode` is not used as a component anywhere in the engine. It
shouldn't implement `Component`. It might mislead users into thinking it
has any effect as a component.
---
## Changelog
- Remove `Component` implementation for `AlphaMode`. It wasn't used by
anything.
## Migration Guide
`AlphaMode` is not a component anymore.
It wasn't used anywhere in the engine. If you were using it as a
component for your own purposes, you should use a newtype instead, as
follow:
```rust
#[derive(Component, Deref)]
struct MyAlphaMode(AlphaMode);
```
Then replace uses of `AlphaMode` with `MyAlphaMode`
```diff
- Query<&AlphaMode, …>,
+ Query<&MyAlphaMode, …>,
```
# Objective
- When a window is closed, the associated camera keeps rendering even if
the RenderTarget isn't valid anymore.
- This is essentially just wasting a lot of performance.
## Solution
- Detect the window close event and disable any camera that used the
window has a RenderTarget.
## Notes
It's possible a similar thing could be done for camera that use an image
handle, but I would fix that in a separate PR.
# Objective
`NoFrustumCulling` doesn't implement `Reflect`, while nothing prevents
it from implementing it.
## Solution
Implement `Reflect` for it.
---
## Changelog
- Add `Reflect` derive to `NoFrustrumCulling`.
- Add `FromReflect` derive to `Visibility`.
# Objective
This calculation is performed componentwise but all the values are
vectors so it should be using vector operations.
Works correctly with the `relative_cursor_position` example.
# Objective
To upgrade winit's dependency, it's useful to reuse SmolStr, which
replaces/improves the too restrictive Key letter enums.
As Input<Key> is a resource it should implement Reflect through all its
fields.
## Solution
Add smol_str to bevy_reflect supported types, behind a feature flag.
This PR blocks winit's upgrade PR:
https://github.com/bevyengine/bevy/pull/8745.
# Current state
- I'm discovering bevy_reflect, I appreciate all feedbacks, and send me
your nitpicks!
- Lacking more tests
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
The goal of this PR is to receive touchpad magnification and rotation
events.
## Solution
Implement pendants for winit's `TouchpadMagnify` and `TouchpadRotate`
events.
Adjust the `mouse_input_events.rs` example to debug magnify and rotate
events.
Since winit only reports these events on macOS, the Bevy events for
touchpad magnification and rotation are currently only fired on macOS.
Updates the requirements on
[notify](https://github.com/notify-rs/notify) to permit the latest
version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/notify-rs/notify/blob/main/CHANGELOG.md">notify's
changelog</a>.</em></p>
<blockquote>
<h2>notify 6.0.0 (2023-05-17)</h2>
<ul>
<li>CHANGE: files and directories moved into a watch folder on Linux
will now be reported as <code>rename to</code> events instead of
<code>create</code> events <a
href="https://redirect.github.com/notify-rs/notify/issues/480">#480</a></li>
<li>CHANGE: on Linux <code>rename from</code> events will be emitted
immediately without starting a new thread <a
href="https://redirect.github.com/notify-rs/notify/issues/480">#480</a></li>
<li>CHANGE: raise MSRV to 1.60 <a
href="https://redirect.github.com/notify-rs/notify/issues/480">#480</a></li>
</ul>
<h2>debouncer-mini 0.3.0 (2023-05-17)</h2>
<ul>
<li>CHANGE: upgrade to notify 6.0.0, pushing MSRV to 1.60 <a
href="https://redirect.github.com/notify-rs/notify/issues/480">#480</a></li>
</ul>
<h2>debouncer-full 0.1.0 (2023-05-17)</h2>
<p>Newly introduced alternative debouncer with more features. <a
href="https://redirect.github.com/notify-rs/notify/issues/480">#480</a></p>
<ul>
<li>FEATURE: only emit a single <code>rename</code> event if the rename
<code>From</code> and <code>To</code> events can be matched</li>
<li>FEATURE: merge multiple <code>rename</code> events</li>
<li>FEATURE: keep track of the file system IDs all files and stiches
rename events together (FSevents, Windows)</li>
<li>FEATURE: emit only one <code>remove</code> event when deleting a
directory (inotify)</li>
<li>FEATURE: don't emit duplicate create events</li>
<li>FEATURE: don't emit <code>Modify</code> events after a
<code>Create</code> event</li>
</ul>
<p><a
href="https://redirect.github.com/notify-rs/notify/issues/480">#480</a>:
<a
href="https://redirect.github.com/notify-rs/notify/pull/480">notify-rs/notify#480</a></p>
<h2>notify 5.2.0 (2023-05-17)</h2>
<ul>
<li>CHANGE: implement <code>Copy</code> for <code>EventKind</code> and
<code>ModifyKind</code> <a
href="https://redirect.github.com/notify-rs/notify/issues/481">#481</a></li>
</ul>
<p><a
href="https://redirect.github.com/notify-rs/notify/issues/481">#481</a>:
<a
href="https://redirect.github.com/notify-rs/notify/pull/481">notify-rs/notify#481</a></p>
<h2>notify 5.1.0 (2023-01-15)</h2>
<ul>
<li>CHANGE: switch from winapi to windows-sys <a
href="https://redirect.github.com/notify-rs/notify/issues/457">#457</a></li>
<li>FIX: kqueue-backend: batch file-watching together to improve
performance <a
href="https://redirect.github.com/notify-rs/notify/issues/454">#454</a></li>
<li>DOCS: include license file in crate again <a
href="https://redirect.github.com/notify-rs/notify/issues/461">#461</a></li>
<li>DOCS: typo and examples fixups</li>
</ul>
<p><a
href="https://redirect.github.com/notify-rs/notify/issues/454">#454</a>:
<a
href="https://redirect.github.com/notify-rs/notify/pull/454">notify-rs/notify#454</a>
<a
href="https://redirect.github.com/notify-rs/notify/issues/461">#461</a>:
<a
href="https://redirect.github.com/notify-rs/notify/pull/461">notify-rs/notify#461</a>
<a
href="https://redirect.github.com/notify-rs/notify/issues/457">#457</a>:
<a
href="https://redirect.github.com/notify-rs/notify/pull/457">notify-rs/notify#457</a></p>
<h2>debouncer-mini 0.2.1 (2022-09-05)</h2>
<ul>
<li>DOCS: correctly document the <code>crossbeam</code> feature <a
href="https://redirect.github.com/notify-rs/notify/issues/440">#440</a></li>
</ul>
<p><a
href="https://redirect.github.com/notify-rs/notify/issues/440">#440</a>:
<a
href="https://redirect.github.com/notify-rs/notify/pull/440">notify-rs/notify#440</a></p>
<h2>debouncer-mini 0.2.0 (2022-08-30)</h2>
<p>Upgrade notify dependency to 5.0.0</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/notify-rs/notify/commits">compare view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on
[ruzstd](https://github.com/KillingSpark/zstd-rs) to permit the latest
version.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/KillingSpark/zstd-rs/releases">ruzstd's
releases</a>.</em></p>
<blockquote>
<h2>No-std support and better dict API</h2>
<p>This release features no-std support with big thanks to <a
href="https://github.com/antangelo"><code>@antangelo</code></a>!</p>
<p>Also the API for dictionaries has been revised, which required some
breaking changes in that department</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fa7bd9c7b3"><code>fa7bd9c</code></a>
allow streaming decoder to also be used with a &mut FrameDecoder for
easier r...</li>
<li><a
href="3b6403b8e7"><code>3b6403b</code></a>
reenable forcing a different dict</li>
<li><a
href="2be7fbb01b"><code>2be7fbb</code></a>
Merge pull request <a
href="https://redirect.github.com/KillingSpark/zstd-rs/issues/40">#40</a>
from KillingSpark/overhaul_dicts</li>
<li><a
href="343d69b339"><code>343d69b</code></a>
no need to check that the dict still matches at the start of each decode
call</li>
<li><a
href="d73f5e689a"><code>d73f5e6</code></a>
cargo fmt</li>
<li><a
href="f3f09c76f0"><code>f3f09c7</code></a>
improve initing the decoder from a dict</li>
<li><a
href="0b9331dd19"><code>0b9331d</code></a>
make clippy happy</li>
<li><a
href="06433dec34"><code>06433de</code></a>
start overhauling dict API</li>
<li><a
href="1256944604"><code>1256944</code></a>
Update ci.yml</li>
<li><a
href="3449d0a2bf"><code>3449d0a</code></a>
Merge pull request <a
href="https://redirect.github.com/KillingSpark/zstd-rs/issues/39">#39</a>
from antangelo/no_std</li>
<li>Additional commits viewable in <a
href="https://github.com/KillingSpark/zstd-rs/compare/v0.3.1...v0.4.0">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Followup to #7184
This makes `Reflect: DynamicTypePath` which allows us to remove
`Reflect::get_type_path`, reducing unnecessary codegen and simplifying
`Reflect` implementations.
# Objective
Be consistent with `Resource`s and `Components` and have `Event` types
be more self-documenting.
Although not susceptible to accidentally using a function instead of a
value due to `Event`s only being initialized by their type, much of the
same reasoning for removing the blanket impl on `Resource` also applies
here.
* Not immediately obvious if a type is intended to be an event
* Prevent invisible conflicts if the same third-party or primitive types
are used as events
* Allows for further extensions (e.g. opt-in warning for missed events)
## Solution
Remove the blanket impl for the `Event` trait. Add a derive macro for
it.
---
## Changelog
- `Event` is no longer implemented for all applicable types. Add the
`#[derive(Event)]` macro for events.
## Migration Guide
* Add the `#[derive(Event)]` macro for events. Third-party types used as
events should be wrapped in a newtype.
# Objective
It was accidentally found that rustc is unable to parse certain
constructs in `where` clauses properly. `bevy_reflect::Reflect`'s habit
of copying and pasting the field types in a type's definition to its
`where` clauses made it very easy to accidentally run into this
behaviour - particularly with the construct
```rust
where
for<'a> fn(&'a T) -> &'a T: Trait1 + Trait2
```
which was incorrectly parsed as
```rust
where
for<'a> (fn(&'a T) -> &'a T: Trait1 + Trait2)
^ ^ incorrect syntax grouping
```
instead of
```rust
where
(for<'a> fn(&'a T) -> &'a T): Trait1 + Trait2
^ ^ correct syntax grouping
```
Fixes#8759
## Solution
This commit fixes the issue by inserting explicit parentheses to
disambiguate types from their bound lists.
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/8586.
## Solution
- Add `preferred_theme` field to `Window` and set it when window
creation
- Add `window_theme` field to `InternalWindowState` to store current
window theme
- Expose winit `WindowThemeChanged` event
---------
Co-authored-by: hate <15314665+hate@users.noreply.github.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
Fixes#8751
## Solution
The doc string for the `primary_window` field on `Window` now mentions
that the default spawned primary window is spawned with the
`PrimaryWindow` marker component.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
- Fix#8658
- `without_winit` example panics `thread 'Compute Task Pool (2)'
panicked at 'called `Option::unwrap()` on a `None` value',
crates/bevy_render/src/pipelined_rendering.rs:134:84`
## Solution
- In the default runner method `run_once`, correctly finish the
initialisation of the plugins. `run_once` can't be called twice so it's
ok to do it there
# Objective
I was trying to add some `Diagnostics` to have a better break down of
performance but I noticed that the current implementation uses a
`ResMut` which forces the functions to all run sequentially whereas
before they could run in parallel. This created too great a performance
penalty to be usable.
## Solution
This PR reworks how the diagnostics work with a couple of breaking
changes. The idea is to change how `Diagnostics` works by changing it to
a `SystemParam`. This allows us to hold a `Deferred` buffer of
measurements that can be applied later, avoiding the need for multiple
mutable references to the hashmap. This means we can run systems that
write diagnostic measurements in parallel.
Firstly, we rename the old `Diagnostics` to `DiagnosticsStore`. This
clears up the original name for the new interface while allowing us to
preserve more closely the original API.
Then we create a new `Diagnostics` struct which implements `SystemParam`
and contains a deferred `SystemBuffer`. This can be used very similar to
the old `Diagnostics` for writing new measurements.
```rust
fn system(diagnostics: ResMut<Diagnostics>) { diagnostics.new_measurement(ID, || 10.0)}
// changes to
fn system(mut diagnostics: Diagnostics) { diagnostics.new_measurement(ID, || 10.0)}
```
For reading the diagnostics, the user needs to change from `Diagnostics`
to `DiagnosticsStore` but otherwise the function calls are the same.
Finally, we add a new method to the `App` for registering diagnostics.
This replaces the old method of creating a startup system and adding it
manually.
Testing it, this PR does indeed allow Diagnostic systems to be run in
parallel.
## Changelog
- Change `Diagnostics` to implement `SystemParam` which allows
diagnostic systems to run in parallel.
## Migration Guide
- Register `Diagnostic`'s using the new
`app.register_diagnostic(Diagnostic::new(DIAGNOSTIC_ID,
"diagnostic_name", 10));`
- In systems for writing new measurements, change `mut diagnostics:
ResMut<Diagnostics>` to `mut diagnostics: Diagnostics` to allow the
systems to run in parallel.
- In systems for reading measurements, change `diagnostics:
Res<Diagnostics>` to `diagnostics: Res<DiagnosticsStore>`.
# Objective
- Introduce a stable alternative to
[`std::any::type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html).
- Rewrite of #5805 with heavy inspiration in design.
- On the path to #5830.
- Part of solving #3327.
## Solution
- Add a `TypePath` trait for static stable type path/name information.
- Add a `TypePath` derive macro.
- Add a `impl_type_path` macro for implementing internal and foreign
types in `bevy_reflect`.
---
## Changelog
- Added `TypePath` trait.
- Added `DynamicTypePath` trait and `get_type_path` method to `Reflect`.
- Added a `TypePath` derive macro.
- Added a `bevy_reflect::impl_type_path` for implementing `TypePath` on
internal and foreign types in `bevy_reflect`.
- Changed `bevy_reflect::utility::(Non)GenericTypeInfoCell` to
`(Non)GenericTypedCell<T>` which allows us to be generic over both
`TypeInfo` and `TypePath`.
- `TypePath` is now a supertrait of `Asset`, `Material` and
`Material2d`.
- `impl_reflect_struct` needs a `#[type_path = "..."]` attribute to be
specified.
- `impl_reflect_value` needs to either specify path starting with a
double colon (`::core::option::Option`) or an `in my_crate::foo`
declaration.
- Added `bevy_reflect_derive::ReflectTypePath`.
- Most uses of `Ident` in `bevy_reflect_derive` changed to use
`ReflectTypePath`.
## Migration Guide
- Implementors of `Asset`, `Material` and `Material2d` now also need to
derive `TypePath`.
- Manual implementors of `Reflect` will need to implement the new
`get_type_path` method.
## Open Questions
- [x] ~This PR currently does not migrate any usages of
`std::any::type_name` to use `bevy_reflect::TypePath` to ease the review
process. Should it?~ Migration will be left to a follow-up PR.
- [ ] This PR adds a lot of `#[derive(TypePath)]` and `T: TypePath` to
satisfy new bounds, mostly when deriving `TypeUuid`. Should we make
`TypePath` a supertrait of `TypeUuid`? [Should we remove `TypeUuid` in
favour of
`TypePath`?](2afbd85532 (r961067892))
# Objective
- Continue with #8685 to make `TonyMcMapface` the default tonemapping
## Solution
- Change the default value `Camera3dBundle::tonemapping` from
`Tonemapping::ReinhardLuminance` to `Default::default()`
(`Tonemapping::TonyMcMapface`)
# Objective
- `apply_system_buffers` is an unhelpful name: it introduces a new
internal-only concept
- this is particularly rough for beginners as reasoning about how
commands work is a critical stumbling block
## Solution
- rename `apply_system_buffers` to the more descriptive `apply_deferred`
- rename related fields, arguments and methods in the internals fo
bevy_ecs for consistency
- update the docs
## Changelog
`apply_system_buffers` has been renamed to `apply_deferred`, to more
clearly communicate its intent and relation to `Deferred` system
parameters like `Commands`.
## Migration Guide
- `apply_system_buffers` has been renamed to `apply_deferred`
- the `apply_system_buffers` method on the `System` trait has been
renamed to `apply_deferred`
- the `is_apply_system_buffers` function has been replaced by
`is_apply_deferred`
- `Executor::set_apply_final_buffers` is now
`Executor::set_apply_final_deferred`
- `Schedule::apply_system_buffers` is now `Schedule::apply_deferred`
---------
Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
# Objective
Fixes#8596
## Solution
Change interface of the trait Map. Adjust implementations of this trait
---
## Changelog
### Changed
- Interface of Map trait
### Added
- `Map::get_at_mut`
## Migration Guide
Every implementor of Map trait would need to implement `get_at_mut`.
Which, judging by changes in this PR, should be fairly trivial.
- Supress false positive `redundant_clone` lints.
- Supress inactionable `result_large_err` lint.
Most of the size(50 out of 68 bytes) is coming from
`naga::WithSpan<naga::valid::ValidationError>`
# Objective
- Make the dependency job successful again
## Solution
- Update the list of duplicates
- Remove a security issue exception not needed anymore
- Also update a dependency that was missed by dependabot
# Objective
Right now it's impossible to construct a MapIter outside of the
bevy_reflect crate, making it impossible to implement the Map trait for
custom map types.
## Solution
Addition of a pub constructor to MapIter.
Updates the requirements on
[android_log-sys](https://github.com/nercury/android_log-sys-rs) to
permit the latest version.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/nercury/android_log-sys-rs/commits">compare
view</a></li>
</ul>
</details>
<br />
You can trigger a rebase of this PR by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Objective
The `Condition` trait is only implemented for systems and system
functions that take no input. This can make it awkward to write
conditions that are intended to be used with system piping.
## Solution
Add an `In` generic to the trait. It defaults to `()`.
---
## Changelog
- Made the `Condition` trait generic over system inputs.
# Objective
- Fix Wayland window client side decorations issue on Gnome Wayland,
fixes#3301.
## Solution
- One simple one line solution: Add winit's `wayland-csd-adwaita`
feature to Bevy's `wayland` feature.
Copied from
https://github.com/bevyengine/bevy/issues/3301#issuecomment-1569611257:
### Investigation
1. Gnome forced Wayland apps to implement CSD, whether on their own or
using some libraries like Gnome's official solution
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor). Many Linux
apps do this with libdecor, like blender, kitty... I think it's not
comfortable for Bevy to fix this problem this way.
2. Winit has support for CSD on
wayland(8bb004a1d9/Cargo.toml (L42)),
but Bevy disabled Winit's default features, thus no winit's
`wayland-csd-adwaita` feature. And Bevy's `wayland` feature doesn't
include winit's `wayland-csd-adwaita` feature so users can't get window
decorations on Wayland even with Bevy's `wayland` feature enabled.
3. Many rust UI toolkit, like iced, doesn't disable winit's
`wayland-csd-adwaita` feature.
### Conclusion and one Possible solution
Bevy disabled `winit`'s default features in order to decrease package
size. But I think it's acceptable to add `winit`'s `wayland-csd-adwaita`
feature to Bevy's `wayland` feature gate to fix this issue easily for
this only add on crate: sctk-adwaita.
# Objective
Several of our built-in `Command` types are too public:
- `GetOrSpawn` is public, even though it only makes sense to call it
from within `Commands::get_or_spawn`.
- `Remove` and `RemoveResource` contain public `PhantomData` marker
fields.
## Solution
Remove `GetOrSpawn` and use an anonymous command. Make the marker fields
private.
---
## Migration Guide
The `Command` types `Remove` and `RemoveResource` may no longer be
constructed manually.
```rust
// Before:
commands.add(Remove::<T> {
entity: id,
phantom: PhantomData,
});
// After:
commands.add(Remove::<T>::new(id));
// Before:
commands.add(RemoveResource::<T> { phantom: PhantomData });
// After:
commands.add(RemoveResource::<T>::new());
```
The command type `GetOrSpawn` has been removed. It was not possible to
use this type outside of `bevy_ecs`.
## Objective
- Provide a way to use `CubicCurve` non-iter methods
- Accept a `FnMut` over a `fn` pointer on `iter_samples`
- Improve `build_*_cubic_100_points` benchmark by -45% (this means they
are twice as fast)
### Solution
Previously, the only way to iterate over an evenly spaced set of points
on a `CubicCurve` was to use one of the `iter_*` methods.
The return value of those methods were bound by `&self` lifetime, making
them unusable in certain contexts.
Furthermore, other `CubicCurve` methods (`position`, `velocity`,
`acceleration`) required normalizing `t` over the `CubicCurve`'s
internal segment count.
There were no way to access this segment count, making those methods
pretty much unusable.
The newly added `segment_count` allows accessing the segment count.
`iter_samples` used to accept a `fn`, a function pointer. This is
surprising and contrary to the rust stdlib APIs, which accept `Fn`
traits for `Iterator` combinators.
`iter_samples` now accepts a `FnMut`.
I don't trust a bit the bevy benchmark suit, but according to it, this
doubles (-45%) the performance on the `build_pos_cubic_100_points` and
`build_accel_cubic_100_points` benchmarks.
---
## Changelog
- Added the `CubicCurve::segments` method to access the underlying
segments of a cubic curve
- Allow closures as `CubicCurve::iter_samples` `sample_function`
argument.
# Objective
Add documentation to `Query` and `QueryState` errors in bevy_ecs
(`QuerySingleError`, `QueryEntityError`, `QueryComponentError`)
## Solution
- Change display message for `QueryEntityError::QueryDoesNotMatch`: this
error can also happen when the entity has a component which is filtered
out (with `Without<C>`)
- Fix wrong reference in the documentation of `Query::get_component` and
`Query::get_component_mut` from `QueryEntityError` to
`QueryComponentError`
- Complete the documentation of the three error enum variants.
- Add examples for `QueryComponentError::MissingReadAccess` and
`QueryComponentError::MissingWriteAccess`
- Add reference to `QueryState` in `QueryEntityError`'s documentation.
---
## Migration Guide
Expect `QueryEntityError::QueryDoesNotMatch`'s display message to
change? Not sure that counts.
---------
Co-authored-by: harudagondi <giogdeasis@gmail.com>
# Objective
- Make #8015 easier to review;
## Solution
- This commit contains changes not directly related to transmission
required by #8015, in easier-to-review, one-change-per-commit form.
---
## Changelog
### Fixed
- Clear motion vector prepass using `0.0` instead of `1.0`, to avoid TAA
artifacts on transparent objects against the background;
### Added
- The `E` mathematical constant is now available for use in shaders,
exposed under `bevy_pbr::utils`;
- A new `TAA` shader def is now available, for conditionally enabling
shader logic via `#ifdef` when TAA is enabled; (e.g. for jittering
texture samples)
- A new `FallbackImageZero` resource is introduced, for when a fallback
image filled with zeroes is required;
- A new `RenderPhase<I>::render_range()` method is introduced, for
render phases that need to render their items in multiple parceled out
“steps”;
### Changed
- The `MainTargetTextures` struct now holds both `Texture` and
`TextureViews` for the main textures;
- The fog shader functions under `bevy_pbr::fog` now take the a `Fog`
structure as their first argument, instead of relying on the global
`fog` uniform;
- The main textures can now be used as copy sources;
## Migration Guide
- `ViewTarget::main_texture()` and `ViewTarget::main_texture_other()`
now return `&Texture` instead of `&TextureView`. If you were relying on
these methods, replace your usage with
`ViewTarget::main_texture_view()`and
`ViewTarget::main_texture_other_view()`, respectively;
- `ViewTarget::sampled_main_texture()` now returns `Option<&Texture>`
instead of a `Option<&TextureView>`. If you were relying on this method,
replace your usage with `ViewTarget::sampled_main_texture_view()`;
- The `apply_fog()`, `linear_fog()`, `exponential_fog()`,
`exponential_squared_fog()` and `atmospheric_fog()` functions now take a
configurable `Fog` struct. If you were relying on them, update your
usage by adding the global `fog` uniform as their first argument;
Change the default tonemapping method from ReinhardLuminance to
TonyMcMapface, which generally looks nicer and works out of the box with
bloom.
---
## Changelog
- TonyMcMapface is now the default tonemapper, instead of
ReinhardLuminance.
## Migration Guide
- The default tonemapper has been changed from ReinhardLuminance to
TonyMcMapface. Explicitly set ReinhardLuminance on your cameras to get
back the previous look.
# Objective
When using `FromReflect`, fields can be optionally left out if they are
marked with `#[reflect(default)]`. This is very handy for working with
serialized data as giant structs only need to list a subset of defined
fields in order to be constructed.
<details>
<summary>Example</summary>
Take the following struct:
```rust
#[derive(Reflect, FromReflect)]
struct Foo {
#[reflect(default)]
a: usize,
#[reflect(default)]
b: usize,
#[reflect(default)]
c: usize,
#[reflect(default)]
d: usize,
}
```
Since all the fields are default-able, we can successfully call
`FromReflect` on deserialized data like:
```rust
(
"foo::Foo": (
// Only set `b` and default the rest
b: 123
)
)
```
</details>
Unfortunately, this does not work with fields in enum variants. Marking
a variant field as `#[reflect(default)]` does nothing when calling
`FromReflect`.
## Solution
Allow enum variant fields to define a default value using
`#[reflect(default)]`.
### `#[reflect(Default)]`
One thing that structs and tuple structs can do is use their `Default`
implementation when calling `FromReflect`. Adding `#[reflect(Default)]`
to the struct or tuple struct both registers `ReflectDefault` and alters
the `FromReflect` implementation to use `Default` to generate any
missing fields.
This works well enough for structs and tuple structs, but for enums it's
not as simple. Since the `Default` implementation for an enum only
covers a single variant, it's not as intuitive as to what the behavior
will be. And (imo) it feels weird that we would be able to specify
default values in this way for one variant but not the others.
Because of this, I chose to not implement that behavior here. However,
I'm open to adding it in if anyone feels otherwise.
---
## Changelog
- Allow enum variant fields to define a default value using
`#[reflect(default)]`
# Objective
Fix#7833.
Safety comments in the multi-threaded executor don't really talk about
system world accesses, which makes it unclear if the code is actually
valid.
## Solution
Update the `System` trait to use `UnsafeWorldCell`. This type's API is
written in a way that makes it much easier to cleanly maintain safety
invariants. Use this type throughout the multi-threaded executor, with a
liberal use of safety comments.
---
## Migration Guide
The `System` trait now uses `UnsafeWorldCell` instead of `&World`. This
type provides a robust API for interior mutable world access.
- The method `run_unsafe` uses this type to manage world mutations
across multiple threads.
- The method `update_archetype_component_access` uses this type to
ensure that only world metadata can be used.
```rust
let mut system = IntoSystem::into_system(my_system);
system.initialize(&mut world);
// Before:
system.update_archetype_component_access(&world);
unsafe { system.run_unsafe(&world) }
// After:
system.update_archetype_component_access(world.as_unsafe_world_cell_readonly());
unsafe { system.run_unsafe(world.as_unsafe_world_cell()) }
```
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Right now we can't really benefit from [early depth
testing](https://www.khronos.org/opengl/wiki/Early_Fragment_Test) in our
PBR shader because it includes codepaths with `discard`, even for
situations where they are not necessary.
## Solution
- This PR introduces a new `MeshPipelineKey` and shader def,
`MAY_DISCARD`;
- All possible material/mesh options that that may result in `discard`s
being needed must set `MAY_DISCARD` ahead of time:
- Right now, this is only `AlphaMode::Mask(f32)`, but in the future
might include other options/effects; (e.g. one effect I'm personally
interested in is bayer dither pseudo-transparency for LOD transitions of
opaque meshes)
- Shader codepaths that can `discard` are guarded by an `#ifdef
MAY_DISCARD` preprocessor directive:
- Right now, this is just one branch in `alpha_discard()`;
- If `MAY_DISCARD` is _not_ set, the `@early_depth_test` attribute is
added to the PBR fragment shader. This is a not yet documented, possibly
non-standard WGSL extension I found browsing Naga's source code. [I
opened a PR to document it
there](https://github.com/gfx-rs/naga/pull/2132). My understanding is
that for backends where this attribute is supported, it will force an
explicit opt-in to early depth test. (e.g. via
`layout(early_fragment_tests) in;` in GLSL)
## Caveats
- I included `@early_depth_test` for the sake of us being explicit, and
avoiding the need for the driver to be “smart” about enabling this
feature. That way, if we make a mistake and include a `discard`
unguarded by `MAY_DISCARD`, it will either produce errors or noticeable
visual artifacts so that we'll catch early, instead of causing a
performance regression.
- I'm not sure explicit early depth test is supported on the naga Metal
backend, which is what I'm currently using, so I can't really test the
explicit early depth test enable, I would like others with Vulkan/GL
hardware to test it if possible;
- I would like some guidance on how to measure/verify the performance
benefits of this;
- If I understand it correctly, this, or _something like this_ is needed
to fully reap the performance gains enabled by #6284;
- This will _most definitely_ conflict with #6284 and #6644. I can fix
the conflicts as needed, depending on whether/the order they end up
being merging in.
---
## Changelog
### Changed
- Early depth tests are now enabled whenever possible for meshes using
`StandardMaterial`, reducing the number of fragments evaluated for
scenes with lots of occlusions.
# Objective
Fix#8604
## Solution
Use `.add_srgb_suffix()` when creating the screenshot texture.
Allow converting `Bgra8Unorm` images.
Only a two line change for the fix, the `screenshot.rs` changes are just
a bit of cleanup.
# Objective
Fix warnings:
```rs
warning: variable does not need to be mutable
--> /bevy/crates/bevy_app/src/plugin_group.rs:147:13
|
147 | let mut plugin_entry = self
| ----^^^^^^^^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
warning: variable does not need to be mutable
--> /bevy/crates/bevy_app/src/plugin_group.rs:161:13
|
161 | let mut plugin_entry = self
| ----^^^^^^^^^^^^
| |
| help: remove this `mut`
warning: `bevy_app` (lib) generated 2 warnings (run `cargo fix --lib -p bevy_app` to apply 2 suggestions)
warning: variable does not need to be mutable
--> /bevy/crates/bevy_render/src/view/window.rs:126:13
|
126 | ... let mut extracted_window = extracted_windows.entry(entity).or_insert(Extracte...
| ----^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_mut)]` on by default
warning: `bevy_render` (lib) generated 1 warning (run `cargo fix --lib -p bevy_render` to apply 1 suggestion)
```
## Solution
- Remove the mut keyword in those variables.
# Objective
Reduce missing docs warning noise when building examples for wasm
## Solution
Added "#[allow(missing_docs)]" on the wasm specific version of
BoxedFuture
# Objective
- Allow for directly call methods on states without first calling
`state.get().my_method()`
## Solution
- Implement `Deref` for `State<S>` with `Target = S`
---
*I did not implement `DerefMut` because states hold no data and should
only be changed via `NextState::set()`*
# Objective
- If I understand correctly, forward points in `direction`, so the
negative of `direction` should be back.
## Migration Guide
- `Transform::look_to` method changed default value of
`direction.try_normalize()` from `Vec3::Z` to `Vec3::NEG_Z`
# Objective
- Since the `RequestRedraw` event triggers the bevy app to run `update`
in `bevy_app::app::App`, the documentation should state that all the
windows in the application and its sub-apps are going to get redrawn,
rather than a single window.
## Solution
- Change `RequestRedraw` documentation in `bevy_window` to mention every
window.
# Objective
Make `Material2dPipeline` reusable. This was already done for PBR
materials in #7548.
## Solution
Expose `extract_materials_2d`, `prepare_materials_2d` and
`ExtractedMaterials2d`.
---
## Changelog
- bevy_sprite: Make `prepare_materials_2d`, `extract_materials_2d` and
`ExtractedMaterials2d` public.
Updates the requirements on
[libloading](https://github.com/nagisa/rust_libloading) to permit the
latest version.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="83b1037f21"><code>83b1037</code></a>
Release 0.8.0</li>
<li><a
href="a6a394a7ef"><code>a6a394a</code></a>
bump MSRV to 1.48</li>
<li><a
href="c7955a761e"><code>c7955a7</code></a>
Replace winapi with windows-sys</li>
<li><a
href="95d03a1ddf"><code>95d03a1</code></a>
Add support for QNX Neutrino</li>
<li><a
href="6e284984ae"><code>6e28498</code></a>
Fix CI</li>
<li><a
href="95a0f62e8f"><code>95a0f62</code></a>
Placate clippy</li>
<li><a
href="224a3def35"><code>224a3de</code></a>
Release 0.7.4</li>
<li><a
href="bd17713dcc"><code>bd17713</code></a>
Support AIX dyld constants</li>
<li><a
href="6e07929736"><code>6e07929</code></a>
fix typo</li>
<li><a
href="6b33651a90"><code>6b33651</code></a>
Construct a PathBuf</li>
<li>Additional commits viewable in <a
href="https://github.com/nagisa/rust_libloading/compare/0.7.0...0.8.0">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on
[sysinfo](https://github.com/GuillaumeGomez/sysinfo) to permit the
latest version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/GuillaumeGomez/sysinfo/blob/master/CHANGELOG.md">sysinfo's
changelog</a>.</em></p>
<blockquote>
<h1>0.29.0</h1>
<ul>
<li>Add <code>ProcessExt::effective_user_id</code> and
<code>ProcessExt::effective_group_id</code>.</li>
<li>Rename <code>DiskType</code> into <code>DiskKind</code>.</li>
<li>Rename <code>DiskExt::type_</code> into
<code>DiskExt::kind</code>.</li>
<li>macOS: Correctly handle <code>ProcessStatus</code> and remove public
<code>ThreadStatus</code> field.</li>
<li>Windows 11: Fix CPU core usage.</li>
</ul>
<h1>0.28.4</h1>
<ul>
<li>macOS: Improve CPU computation.</li>
<li>Strengthen a process test (needed for debian).</li>
</ul>
<h1>0.28.3</h1>
<ul>
<li>FreeBSD/Windows: Add missing frequency for global CPU.</li>
<li>macOS: Fix used memory computation.</li>
<li>macOS: Improve available memory computation.</li>
<li>Windows: Fix potential panic when getting process data.</li>
</ul>
<h1>0.28.2</h1>
<ul>
<li>Linux: Improve CPU usage computation.</li>
</ul>
<h1>0.28.1</h1>
<ul>
<li>macOS: Fix overflow when computing CPU usage.</li>
</ul>
<h1>0.28.0</h1>
<ul>
<li>Linux: Fix name and CPU usage for processes tasks.</li>
<li>unix: Keep all users, even "not real" accounts.</li>
<li>Windows: Use SID for Users ID.</li>
<li>Fix C API.</li>
<li>Disable default cdylib compilation.</li>
<li>Add <code>serde</code> feature to enable serialization.</li>
<li>Linux: Handle <code>Idle</code> state in
<code>ProcessStatus</code>.</li>
<li>Linux: Add brand and name of ARM CPUs.</li>
</ul>
<h1>0.27.8</h1>
<ul>
<li>macOS: Fix overflow when computing CPU usage.</li>
</ul>
<h1>0.27.7</h1>
<ul>
<li>macOS: Fix process CPU usage computation</li>
<li>Linux: Improve ARM CPU <code>brand</code> and <code>name</code>
information.</li>
<li>Windows: Fix resource leak.</li>
<li>Documentation improvements.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/GuillaumeGomez/sysinfo/commits">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Objective
- Fixes#7352
## Solution
GLES doesn't support binding specific mip levels for sampling. Fallback
to using separate textures instead.
-
[wgpu-hal/src/gles/device.rs](628a95cd1c/wgpu-hal/src/gles/device.rs (L1038))
---
---------
Co-authored-by: Wilhelm Vallrand <>
# Objective
This method has no documentation and it's extremely unclear what it
does, or what the returned tick represents.
## Solution
Write documentation.
# Objective
- Update dependencies `ruzstd` and `basis-universal`
- Alternative to #5278 and #8133
## Solution
- Update the dependencies, fix the code
- Bevy now also depend on `syn@2` so it's not a blocker to update
`ruzstd` anymore
# Objective
Fix an out-of-date doc string.
The old doc string says "returns None if …" and "for a given
descriptor",
but this method neither takes an argument or returns an `Option`.
# Objective
Add support for the [Netpbm](https://en.wikipedia.org/wiki/Netpbm) image
formats, behind a `pnm` feature flag.
My personal use case for this was robotics applications, with `pgm`
being a popular format used in the field to represent world maps in
robots.
I chose the formats and feature name by checking the logic in
[image.rs](a35ed552fa/crates/bevy_render/src/texture/image.rs (L76))
## Solution
Quite straightforward, the `pnm` feature flag already exists in the
`image` crate so it's just creating and exposing a `pnm` feature flag in
the root `Cargo.toml` and forwarding it through `bevy_internal` and
`bevy_render` all the way to the `image` crate.
---
## Changelog
### Added
`pnm` feature to add support for `pam`, `pbm`, `pgm` and `ppm` image
formats.
---------
Signed-off-by: Luca Della Vedova <lucadv@intrinsic.ai>
# 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
The unit test `chang_tick_wraparound` is meant to ensure that change
ticks correctly deal with wrapping by setting the world's
`last_change_tick` to `u32::MAX`. However, since systems don't use* the
value of `World::last_change_tick`, this test doesn't actually involve
any wrapping behavior.
*exclusive systems do use `World::last_change_tick`; however it gets
overwritten by the system's own last tick in `System::run`.
## Solution
Use `QueryState` instead of systems in the unit test. This approach
actually uses `World::last_change_tick`, so it properly tests that
change ticks deal with wrapping correctly.
# Objective
- Simplify API and make authoring styles easier
See:
https://github.com/bevyengine/bevy/issues/8540#issuecomment-1536177102
## Solution
- The `size`, `min_size`, `max_size`, and `gap` properties have been
replaced by `width`, `height`, `min_width`, `min_height`, `max_width`,
`max_height`, `row_gap`, and `column_gap` properties
---
## Changelog
- Flattened `Style` properties that have a `Size` value directly into
`Style`
## Migration Guide
- The `size`, `min_size`, `max_size`, and `gap` properties have been
replaced by the `width`, `height`, `min_width`, `min_height`,
`max_width`, `max_height`, `row_gap`, and `column_gap` properties. Use
the new properties instead.
---------
Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
# Objective
- Fix#5631
## Solution
- Wait 50ms (configurable) after the last modification event before
reloading an asset.
---
## Changelog
- `AssetPlugin::watch_for_changes` is now a `ChangeWatcher` instead of a
`bool`
- Fixed https://github.com/bevyengine/bevy/issues/5631
## Migration Guide
- Replace `AssetPlugin::watch_for_changes: true` with e.g.
`ChangeWatcher::with_delay(Duration::from_millis(200))`
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
* `Node::physical_rect` divides the logical size of the node by the
scale factor, when it should multiply.
* Add a `physical_size` method to `Node` that calculates the physical
size of a node.
---
## Changelog
* Added a method `physical_size` to `Node` that calculates the physical
size of the `Node` based on the given scale factor.
* Fixed the `Node::physical_rect` method, the logical size should be
multiplied by the scale factor to get the physical size.
* Removed the `scale_value` function from the `text` widget module and
replaced its usage with `Node::physical_size`.
* Derived `Copy` for `Node` (since it's only a wrapped `Vec2`).
* Made `Node::size` const.
# Objective
`ScheduleGraph` currently stores run conditions in a
`Option<Vec<BoxedCondition>>`. The `Option` is unnecessary, since we can
just use an empty vector instead of `None`.
# Objective
The method `UnsafeWorldCell::world_mut` is a special case, since its
safety contract is more difficult to satisfy than the other methods on
`UnsafeWorldCell`. Rewrite its documentation to be specific about when
it can and cannot be used. Provide examples and emphasize that it is
unsound to call in most cases.
# Objective
The method `UnsafeWorldCell::read_change_tick` is longer than it needs
to be. `World` only has a method called this because it has two methods
for getting a change tick: one that takes `&self` and one that takes
`&mut self`. Since this distinction is not applicable to
`UnsafeWorldCell`, we should just call this method `change_tick`.
## Solution
Deprecate the current method and add a new one called `change_tick`.
---
## Changelog
- Renamed `UnsafeWorldCell::read_change_tick` to `change_tick`.
## Migration Guide
The `UnsafeWorldCell` method `read_change_tick` has been renamed to
`change_tick`.
# Objective
`ScheduleRunnerPlugin` was still configured via a resource, meaning
users would be able to change the settings while the app is running, but
the changes wouldn't have an effect.
## Solution
Configure plugin directly
---
## Changelog
- Changed: merged `ScheduleRunnerSettings` into `ScheduleRunnerPlugin`
## Migration Guide
- instead of inserting the `ScheduleRunnerSettings` resource, configure
the `ScheduleRunnerPlugin`
# Objective
- Fixes#3531
## Solution
- Added an append wrapper to BufferVec based on the function signature
for vec.append()
---
First PR to Bevy. I didn't see any tests for other BufferVec methods
(could have missed them) and currently this method is not used anywhere
in the project. Let me know if there are tests to add or if I should
find somewhere to use append so it is not dead code. The issue mentions
implementing `truncate` and `extend` which were already implemented and
merged
[here](https://github.com/bevyengine/bevy/pull/6833/files#diff-c8fb332382379e383f1811e30c31991b1e0feb38ca436c357971755368012ced)
# Objective
Replace `Query<&T, Changed<T>>` style queries with the more efficient
`Query<Ref<T>>` form in two of the UI systems.
---
## Changelog
Replaced use of `Changed` with `Ref` in queries in the
`ui_layout_system` and `calc_bounds` UI systems.
# Objective
- When writing render nodes that need a view, you always need to define
a `Query` on the associated view and make sure to update it manually and
query it manually. This is verbose and error prone.
## Solution
- Introduce a new `ViewNode` trait and `ViewNodeRunner` `Node` that will
take care of managing the associated view query automatically.
- The trait is currently a passthrough of the `Node` trait. So it still
has the update/run with all the same data passed in.
- The `ViewNodeRunner` is the actual node that is added to the render
graph and it contains the custom node. This is necessary because it's
the one that takes care of updating the node.
---
## Changelog
- Add `ViewNode`
- Add `ViewNodeRunner`
## Notes
Currently, this only handles the view query, but it could probably have
a ReadOnlySystemState that would also simplify querying all the readonly
resources that most render nodes currently query manually. The issue is
that I don't know how to do that without a `&mut self`.
At first, I tried making this a default feature of all `Node`, but I
kept hitting errors related to traits and generics and stuff I'm not
super comfortable with. This implementations is much simpler and keeps
the default Node behaviour so isn't a breaking change
## Reviewer Notes
The PR looks quite big, but the core of the PR is the changes in
`render_graph/node.rs`. Every other change is simply updating existing
nodes to use this new feature.
## Open questions
~~- Naming is not final, I'm opened to anything. I named it
ViewQueryNode because it's a node with a managed Query on a View.~~
~~- What to do when the query fails? All nodes using this pattern
currently just `return Ok(())` when it fails, so I chose that, but
should it be more flexible?~~
~~- Is the ViewQueryFilter actually necessary? All view queries run on
the entity that is already guaranteed to be a view. Filtering won't do
much, but maybe someone wants to control an effect with the presence of
a component instead of a flag.~~
~~- What to do with Nodes that are empty struct? Implementing
`FromWorld` is pretty verbose but not implementing it means there's 2
ways to create a `ViewNodeRunner` which seems less ideal. This is an
issue now because most node simply existed to hold the query, but now
that they don't hold the query state we are left with a bunch of empty
structs.~~
- Should we have a `RenderGraphApp::add_render_graph_view_node()`, this
isn't necessary, but it could make the code a bit shorter.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Add Reflect and FromReflect for AssetPath
- Fixes#8458
## Solution
- Straightforward derive of `Reflect` and `FromReflect` for `AssetPath`
- Implement `Reflect` and `FromReflect` for `Cow<'static, Path>` as to
satisfy the 'static lifetime requierments of bevy_reflect.
Implementation is a direct copy of that for `Cow<'static, str>` so maybe
it begs the question that was already asked in #7429 - maybe it would be
benefitial to write a general implementation for `Reflect` for
`Cow<'static, T>`.