# 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>`.
# Objective
Sometimes we might want to read from the depth texture in some custom
rendering features. We must then add `STORAGE_BINDING` or
`TEXTURE_BINDING` to the texture usage flags when creating them.
## Solution
This PR allows one to customize the usage flags in the `Camera3d`
component.
# Objective
- Fixes#8563
## Solution
~~- Implement From<Color> for [u8; 4]~~
~~- also implement From<[u8; 4]> for Color because why not.~~
- implement method `as_rgba_u8` in Color
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
`text_system` and `measure_text_system` both keep local queues to keep
track of text node entities that need recomputations/remeasurement,
which scales very badly with large numbers of text entities (O(n^2)) and
makes the code quite difficult to understand.
Also `text_system` filters for `Changed<Text>`, this isn't something
that it should do. When a text node entity fails to be processed by
`measure_text_system` because a font can't be found, the text node will
still be added to `text_system`'s local queue for recomputation. `Text`
should only ever be queued by `text_system` when a text node's geometry
is modified or a new measure is added.
## Solution
Remove the local text queues and use a component `TextFlags` to schedule
remeasurements and recomputations.
## Changelog
* Created a component `TextFlags` with fields `remeasure` and
`recompute`, which can be used to schedule a text `remeasure` or
`recomputation` respectively and added it to `TextBundle`.
* Removed the local text queues from `measure_text_system` and
`text_system` and instead use the `TextFlags` component to schedule
remeasurements and recomputations.
## Migration Guide
The component `TextFlags` has been added to `TextBundle`.
# Objective
Copy the `debug::print_tree` function from Taffy except display entity
ids instead of Taffy's node ids and indicate which ui nodes have a
measure func.
# Objective
Ensure future consistency between the two compare functions for all
types with manual `Ord` and `PartialOrd` implementations.
## Solution
Use `Self::cpm` in the implementation of `partial_cpm` for types
`Handle` and `Name`.
# Objective
there were typos in AxisSettings livezone/deadzone get/set function doc
comments.
## Solution
I changed the comments to be (hopefully) correct this time. I could be
wrong though.
# Objective
- Support WebGPU
- alternative to #5027 that doesn't need any async / await
- fixes#8315
- Surprise fix#7318
## Solution
### For async renderer initialisation
- Update the plugin lifecycle:
- app builds the plugin
- calls `plugin.build`
- registers the plugin
- app starts the event loop
- event loop waits for `ready` of all registered plugins in the same
order
- returns `true` by default
- then call all `finish` then all `cleanup` in the same order as
registered
- then execute the schedule
In the case of the renderer, to avoid anything async:
- building the renderer plugin creates a detached task that will send
back the initialised renderer through a mutex in a resource
- `ready` will wait for the renderer to be present in the resource
- `finish` will take that renderer and place it in the expected
resources by other plugins
- other plugins (that expect the renderer to be available) `finish` are
called and they are able to set up their pipelines
- `cleanup` is called, only custom one is still for pipeline rendering
### For WebGPU support
- update the `build-wasm-example` script to support passing `--api
webgpu` that will build the example with WebGPU support
- feature for webgl2 was always enabled when building for wasm. it's now
in the default feature list and enabled on all platforms, so check for
this feature must also check that the target_arch is `wasm32`
---
## Migration Guide
- `Plugin::setup` has been renamed `Plugin::cleanup`
- `Plugin::finish` has been added, and plugins adding pipelines should
do it in this function instead of `Plugin::build`
```rust
// Before
impl Plugin for MyPlugin {
fn build(&self, app: &mut App) {
app.insert_resource::<MyResource>
.add_systems(Update, my_system);
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};
render_app
.init_resource::<RenderResourceNeedingDevice>()
.init_resource::<OtherRenderResource>();
}
}
// After
impl Plugin for MyPlugin {
fn build(&self, app: &mut App) {
app.insert_resource::<MyResource>
.add_systems(Update, my_system);
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};
render_app
.init_resource::<OtherRenderResource>();
}
fn finish(&self, app: &mut App) {
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};
render_app
.init_resource::<RenderResourceNeedingDevice>();
}
}
```
# Objective
Fixes#8528
## Solution
Manually implement `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash`
for `bevy_ecs::event::EventId`. These new implementations do not rely on
the `Event` implementing the same traits allowing `EventId` to be used
in more cases.
# Objective
there was a typo in AxisSettings. It said "Values that are higher than
`livezone_upperbound` will be rounded up to -1.0." which I'm pretty
confident should be "1.0".
## Solution
I removed the '-'
# Objective
After fixing dynamic scene to only map specific entities, we want
map_entities to default to the less error prone behavior and have the
previous behavior renamed to "map_all_entities." As this is a breaking
change, it could not be pushed out with the bug fix.
## Solution
Simple rename and refactor.
## Changelog
### Changed
- `map_entities` now accepts a list of entities to apply to, with
`map_all_entities` retaining previous behavior of applying to all
entities in the map.
## Migration Guide
- In `bevy_ecs`, `ReflectMapEntities::map_entites` now requires an
additional `entities` parameter to specify which entities it applies to.
To keep the old behavior, use the new
`ReflectMapEntities::map_all_entities`, but consider if passing the
entities in specifically might be better for your use case to avoid
bugs.
# Objective
- I want to take screenshots of examples in CI to help with validation
of changes
## Solution
- Can override how much time is updated per frame
- Can specify on which frame to take a screenshots
- Save screenshots in CI
I reused the `TimeUpdateStrategy::ManualDuration` to be able to set the
time update strategy to a fixed duration every frame. Its previous
meaning didn't make much sense to me. This change makes it possible to
have screenshots that are exactly the same across runs.
If this gets merged, I'll add visual comparison of screenshots between
runs to ensure nothing gets broken
## Migration Guide
* `TimeUpdateStrategy::ManualDuration` meaning has changed. Instead of
setting time to `Instant::now()` plus the given duration, it sets time
to last update plus the given duration.
# Objective
- For many UI use cases (e.g. tree views, lists), it is important to be
able to imperatively sort child nodes.
- This also enables us to eventually support something like the
[`order`](https://developer.mozilla.org/en-US/docs/Web/CSS/order) CSS
property, that declaratively re-orders flex box items by a numeric
value, similar to z-index, but in space.
## Solution
We removed the ability to directly construct `Children` from `&[Entity]`
some time ago (#4197#5532) to enforce consistent hierarchies ([RFC
53](https://github.com/bevyengine/rfcs/blob/main/rfcs/53-consistent-hierarchy.md)).
If I understand it correctly, it's currently possible to re-order
children by using `Children::swap()` or
`commands.entity(id).replace_children(...)`, however these are either
too cumbersome, needlessly inefficient, and/or don't take effect
immediately.
This PR exposes the in-place sorting methods from the `slice` primitive
in `Children`, enabling imperatively sorting children in place via `&mut
Children`, while still preserving consistent hierarchies.
---
## Changelog
### Added
- The sorting methods from the `slice` primitive are now exposed by the
`Children` component, allowing imperatively sorting children in place
(Useful for UI scenarios such as lists)
# Objective
- Handle dangling entity references inside scenes
- Handle references to entities with generation > 0 inside scenes
- Fix a latent bug in `Parent`'s `MapEntities` implementation, which
would, if the parent was outside the scene, cause the scene to be loaded
into the new world with a parent reference potentially pointing to some
random entity in that new world.
- Fixes#4793 and addresses #7235
## Solution
- DynamicScenes now identify entities with a `Entity` instead of a u32,
therefore including generation
- `World` exposes a new `reserve_generations` function that despawns an
entity and advances its generation by some extra amount.
- `MapEntities` implementations have a new `get_or_reserve` function
available that will always return an `Entity`, establishing a new
mapping to a dead entity when the entity they are called with is not in
the `EntityMap`. Subsequent calls with that same `Entity` will return
the same newly created dead entity reference, preserving equality
semantics.
- As a result, after loading a scene containing references to dead
entities (or entities otherwise outside the scene), those references
will all point to different generations on a single entity id in the new
world.
---
## Changelog
### Changed
- In serialized scenes, entities are now identified by a u64 instead of
a u32.
- In serialized scenes, components with entity references now have those
references serialize as u64s instead of structs.
### Fixed
- Scenes containing components with entity references will now
deserialize and add to a world reliably.
## Migration Guide
- `MapEntities` implementations must change from a `&EntityMap`
parameter to a `&mut EntityMapper` parameter and can no longer return a
`Result`. Finally, they should switch from calling `EntityMap::get` to
calling `EntityMapper::get_or_reserve`.
---------
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
# Objective
fixes#8516
* Give `CalculatedSize` a more specific and intuitive name.
* `MeasureFunc`s should only be updated when their `CalculatedSize` is
modified by the systems managing their content.
For example, suppose that you have a UI displaying an image using an
`ImageNode`. When the window is resized, the node's `MeasureFunc` will
be updated even though the dimensions of the texture contained by the
node are unchanged.
* Fix the `CalculatedSize` API so that it no longer requires the extra
boxing and the `dyn_clone` method.
## Solution
* Rename `CalculatedSize` to `ContentSize`
* Only update `MeasureFunc`s on `CalculatedSize` changes.
* Remove the `dyn_clone` method from `Measure` and move the `Measure`
from the `ContentSize` component rather than cloning it.
* Change the measure_func field of `ContentSize` to type
`Option<taffy::node::MeasureFunc>`. Add a `set` method that wraps the
given measure appropriately.
---
## Changelog
* Renamed `CalculatedSize` to `ContentSize`.
* Replaced `upsert_leaf` with a function `update_measure` that only
updates the node's `MeasureFunc`.
* `MeasureFunc`s are only updated when the `ContentSize` changes and not
when the layout changes.
* Scale factor is no longer applied to the size values passed to the
`MeasureFunc`.
* Remove the `ContentSize` scaling in `text_system`.
* The `dyn_clone` method has been removed from the `Measure` trait.
* `Measure`s are moved from the `ContentSize` component instead of
cloning them.
* Added `set` method to `ContentSize` that replaces the `new` function.
## Migration Guide
* `CalculatedSize` has been renamed to `ContentSize`.
* The `upsert_leaf` function has been removed from `UiSurface` and
replaced with `update_measure` which updates the `MeasureFunc` without
node insertion.
* The `dyn_clone` method has been removed from the `Measure` trait.
* The new function of `CalculatedSize` has been replaced with the method
`set`.
# Objective
after calling `SceneSpawner::spawn_as_child`, the scene spawner system
will always try to attach the scene instance to the parent once it is
loaded, even if the parent has been deleted, causing a panic.
## Solution
check if the parent is still alive, and don't spawn the scene instance
if not.
# Objective
- Enable taking a screenshot in wasm
- Followup on #7163
## Solution
- Create a blob from the image data, generate a url to that blob, add an
`a` element to the document linking to that url, click on that element,
then revoke the url
- This will automatically trigger a download of the screenshot file in
the browser
# Objective
This is just an oversight on my part when I implemented this in
https://github.com/bevyengine/bevy/pull/7186, there isn't much reason to
print out the hash of a `Name` like it does currently:
```
Name { hash: 1608798714325729304, name: "Suzanne" } (7v0)
```
## Solution
Instead it would be better if we just printed out the string like so:
```
"Suzanne" (7v0)
```
As it conveys all of the information in a less cluttered and immediately
intuitive way which was the original purpose of `DebugName`. Which I
also think translates to `Name` as well since I mostly see it as a thin
wrapper around a string.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Updated to wgpu 0.16.0 and wgpu-hal 0.16.0
---
## Changelog
1. Upgrade wgpu to 0.16.0 and wgpu-hal to 0.16.0
2. Fix the error in native when using a filterable
`TextureSampleType::Float` on a multisample `BindingType::Texture`.
([https://github.com/gfx-rs/wgpu/pull/3686](https://github.com/gfx-rs/wgpu/pull/3686))
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
> This PR is based on discussion from #6601
The Dynamic types (e.g. `DynamicStruct`, `DynamicList`, etc.) act as
both:
1. Dynamic containers which may hold any arbitrary data
2. Proxy types which may represent any other type
Currently, the only way we can represent the proxy-ness of a Dynamic is
by giving it a name.
```rust
// This is just a dynamic container
let mut data = DynamicStruct::default();
// This is a "proxy"
data.set_name(std::any::type_name::<Foo>());
```
This type name is the only way we check that the given Dynamic is a
proxy of some other type. When we need to "assert the type" of a `dyn
Reflect`, we call `Reflect::type_name` on it. However, because we're
only using a string to denote the type, we run into a few gotchas and
limitations.
For example, hashing a Dynamic proxy may work differently than the type
it proxies:
```rust
#[derive(Reflect, Hash)]
#[reflect(Hash)]
struct Foo(i32);
let concrete = Foo(123);
let dynamic = concrete.clone_dynamic();
let concrete_hash = concrete.reflect_hash();
let dynamic_hash = dynamic.reflect_hash();
// The hashes are not equal because `concrete` uses its own `Hash` impl
// while `dynamic` uses a reflection-based hashing algorithm
assert_ne!(concrete_hash, dynamic_hash);
```
Because the Dynamic proxy only knows about the name of the type, it's
unaware of any other information about it. This means it also differs on
`Reflect::reflect_partial_eq`, and may include ignored or skipped fields
in places the concrete type wouldn't.
## Solution
Rather than having Dynamics pass along just the type name of proxied
types, we can instead have them pass around the `TypeInfo`.
Now all Dynamic types contain an `Option<&'static TypeInfo>` rather than
a `String`:
```diff
pub struct DynamicTupleStruct {
- type_name: String,
+ represented_type: Option<&'static TypeInfo>,
fields: Vec<Box<dyn Reflect>>,
}
```
By changing `Reflect::get_type_info` to
`Reflect::represented_type_info`, hopefully we make this behavior a
little clearer. And to account for `None` values on these dynamic types,
`Reflect::represented_type_info` now returns `Option<&'static
TypeInfo>`.
```rust
let mut data = DynamicTupleStruct::default();
// Not proxying any specific type
assert!(dyn_tuple_struct.represented_type_info().is_none());
let type_info = <Foo as Typed>::type_info();
dyn_tuple_struct.set_represented_type(Some(type_info));
// Alternatively:
// let dyn_tuple_struct = foo.clone_dynamic();
// Now we're proxying `Foo`
assert!(dyn_tuple_struct.represented_type_info().is_some());
```
This means that we can have full access to all the static type
information for the proxied type. Future work would include
transitioning more static type information (trait impls, attributes,
etc.) over to the `TypeInfo` so it can actually be utilized by Dynamic
proxies.
### Alternatives & Rationale
> **Note**
> These alternatives were written when this PR was first made using a
`Proxy` trait. This trait has since been removed.
<details>
<summary>View</summary>
#### Alternative: The `Proxy<T>` Approach
I had considered adding something like a `Proxy<T>` type where `T` would
be the Dynamic and would contain the proxied type information.
This was nice in that it allows us to explicitly determine whether
something is a proxy or not at a type level. `Proxy<DynamicStruct>`
proxies a struct. Makes sense.
The reason I didn't go with this approach is because (1) tuples, (2)
complexity, and (3) `PartialReflect`.
The `DynamicTuple` struct allows us to represent tuples at runtime. It
also allows us to do something you normally can't with tuples: add new
fields. Because of this, adding a field immediately invalidates the
proxy (e.g. our info for `(i32, i32)` doesn't apply to `(i32, i32,
NewField)`). By going with this PR's approach, we can just remove the
type info on `DynamicTuple` when that happens. However, with the
`Proxy<T>` approach, it becomes difficult to represent this behavior—
we'd have to completely control how we access data for `T` for each `T`.
Secondly, it introduces some added complexities (aside from the manual
impls for each `T`). Does `Proxy<T>` impl `Reflect`? Likely yes, if we
want to represent it as `dyn Reflect`. What `TypeInfo` do we give it?
How would we forward reflection methods to the inner type (remember, we
don't have specialization)? How do we separate this from Dynamic types?
And finally, how do all this in a way that's both logical and intuitive
for users?
Lastly, introducing a `Proxy` trait rather than a `Proxy<T>` struct is
actually more inline with the [Unique Reflect
RFC](https://github.com/bevyengine/rfcs/pull/56). In a way, the `Proxy`
trait is really one part of the `PartialReflect` trait introduced in
that RFC (it's technically not in that RFC but it fits well with it),
where the `PartialReflect` serves as a way for proxies to work _like_
concrete types without having full access to everything a concrete
`Reflect` type can do. This would help bridge the gap between the
current state of the crate and the implementation of that RFC.
All that said, this is still a viable solution. If the community
believes this is the better path forward, then we can do that instead.
These were just my reasons for not initially going with it in this PR.
#### Alternative: The Type Registry Approach
The `Proxy` trait is great and all, but how does it solve the original
problem? Well, it doesn't— yet!
The goal would be to start moving information from the derive macro and
its attributes to the generated `TypeInfo` since these are known
statically and shouldn't change. For example, adding `ignored: bool` to
`[Un]NamedField` or a list of impls.
However, there is another way of storing this information. This is, of
course, one of the uses of the `TypeRegistry`. If we're worried about
Dynamic proxies not aligning with their concrete counterparts, we could
move more type information to the registry and require its usage.
For example, we could replace `Reflect::reflect_hash(&self)` with
`Reflect::reflect_hash(&self, registry: &TypeRegistry)`.
That's not the _worst_ thing in the world, but it is an ergonomics loss.
Additionally, other attributes may have their own requirements, further
restricting what's possible without the registry. The `Reflect::apply`
method will require the registry as well now. Why? Well because the
`map_apply` function used for the `Reflect::apply` impls on `Map` types
depends on `Map::insert_boxed`, which (at least for `DynamicMap`)
requires `Reflect::reflect_hash`. The same would apply when adding
support for reflection-based diffing, which will require
`Reflect::reflect_partial_eq`.
Again, this is a totally viable alternative. I just chose not to go with
it for the reasons above. If we want to go with it, then we can close
this PR and we can pursue this alternative instead.
#### Downsides
Just to highlight a quick potential downside (likely needs more
investigation): retrieving the `TypeInfo` requires acquiring a lock on
the `GenericTypeInfoCell` used by the `Typed` impls for generic types
(non-generic types use a `OnceBox which should be faster). I am not sure
how much of a performance hit that is and will need to run some
benchmarks to compare against.
</details>
### Open Questions
1. Should we use `Cow<'static, TypeInfo>` instead? I think that might be
easier for modding? Perhaps, in that case, we need to update
`Typed::type_info` and friends as well?
2. Are the alternatives better than the approach this PR takes? Are
there other alternatives?
---
## Changelog
### Changed
- `Reflect::get_type_info` has been renamed to
`Reflect::represented_type_info`
- This method now returns `Option<&'static TypeInfo>` rather than just
`&'static TypeInfo`
### Added
- Added `Reflect::is_dynamic` method to indicate when a type is dynamic
- Added a `set_represented_type` method on all dynamic types
### Removed
- Removed `TypeInfo::Dynamic` (use `Reflect::is_dynamic` instead)
- Removed `Typed` impls for all dynamic types
## Migration Guide
- The Dynamic types no longer take a string type name. Instead, they
require a static reference to `TypeInfo`:
```rust
#[derive(Reflect)]
struct MyTupleStruct(f32, f32);
let mut dyn_tuple_struct = DynamicTupleStruct::default();
dyn_tuple_struct.insert(1.23_f32);
dyn_tuple_struct.insert(3.21_f32);
// BEFORE:
let type_name = std::any::type_name::<MyTupleStruct>();
dyn_tuple_struct.set_name(type_name);
// AFTER:
let type_info = <MyTupleStruct as Typed>::type_info();
dyn_tuple_struct.set_represented_type(Some(type_info));
```
- `Reflect::get_type_info` has been renamed to
`Reflect::represented_type_info` and now also returns an
`Option<&'static TypeInfo>` (instead of just `&'static TypeInfo`):
```rust
// BEFORE:
let info: &'static TypeInfo = value.get_type_info();
// AFTER:
let info: &'static TypeInfo = value.represented_type_info().unwrap();
```
- `TypeInfo::Dynamic` and `DynamicInfo` has been removed. Use
`Reflect::is_dynamic` instead:
```rust
// BEFORE:
if matches!(value.get_type_info(), TypeInfo::Dynamic) {
// ...
}
// AFTER:
if value.is_dynamic() {
// ...
}
```
---------
Co-authored-by: radiish <cb.setho@gmail.com>
# Objective
A lot of items in `bevy_ui` could be `FromReflect` but aren't. This
prevents users and library authors from being able to convert from a
`dyn Reflect` to one of these items.
## Solution
Derive `FromReflect` where possible. Also register the
`ReflectFromReflect` type data.
# Objective
Considering that `FromReflect` is a very common trait to derive, it
would make sense to include `ReflectFromReflect` in the `bevy_reflect`
prelude so users don't need to import it separately.
## Solution
Add `ReflectFromReflect` to the prelude.
# Objective
Currently, there isn't a clean way of getting an untyped handle to an
asset during asset loading. This is useful for when an asset needs to
reference other assets, but may not know the concrete type of each
asset.
We could "hack" this together by just using some random asset:
```rust
// We don't care what `bar.baz` is, so we "pretend" it's an `Image`
let handle: Handle<Image> = load_context.get_handle("foo/bar.baz");
```
This should work since we don't actually care about the underlying type
in this case. However, we can do better.
## Solution
Add the `LoadContext::get_handle_untyped` method to get untyped handles
to assets.
# Objective
- Reduce compilation time
## Solution
- Make `spirv` and `glsl` shader format support optional. They are not
needed for Bevy shaders.
- on my mac (where shaders are compiled to `msl`), this reduces the
total build time by 2 to 5 seconds, improvement should be even better
with less cores
There is a big reduction in compile time for `naga`, and small
improvements on `wgpu` and `bevy_render`
This PR with optional shader formats enabled timings:
<img width="1478" alt="current main"
src="https://user-images.githubusercontent.com/8672791/234347032-cbd5c276-a9b0-49c3-b793-481677391c18.png">
This PR:
<img width="1479" alt="this pr"
src="https://user-images.githubusercontent.com/8672791/234347059-a67412a9-da8d-4356-91d8-7b0ae84ca100.png">
---
## Migration Guide
- If you want to use shaders in `spirv`, enable the
`shader_format_spirv` feature
- If you want to use shaders in `glsl`, enable the `shader_format_glsl`
feature
# Objective
- Fixes#8484
## Solution
Since #8445 fonts need to register a debug asset, otherwise the
`debug_asset_server` feature doesn't work. This adds the debug asset
registration
# Objective
Provide the ability to trigger controller rumbling (force-feedback) with
a cross-platform API.
## Solution
This adds the `GamepadRumbleRequest` event to `bevy_input` and adds a
system in `bevy_gilrs` to read them and rumble controllers accordingly.
It's a relatively primitive API with a `duration` in seconds and
`GamepadRumbleIntensity` with values for the weak and strong gamepad
motors. It's is an almost 1-to-1 mapping to platform APIs. Some
platforms refer to these motors as left and right, and low frequency and
high frequency, but by convention, they're usually the same.
I used #3868 as a starting point, updated to main, removed the low-level
gilrs effect API, and moved the requests to `bevy_input` and exposed the
strong and weak intensities.
I intend this to hopefully be a non-controversial cross-platform
starting point we can build upon to eventually support more fine-grained
control (closer to the gilrs effect API)
---
## Changelog
### Added
- Gamepads can now be rumbled by sending the `GamepadRumbleRequest`
event.
---------
Co-authored-by: Nicola Papale <nico@nicopap.ch>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Bruce Reif (Buswolley) <bruce.reif@dynata.com>
# Objective
`Camera::logical_viewport_rect()` returns `Option<(Vec2, Vec2)>` which
is a tuple of vectors representing the `(min, max)` bounds of the
viewport rect. Since the function says it returns a rect and there is a
`Rect { min, max }` struct in `bevy_math`, using the struct will be
clearer.
## Solution
Replaced `Option<(Vec2, Vec2)>` with `Option<Rect>` for
`Camera::logical_viewport_rect()`.
---
## Changelog
- Changed `Camera::logical_viewport_rect` return type from `(Vec2,
Vec2)` to `Rect`
## Migration Guide
Before:
```
fn view_logical_camera_rect(camera_query: Query<&Camera>) {
let camera = camera_query.single();
let Some((min, max)) = camera.logical_viewport_rect() else { return };
dbg!(min, max);
}
```
After:
```
fn view_logical_camera_rect(camera_query: Query<&Camera>) {
let camera = camera_query.single();
let Some(Rect { min, max }) = camera.logical_viewport_rect() else { return };
dbg!(min, max);
}
```
# Objective
Add a bounding box gizmo
![Screenshot from 2023-04-22
23-49-40](https://user-images.githubusercontent.com/29694403/233808825-7593dc38-0623-48a9-b0d7-a4ca24a9e071.png)
## Changes
- Added the `AabbGizmo` component that will draw the `Aabb` component on
that entity.
- Added an option to draw all bounding boxes in a scene on the
`GizmoConfig` resource.
- Added `TransformPoint` trait to generalize over the point
transformation methods on various transform types (e.g `Transform` and
`GlobalTransform`).
- Changed the `Gizmos::cuboid` method to accept an `impl TransformPoint`
instead of separate translation, rotation, and scale.
# Objective
Timer with zero `Duration` panics at `tick()` because of division by
zero. This PR Fixes#8463 .
## Solution
- Handle division by zero separately with `checked_div` and
`checked_rem`.
---
## Changelog
- Replace division with `checked_div`. Set `times_finished_this_tick` to
u32::MAX when duration is zero.
- Set `elapsed` to `Duration::ZERO` when timer duration is zero.
- Set `percent` to `1.0` when duration is zero.
- `times_finished_this_tick` is [not used
anywhere](https://github.com/bevyengine/bevy/search?q=times_finished_this_tick),
that's why this change will not affect other parts of the project.
- `times_finished_this_tick` is set to `0` after `reset()` and before
first `tick()` call.
# Objective
- Add `Aabb` calculation for `Sprite`, `TextureAtlasSprite` and
`Mesh2d`.
- Enable frustum culling for 2D entities since frustum culling requires
a `Aabb` component in the entity to function.
- Improve 2D performance massively when there are many sprites out of
view. (ex: `many_sprites`)
## Solution
- Derived from @Weasy666's #3944 pull request, which had no activity
since multiple months.
- Adapted the code to the latest version of Bevy.
- Added support for sprites with non-center `Anchor`s to avoid culling
prematurely when part of the sprite is still in view or not culling when
sprite is already out of view.
### Note
- Gives 15.8x performance boosts in some scenarios. (5 fps vs 79 fps
with 409600 sprites in `many_sprites`)
---------
Co-authored-by: ira <JustTheCoolDude@gmail.com>
# Objective
The objective is to be able to load data from "application-specific"
(see glTF spec 3.7.2.1.) vertex attribute semantics from glTF files into
Bevy meshes.
## Solution
Rather than probe the glTF for the specific attributes supported by
Bevy, this PR changes the loader to iterate through all the attributes
and map them onto `MeshVertexAttribute`s. This mapping includes all the
previously supported attributes, plus it is now possible to add mappings
using the `add_custom_vertex_attribute()` method on `GltfPlugin`.
## Changelog
- Add support for loading custom vertex attributes from glTF files.
- Add the `custom_gltf_vertex_attribute.rs` example to illustrate
loading custom vertex attributes.
## Migration Guide
- If you were instantiating `GltfPlugin` using the unit-like struct
syntax, you must instead use `GltfPlugin::default()` as the type is no
longer unit-like.
This line does not appear to be an intended part of the `Panics`
section, but instead looks like it was missed when copy-pasting a
`Panics` section from above.
It confused me when I was reading the docs. At first I read it as if it
was an imperative statement saying not to use `match` statements which
seemed odd and out of place. Once I saw the code it was clearly in err.
# Objective
- Cleanup documentation string to reduce end-user confusion.
Links in the api docs are nice. I noticed that there were several places
where structs / functions and other things were referenced in the docs,
but weren't linked. I added the links where possible / logical.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
- Enabling AlphaMode::Opaque in the shader_prepass example crashes. The
issue seems to be that enabling opaque also generates vertex_uvs
Fixes https://github.com/bevyengine/bevy/issues/8273
## Solution
- Use the vertex_uvs in the shader if they are present
# Objective
The first query of `measure_text_system`'s `text_queries` `ParamSet`
queries for all changed `Text` meaning that non-UI `Text` entities could
be added to its queue.
## Solution
Add a `With<Node>` query filter.
---
## Changelog
changes:
* Added a `With<Node>` query filter to first query of
`measure_text_system`'s `text_queries` `ParamSet` to ensure that only UI
node entities are added to its local queue.
* Fixed comment (text is not computed on changes to style).
# Objective
- Fix the issue described in #8183: Box<dyn Reflect> structs with a
hashmap in them will panic when clone_value is called on it
- Fixes: #8183
## Solution
- Updates the implementation of Reflect for Hashmaps to make clone_value
call from_reflect on the key before inserting it into the new struct
# Objective
- Have a default font
## Solution
- Add a font based on FiraMono containing only ASCII characters and use
it as the default font
- It is behind a feature `default_font` enabled by default
- I also updated examples to use it, but not UI examples to still show
how to use a custom font
---
## Changelog
* If you display text without using the default handle provided by
`TextStyle`, the text will be displayed
# Objective
Added the possibility to draw arcs in 2d via gizmos
## Solution
- Added `arc_2d` function to `Gizmos`
- Added `arc_inner` function
- Added `Arc2dBuilder<'a, 's>`
- Updated `2d_gizmos.rs` example to draw an arc
---------
Co-authored-by: kjolnyr <kjolnyr@protonmail.ch>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: ira <JustTheCoolDude@gmail.com>
# Objective
If a UI node has a changed `CalculatedSize` component and either the UI
does a full update or the node also has a changed `Style` component, the
node's corresponding Taffy node will be updated twice by
`flex_node_system`.
## Solution
Add a `Without<Calculated>` query filter so that the two changed node
queries in `flex_node_system` are mutually exclusive and move the
`CalculatedSize` node updater into the else block of the full-update if
conditional.
# Objective
- Mesh entities should cast shadows when not having Aabbs and having
NoFrustumCulling
- Fixes#8442
## Solution
- Mesh entities with NoFrustumCulling get no automatic Aabbs added
- Point and spot lights do not cull mesh entities for their shadow
mapping if they do not have an Aabb, but directional lights do
- Make directional lights not cull mesh entities from cascades if the do
not have Aabbs. So no Aabb as a consequence of a NoFrustumCulling
component will mean that those mesh entities are not culled and so are
visible to the light.
---
## Changelog
- Fixed: Mesh entities with NoFrustumCulling will cast shadows for
directional light shadow maps
Fixes https://github.com/bevyengine/bevy/issues/1207
# Objective
Right now, it's impossible to capture a screenshot of the entire window
without forking bevy. This is because
- The swapchain texture never has the COPY_SRC usage
- It can't be accessed without taking ownership of it
- Taking ownership of it breaks *a lot* of stuff
## Solution
- Introduce a dedicated api for taking a screenshot of a given bevy
window, and guarantee this screenshot will always match up with what
gets put on the screen.
---
## Changelog
- Added the `ScreenshotManager` resource with two functions,
`take_screenshot` and `save_screenshot_to_disk`
# Objective
Methods for interacting with world schedules currently have two
variants: one that takes `impl ScheduleLabel` and one that takes `&dyn
ScheduleLabel`. Operations such as `run_schedule` or `schedule_scope`
only use the label by reference, so there is little reason to have an
owned variant of these functions.
## Solution
Decrease maintenance burden by merging the `ref` variants of these
functions with the owned variants.
---
## Changelog
- Deprecated `World::run_schedule_ref`. It is now redundant, since
`World::run_schedule` can take values by reference.
## Migration Guide
The method `World::run_schedule_ref` has been deprecated, and will be
removed in the next version of Bevy. Use `run_schedule` instead.
# Objective
Label traits such as `ScheduleLabel` currently have a major footgun: the
trait is implemented for `Box<dyn ScheduleLabel>`, but the
implementation does not function as one would expect since `Box<T>` is
considered to be a distinct type from `T`. This is because the behavior
of the `ScheduleLabel` trait is specified mainly through blanket
implementations, which prevents `Box<dyn ScheduleLabel>` from being
properly special-cased.
## Solution
Replace the blanket-implemented behavior with a series of methods
defined on `ScheduleLabel`. This allows us to fully special-case
`Box<dyn ScheduleLabel>` .
---
## Changelog
Fixed a bug where boxed label types (such as `Box<dyn ScheduleLabel>`)
behaved incorrectly when compared with concretely-typed labels.
## Migration Guide
The `ScheduleLabel` trait has been refactored to no longer depend on the
traits `std::any::Any`, `bevy_utils::DynEq`, and `bevy_utils::DynHash`.
Any manual implementations will need to implement new trait methods in
their stead.
```rust
impl ScheduleLabel for MyType {
// Before:
fn dyn_clone(&self) -> Box<dyn ScheduleLabel> { ... }
// After:
fn dyn_clone(&self) -> Box<dyn ScheduleLabel> { ... }
fn as_dyn_eq(&self) -> &dyn DynEq {
self
}
// No, `mut state: &mut` is not a typo.
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
self.hash(&mut state);
// Hashing the TypeId isn't strictly necessary, but it prevents collisions.
TypeId::of::<Self>().hash(&mut state);
}
}
```
Added helper extracted from #7711. that PR contains some controversy
conditions, but this one should be good to go.
---
## Changelog
### Added
- `any_component_removed` condition.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
Split the UI overflow enum so that overflow can be set for each axis
separately.
## Solution
Change `Overflow` from an enum to a struct with `x` and `y`
`OverflowAxis` fields, where `OverflowAxis` is an enum with `Clip` and
`Visible` variants. Modify `update_clipping` to calculate clipping for
each axis separately. If only one axis is clipped, the other axis is
given infinite bounds.
<img width="642" alt="overflow"
src="https://user-images.githubusercontent.com/27962798/227592983-568cf76f-7e40-48c4-a511-43c886f5e431.PNG">
---
## Changelog
* Split the UI overflow implementation so overflow can be set for each
axis separately.
* Added the enum `OverflowAxis` with `Clip` and `Visible` variants.
* Changed `Overflow` to a struct with `x` and `y` fields of type
`OverflowAxis`.
* `Overflow` has new methods `visible()` and `hidden()` that replace its
previous `Clip` and `Visible` variants.
* Added `Overflow` helper methods `clip_x()` and `clip_y()` that return
a new `Overflow` value with the given axis clipped.
* Modified `update_clipping` so it calculates clipping for each axis
separately. If a node is only clipped on a single axis, the other axis
is given `-f32::INFINITY` to `f32::INFINITY` clipping bounds.
## Migration Guide
The `Style` property `Overflow` is now a struct with `x` and `y` fields,
that allow for per-axis overflow control.
Use these helper functions to replace the variants of `Overflow`:
* Replace `Overflow::Visible` with `Overflow::visible()`
* Replace `Overflow::Hidden` with `Overflow::clip()`
# Objective
Avoid queuing empty meshes for rendering.
Should prevent #8144 from triggering when no gizmos are in use. Not a
real fix, unfortunately.
## Solution
Add an `in_use` field to `GizmoStorage` and only set it to true when
there are gizmos to draw.
# Objective
Follow-up to #8377.
As the system module has been refactored, there are many types that no
longer make sense to live in the files that they do:
- The `IntoSystem` trait is in `function_system.rs`, even though this
trait is relevant to all kinds of systems. Same for the `In<T>` type.
- `PipeSystem` is now just an implementation of `CombinatorSystem`, so
`system_piping.rs` no longer needs its own file.
## Solution
- Move `IntoSystem`, `In<T>`, and system piping combinators & tests into
the top-level `mod.rs` file for `bevy_ecs::system`.
- Move `PipeSystem` into `combinator.rs`.
# Objective
Add Reflection to `TextureAtlasSprite` to bring it inline with `Sprite`
## Solution
Addition of appropriate macros to the type
---
## Changelog
`#[reflect(Component)]` and derive `FromReflect` for
`TextureAtlasSprite`
Added `TextureAtlasSprite` to the TypeRegistry
# Objective
Fixes#8415.
## Solution
I simply added the missing types to the type registry.
## Changelog
Added `#[reflect(Component]` to `bevi_ui::ui_node::ZIndex`, since it
impls `Component` and `Reflect.`
The following types have been added to the type registry:
1. `bevy_ui::ZIndex`
2. `bevy_math::Rect`
3. `bevy_text::BreakLineOn`
4. `bevy_text::Text2dBounds`
# Objective
Followup to #7779 which tweaks the actual text measurement algorithm to
be more robust.
Before:
<img width="822" alt="Screenshot 2023-04-17 at 18 12 05"
src="https://user-images.githubusercontent.com/1007307/232566858-3d3f0fd5-f3d4-400a-8371-3c2a3f541e56.png">
After:
<img width="810" alt="Screenshot 2023-04-17 at 18 41 40"
src="https://user-images.githubusercontent.com/1007307/232566919-4254cbfa-1cc3-4ea7-91ed-8ca1b759bacf.png">
(note extra space taken up in header in before example)
## Solution
- Text layout of horizontal text (currently the only kind of text we
support) is now based solely on the layout constraints in the horizontal
axis. It ignores constraints in the vertical axis and computes vertical
size based on wrapping subject to the horizontal axis constraints.
- I've also added a paragraph to the `grid` example for testing / demo
purposes.
# Objective
When changing an Entity's `Parent` to a new one from an old `Parent`
that doesn't exist, Bevy panics. Fixes#8337.
## Solution
Use `get_entity_mut` instead of `entity_mut` in `remove_from_children`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Incorrectly resolved merge conflicts in
https://github.com/bevyengine/bevy/pull/8026 have caused UI text to not
render at all.
## Solution
Restore correct system schedule for text systems
# Objective
An easy way to create 2D grid layouts
## Solution
Enable the `grid` feature in Taffy and add new style types for defining
grids.
## Notes
- ~I'm having a bit of trouble getting `#[derive(Reflect)]` to work
properly. Help with that would be appreciated (EDIT: got it to compile
by ignoring the problematic fields, but this presumably can't be
merged).~ This is now fixed
- ~The alignment types now have a `Normal` variant because I couldn't
get reflect to work with `Option`.~ I've decided to stick with the
flattened variant, as it saves a level of wrapping when authoring
styles. But I've renamed the variants from `Normal` to `Default`.
- ~This currently exposes a simplified API on top of grid. In particular
the following is not currently supported:~
- ~Negative grid indices~ Now supported.
- ~Custom `end` values for grid placement (you can only use `start` and
`span`)~ Now supported
- ~`minmax()` track sizing functions~ minmax is now support through a
`GridTrack::minmax()` constructor
- ~`repeat()`~ repeat is now implemented as `RepeatedGridTrack`
- ~Documentation still needs to be improved.~ An initial pass over the
documentation has been completed.
## Screenshot
<img width="846" alt="Screenshot 2023-03-10 at 17 56 21"
src="https://user-images.githubusercontent.com/1007307/224435332-69aa9eac-123d-4856-b75d-5449d3f1d426.png">
---
## Changelog
- Support for CSS Grid layout added to `bevy_ui`
---------
Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
# Objective
- Currently, it is not possible to call `.pipe` on a system that takes
any input other than `()`.
- The `IntoPipeSystem` trait is currently very difficult to parse due to
its use of generics.
## Solution
Remove the `IntoPipeSystem` trait, and move the `pipe` method to
`IntoSystem`.
---
## Changelog
- System piping has been made more flexible: it is now possible to call
`.pipe` on a system that takes an input.
## Migration Guide
The `IntoPipeSystem` trait has been removed, and the `pipe` method has
been moved to the `IntoSystem` trait.
```rust
// Before:
use bevy_ecs::system::IntoPipeSystem;
schedule.add_systems(first.pipe(second));
// After:
use bevy_ecs::system::IntoSystem;
schedule.add_systems(first.pipe(second));
```
# Objective
- Fixes unclear warning when `insert_non_send_resource` is called on a
Send resource
## Solution
- Add a message to the asssert statement that checks this
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
`text_system` runs before the UI layout is calculated and the size of
the text node is determined, so it cannot correctly shape the text to
fit the layout, and has no way of determining if the text needs to be
wrapped.
The function `text_constraint` attempts to determine the size of the
node from the local size constraints in the `Style` component. It can't
be made to work, you have to compute the whole layout to get the correct
size. A simple example of where this fails completely is a text node set
to stretch to fill the empty space adjacent to a node with size
constraints set to `Val::Percent(50.)`. The text node will take up half
the space, even though its size constraints are `Val::Auto`
Also because the `text_system` queries for changes to the `Style`
component, when a style value is changed that doesn't affect the node's
geometry the text is recomputed unnecessarily.
Querying on changes to `Node` is not much better. The UI layout is
changed to fit the `CalculatedSize` of the text, so the size of the node
is changed and so the text and UI layout get recalculated multiple times
from a single change to a `Text`.
Also, the `MeasureFunc` doesn't work at all, it doesn't have enough
information to fit the text correctly and makes no attempt.
Fixes#7663, #6717, #5834, #1490,
## Solution
Split the `text_system` into two functions:
* `measure_text_system` which calculates the size constraints for the
text node and runs before `UiSystem::Flex`
* `text_system` which runs after `UiSystem::Flex` and generates the
actual text.
* Fix the `MeasureFunc` calculations.
---
Text wrapping in main:
<img width="961" alt="Capturemain"
src="https://user-images.githubusercontent.com/27962798/220425740-4fe4bf46-24fb-4685-a1cf-bc01e139e72d.PNG">
With this PR:
<img width="961" alt="captured_wrap"
src="https://user-images.githubusercontent.com/27962798/220425807-949996b0-f127-4637-9f33-56a6da944fb0.PNG">
## Changelog
* Removed the previous fields from `CalculatedSize`. `CalculatedSize`
now contains a boxed `Measure`.
* Added `measurement` module to `bevy_ui`.
* Added the method `create_text_measure` to `TextPipeline`.
* Added a new system `measure_text_system` that runs before
`UiSystem::Flex` that creates a `MeasureFunc` for the text.
* Rescheduled `text_system` to run after `UiSystem::Flex`.
* Added a trait `Measure`. A `Measure` is used to compute the size of a
UI node when the size of that node is based on its content.
* Added `ImageMeasure` and `TextMeasure` which implement `Measure`.
* Added a new component `UiImageSize` which is used by
`update_image_calculated_size_system` to track image size changes.
* Added a `UiImageSize` component to `ImageBundle`.
## Migration Guide
`ImageBundle` has a new component `UiImageSize` which contains the size
of the image bundle's texture and is updated automatically by
`update_image_calculated_size_system`
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
The implementation of `System::run_unsafe` for `FunctionSystem` requires
that the world is the same one used to initialize the system. However,
the `System` trait has no requirements that the world actually matches,
which makes this implementation unsound.
This was previously mentioned in
https://github.com/bevyengine/bevy/pull/7605#issuecomment-1426491871
Fixes part of #7833.
## Solution
Add the safety invariant that
`System::update_archetype_component_access` must be called prior to
`System::run_unsafe`. Since
`FunctionSystem::update_archetype_component_access` properly validates
the world, this ensures that `run_unsafe` is not called with a
mismatched world.
Most exclusive systems are not required to be run on the same world that
they are initialized with, so this is not a concern for them. Systems
formed by combining an exclusive system with a regular system *do*
require the world to match, however the validation is done inside of
`System::run` when needed.
# Objective
This PR attempts to improve query compatibility checks in scenarios
involving `Or` filters.
Currently, for the following two disjoint queries, Bevy will throw a
panic:
```
fn sys(_: Query<&mut C, Or<(With<A>, With<B>)>>, _: Query<&mut C, (Without<A>, Without<B>)>) {}
```
This PR addresses this particular scenario.
## Solution
`FilteredAccess::with` now stores a vector of `AccessFilters`
(representing a pair of `with` and `without` bitsets), where each member
represents an `Or` "variant".
Filters like `(With<A>, Or<(With<B>, Without<C>)>` are expected to be
expanded into `A * B + A * !C`.
When calculating whether queries are compatible, every `AccessFilters`
of a query is tested for incompatibility with every `AccessFilters` of
another query.
---
## Changelog
- Improved system and query data access compatibility checks in
scenarios involving `Or` filters
---------
Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
If you want to execute a schedule on the world using arbitrarily complex
behavior, you currently need to use "hokey-pokey strats": remove the
schedule from the world, do your thing, and add it back to the world.
Not only is this cumbersome, it's potentially error-prone as one might
forget to re-insert the schedule.
## Solution
Add the `World::{try}schedule_scope{ref}` family of functions, which is
a convenient abstraction over hokey pokey strats. This method
essentially works the same way as `World::resource_scope`.
### Example
```rust
// Run the schedule five times.
world.schedule_scope(MySchedule, |world, schedule| {
for _ in 0..5 {
schedule.run(world);
}
});
```
---
## Changelog
Added the `World::schedule_scope` family of methods, which provide a way
to get mutable access to a world and one of its schedules at the same
time.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
The default StandardMaterial values of `pbr_material.rs` and
`pbr_types.wgsl` are out of sync.
I think they are out of sync since
https://github.com/bevyengine/bevy/pull/7664.
## Solution
Adapt the values: `metallic = 0.0`, `perceptual_roughness = 0.5`.
# Objective
We don't have a constructor function for `UiRect` that sets uniform
horizontal and vertical values, even though it is a common pattern.
## Solution
Add a constructor function to `UiRect` called `axes`, that sets both
`left` and `right` to the same given horizontal value,
and sets both `top` and `bottom` to same given vertical value.
## Changelog
* Added a constructor function `axes` to `UiRect`.
# Objective
fixes#8348
## Solution
- Uses multi-line string with backslashes allowing rustfmt to work
properly in the surrounding area.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
The behavior of change detection within `PipeSystem` is very tricky and
subtle, and is not currently covered by any of our tests as far as I'm
aware.
# Objective
Upon closer inspection, there are a few functions in the ECS that are
not being inlined, even with the highest optimizations and LTO enabled:
- Almost all
[WorldQuery::init_fetch](9fd5f20e25/results/query_get.s (L57))
calls. Affects `Query::get` calls in hot loops. In particular, the
`WorldQuery` implementation for `()` is used *everywhere* as the default
filter and is effectively a no-op.
-
[Entities::get](9fd5f20e25/results/query_get.s (L39)).
Affects `Query::get`, `World::get`, and any component insertion or
removal.
-
[Entities::set](9fd5f20e25/results/entity_remove.s (L2487)).
Affects any component insertion or removal.
-
[Tick::new](9fd5f20e25/results/entity_insert.s (L1368)).
I've only seen this in component insertion and spawning.
- ArchetypeRow::new
- BlobVec::set_len
Almost all of these have trivial or even empty implementations or have
significant opportunity to be optimized into surrounding code when
inlined with LTO enabled.
## Solution
Inline them
# Objective
The method `World::try_run_schedule` currently panics if the `Schedules`
resource does not exist, but it should just return an `Err`. Similarly,
`World::add_schedule` panics unnecessarily if the resource does not
exist.
Also, the documentation for `World::add_schedule` is completely wrong.
## Solution
When the `Schedules` resource does not exist, we now treat it the same
as if it did exist but was empty. When calling `add_schedule`, we
initialize it if it does not exist.
# Objective
Fixes#8215 and #8152. When systems panic, it causes the main thread to
panic as well, which clutters the output.
## Solution
Resolves the panic in the multi-threaded scheduler. Also adds an extra
message that tells the user the system that panicked.
Using the example from the issue, here is what the messages now look
like:
```rust
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Update, panicking_system)
.run();
}
fn panicking_system() {
panic!("oooh scary");
}
```
### Before
```
Compiling bevy_test v0.1.0 (E:\Projects\Rust\bevy_test)
Finished dev [unoptimized + debuginfo] target(s) in 2m 58s
Running `target\debug\bevy_test.exe`
2023-03-30T22:19:09.234932Z INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19044", cpu: "AMD Ryzen 5 2600 Six-Core Processor", core_count: "6", memory: "15.9 GiB" }
thread 'Compute Task Pool (5)' panicked at 'oooh scary', src\main.rs:11:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'Compute Task Pool (5)' panicked at 'A system has panicked so the executor cannot continue.: RecvError', E:\Projects\Rust\bevy\crates\bevy_ecs\src\schedule\executor\multi_threaded.rs:194:60
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', E:\Projects\Rust\bevy\crates\bevy_tasks\src\task_pool.rs:376:49
error: process didn't exit successfully: `target\debug\bevy_test.exe` (exit code: 101)
```
### After
```
Compiling bevy_test v0.1.0 (E:\Projects\Rust\bevy_test)
Finished dev [unoptimized + debuginfo] target(s) in 2.39s
Running `target\debug\bevy_test.exe`
2023-03-30T22:11:24.748513Z INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19044", cpu: "AMD Ryzen 5 2600 Six-Core Processor", core_count: "6", memory: "15.9 GiB" }
thread 'Compute Task Pool (5)' panicked at 'oooh scary', src\main.rs:11:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_test::panicking_system`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
error: process didn't exit successfully: `target\debug\bevy_test.exe` (exit code: 101)
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
Fix#8191.
Currently, a state transition will be triggered whenever the `NextState`
resource has a value, even if that "transition" is to the same state as
the previous one. This caused surprising/meaningless behavior, such as
the existence of an `OnTransition { from: A, to: A }` schedule.
## Solution
State transition schedules now only run if the new state is not equal to
the old state. Change detection works the same way, only being triggered
when the states compare not equal.
---
## Changelog
- State transition schedules are no longer run when transitioning to and
from the same state.
## Migration Guide
State transitions are now only triggered when the exited and entered
state differ. This means that if the world is currently in state `A`,
the `OnEnter(A)` schedule (or `OnExit`) will no longer be run if you
queue up a state transition to the same state `A`.
# Objective
Noticed while writing #7728 that we are using `trace!` logs in our event
functions. This has shown to have significant overhead, even trace level
logs are disabled globally, as seen in #7639.
## Solution
Use the `detailed_trace!` macro introduced in #7639. Also removed the
`event_trace` function that was only used in one location.
---
## Changelog
Changed: Event trace logs are now feature gated behind the
`detailed-trace` feature.
# Objective
Fix#8321
## Solution
The `old_viewport_size` that is used to detect whether the viewport has
changed was not being updated and thus always `None`.
# Objective
Adds a new resource to control a global volume.
Fixes#7690
---
## Solution
Added a new resource to control global volume, this is then multiplied
with an audio sources volume to get the output volume, individual audio
sources can opt out of this my enabling the `absolute_volume` field in
`PlaybackSettings`.
---
## Changelog
### Added
- `GlobalVolume` a resource to control global volume (in prelude).
- `global_volume` field to `AudioPlugin` or setting the initial value of
`GlobalVolume`.
- `Volume` enum that can be `Relative` or `Absolute`.
- `VolumeLevel` struct for defining a volume level.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
when a mesh uses zero for all bone weights, vertices end up in the
middle of the screen.
## Solution
we can address this by explicitly setting the first bone weight to 1
when the weights are given as zero. this is the approach taken by
[unity](https://forum.unity.com/threads/whats-the-problem-with-this-import-fbx-warning.133736/)
(although that also sets the bone index to zero) and
[three.js](94c1a4b86f/src/objects/SkinnedMesh.js (L98)),
and likely other engines.
## Alternatives
it does add a bit of overhead, and users can always fix this themselves,
though it's a bit awkward particularly with gltfs.
(note - this is for work so my sme status shouldn't apply)
---------
Co-authored-by: ira <JustTheCoolDude@gmail.com>
# Objective
- Fix#7263
This has nothing to do with #7024. This is for the case where the
user opted to **not** keep the same global transform on update.
## Solution
- Add a `RemovedComponent<Parent>` to `propagate_transforms`
- Add a `RemovedComponent<Parent>` and `Local<Vec<Entity>>` to
`sync_simple_transforms`
- Add test to make sure all of this works.
### Performance note
This should only incur a cost in cases where a parent is removed.
A minimal overhead (one look up in the `removed_components`
sparse set) per root entities without children which transform didn't
change. A `Vec` the size of the largest number of entities removed
with a `Parent` component in a single frame, and a binary search on
a `Vec` per root entities.
It could slow up considerably in situations where a lot of entities are
orphaned consistently during every frame, since
`sync_simple_transforms` is not parallel. But in this situation,
it is likely that the overhead of archetype updates overwhelms
everything.
---
## Changelog
- Fix the `GlobalTransform` not getting updated when `Parent` is removed
## Migration Guide
- If you called `bevy_transform::systems::sync_simple_transforms` and
`bevy_transform::systems::propagate_transforms` (which is not
re-exported by bevy) you need to account for the additional
`RemovedComponents<Parent>` parameter.
---------
Co-authored-by: vyb <vyb@users.noreply.github.com>
Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Fixes#8333
# Objective
Fixes issue which causes failure to compile if using
`#![deny(missing_docs)]`.
## Solution
Added some very basic commenting to the generated read-only fields.
honestly I feel this to be up for debate since the comments are very
basic and give very little useful information but the purpose of this PR
is to fix the issue at hand.
---
## Changelog
Added comments to the derive macro and the projects now successfully
compile.
---------
Co-authored-by: lupan <kallll5@hotmail.com>
Fixes issue mentioned in PR #8285.
_Note: By mistake, this is currently dependent on #8285_
# Objective
Ensure consistency in the spelling of the documentation.
Exceptions:
`crates/bevy_mikktspace/src/generated.rs` - Has not been changed from
licence to license as it is part of a licensing agreement.
Maybe for further consistency,
https://github.com/bevyengine/bevy-website should also be given a look.
## Solution
### Changed the spelling of the current words (UK/CN/AU -> US) :
cancelled -> canceled (Breaking API changes in #8285)
behaviour -> behavior (Breaking API changes in #8285)
neighbour -> neighbor
grey -> gray
recognise -> recognize
centre -> center
metres -> meters
colour -> color
### ~~Update [`engine_style_guide.md`]~~ Moved to #8324
---
## Changelog
Changed UK spellings in documentation to US
## Migration Guide
Non-breaking changes*
\* If merged after #8285