# Objective
Fixes#13995.
## Solution
Override the default `Ctrl+C` handler with one that sends `AppExit`
event to every app with `TerminalCtrlCHandlerPlugin`.
## Testing
Tested by running the `3d_scene` example and hitting `Ctrl+C` in the
terminal.
---
## Changelog
Handles `Ctrl+C` in the terminal gracefully.
## Migration Guide
If you are overriding the `Ctrl+C` handler then you should call
`TerminalCtrlCHandlerPlugin::gracefully_exit` from your handler. It will
tell the app to exit.
Part of #13681
# Objective
gLTF Assets shouldn't be duplicated between Assets resource and node
children.
Also changed `asset_label` to be a method as [per previous PR
comment](https://github.com/bevyengine/bevy/pull/13558).
## Solution
- Made GltfNode children be Handles instead of asset copies.
## Testing
- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.
---
## Changelog
### Changed
- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.
## Migration Guide
If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.
#### Before
```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
for gltf_handle in gltf_component_query.iter() {
let gltf_root = gltf_assets.get(gltf_handle).unwrap();
let first_node_handle = gltf_root.nodes.get(0).unwrap();
let first_node = gltf_nodes.get(first_node_handle).unwrap();
let first_child = first_node.children.get(0).unwrap();
println!("First nodes child node name is {:?)", first_child.name);
}
}
```
#### After
```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
for gltf_handle in gltf_component_query.iter() {
let gltf_root = gltf_assets.get(gltf_handle).unwrap();
let first_node_handle = gltf_root.nodes.get(0).unwrap();
let first_node = gltf_nodes.get(first_node_handle).unwrap();
let first_child_handle = first_node.children.get(0).unwrap();
let first_child = gltf_nodes.get(first_child_handle).unwrap();
println!("First nodes child node name is {:?)", first_child.name);
}
}
```
# Objective
Allow combining render layers with a more-ergonomic syntax than
`RenderLayers::from_iter(a.iter().chain(b.iter()))`.
## Solution
Add the `or` operation (and corresponding `const` method) to allow
computing the union of a set of render layers. While we're here, also
added `and` and `xor` operations. Someone might find them useful
## Testing
Added a simple unit test.
# Objective
We're able to reflect types sooooooo... why not functions?
The goal of this PR is to make functions callable within a dynamic
context, where type information is not readily available at compile
time.
For example, if we have a function:
```rust
fn add(left: i32, right: i32) -> i32 {
left + right
}
```
And two `Reflect` values we've already validated are `i32` types:
```rust
let left: Box<dyn Reflect> = Box::new(2_i32);
let right: Box<dyn Reflect> = Box::new(2_i32);
```
We should be able to call `add` with these values:
```rust
// ?????
let result: Box<dyn Reflect> = add.call_dynamic(left, right);
```
And ideally this wouldn't just work for functions, but methods and
closures too!
Right now, users have two options:
1. Manually parse the reflected data and call the function themselves
2. Rely on registered type data to handle the conversions for them
For a small function like `add`, this isn't too bad. But what about for
more complex functions? What about for many functions?
At worst, this process is error-prone. At best, it's simply tedious.
And this is assuming we know the function at compile time. What if we
want to accept a function dynamically and call it with our own
arguments?
It would be much nicer if `bevy_reflect` could alleviate some of the
problems here.
## Solution
Added function reflection!
This adds a `DynamicFunction` type to wrap a function dynamically. This
can be called with an `ArgList`, which is a dynamic list of
`Reflect`-containing `Arg` arguments. It returns a `FunctionResult`
which indicates whether or not the function call succeeded, returning a
`Reflect`-containing `Return` type if it did succeed.
Many functions can be converted into this `DynamicFunction` type thanks
to the `IntoFunction` trait.
Taking our previous `add` example, this might look something like
(explicit types added for readability):
```rust
fn add(left: i32, right: i32) -> i32 {
left + right
}
let mut function: DynamicFunction = add.into_function();
let args: ArgList = ArgList::new().push_owned(2_i32).push_owned(2_i32);
let result: Return = function.call(args).unwrap();
let value: Box<dyn Reflect> = result.unwrap_owned();
assert_eq!(value.take::<i32>().unwrap(), 4);
```
And it also works on closures:
```rust
let add = |left: i32, right: i32| left + right;
let mut function: DynamicFunction = add.into_function();
let args: ArgList = ArgList::new().push_owned(2_i32).push_owned(2_i32);
let result: Return = function.call(args).unwrap();
let value: Box<dyn Reflect> = result.unwrap_owned();
assert_eq!(value.take::<i32>().unwrap(), 4);
```
As well as methods:
```rust
#[derive(Reflect)]
struct Foo(i32);
impl Foo {
fn add(&mut self, value: i32) {
self.0 += value;
}
}
let mut foo = Foo(2);
let mut function: DynamicFunction = Foo::add.into_function();
let args: ArgList = ArgList::new().push_mut(&mut foo).push_owned(2_i32);
function.call(args).unwrap();
assert_eq!(foo.0, 4);
```
### Limitations
While this does cover many functions, it is far from a perfect system
and has quite a few limitations. Here are a few of the limitations when
using `IntoFunction`:
1. The lifetime of the return value is only tied to the lifetime of the
first argument (useful for methods). This means you can't have a
function like `(a: i32, b: &i32) -> &i32` without creating the
`DynamicFunction` manually.
2. Only 15 arguments are currently supported. If the first argument is a
(mutable) reference, this number increases to 16.
3. Manual implementations of `Reflect` will need to implement the new
`FromArg`, `GetOwnership`, and `IntoReturn` traits in order to be used
as arguments/return types.
And some limitations of `DynamicFunction` itself:
1. All arguments share the same lifetime, or rather, they will shrink to
the shortest lifetime.
2. Closures that capture their environment may need to have their
`DynamicFunction` dropped before accessing those variables again (there
is a `DynamicFunction::call_once` to make this a bit easier)
3. All arguments and return types must implement `Reflect`. While not a
big surprise coming from `bevy_reflect`, this implementation could
actually still work by swapping `Reflect` out with `Any`. Of course,
that makes working with the arguments and return values a bit harder.
4. Generic functions are not supported (unless they have been manually
monomorphized)
And general, reflection gotchas:
1. `&str` does not implement `Reflect`. Rather, `&'static str`
implements `Reflect` (the same is true for `&Path` and similar types).
This means that `&'static str` is considered an "owned" value for the
sake of generating arguments. Additionally, arguments and return types
containing `&str` will assume it's `&'static str`, which is almost never
the desired behavior. In these cases, the only solution (I believe) is
to use `&String` instead.
### Followup Work
This PR is the first of two PRs I intend to work on. The second PR will
aim to integrate this new function reflection system into the existing
reflection traits and `TypeInfo`. The goal would be to register and call
a reflected type's methods dynamically.
I chose not to do that in this PR since the diff is already quite large.
I also want the discussion for both PRs to be focused on their own
implementation.
Another followup I'd like to do is investigate allowing common container
types as a return type, such as `Option<&[mut] T>` and `Result<&[mut] T,
E>`. This would allow even more functions to opt into this system. I
chose to not include it in this one, though, for the same reasoning as
previously mentioned.
### Alternatives
One alternative I had considered was adding a macro to convert any
function into a reflection-based counterpart. The idea would be that a
struct that wraps the function would be created and users could specify
which arguments and return values should be `Reflect`. It could then be
called via a new `Function` trait.
I think that could still work, but it will be a fair bit more involved,
requiring some slightly more complex parsing. And it of course is a bit
more work for the user, since they need to create the type via macro
invocation.
It also makes registering these functions onto a type a bit more
complicated (depending on how it's implemented).
For now, I think this is a fairly simple, yet powerful solution that
provides the least amount of friction for users.
---
## Showcase
Bevy now adds support for storing and calling functions dynamically
using reflection!
```rust
// 1. Take a standard Rust function
fn add(left: i32, right: i32) -> i32 {
left + right
}
// 2. Convert it into a type-erased `DynamicFunction` using the `IntoFunction` trait
let mut function: DynamicFunction = add.into_function();
// 3. Define your arguments from reflected values
let args: ArgList = ArgList::new().push_owned(2_i32).push_owned(2_i32);
// 4. Call the function with your arguments
let result: Return = function.call(args).unwrap();
// 5. Extract the return value
let value: Box<dyn Reflect> = result.unwrap_owned();
assert_eq!(value.take::<i32>().unwrap(), 4);
```
## Changelog
#### TL;DR
- Added support for function reflection
- Added a new `Function Reflection` example:
ba727898f2/examples/reflection/function_reflection.rs (L1-L157)
#### Details
Added the following items:
- `ArgError` enum
- `ArgId` enum
- `ArgInfo` struct
- `ArgList` struct
- `Arg` enum
- `DynamicFunction` struct
- `FromArg` trait (derived with `derive(Reflect)`)
- `FunctionError` enum
- `FunctionInfo` struct
- `FunctionResult` alias
- `GetOwnership` trait (derived with `derive(Reflect)`)
- `IntoFunction` trait (with blanket implementation)
- `IntoReturn` trait (derived with `derive(Reflect)`)
- `Ownership` enum
- `ReturnInfo` struct
- `Return` enum
---------
Co-authored-by: Periwink <charlesbour@gmail.com>
# Objective
- When no wgpu backend is selected, there should be a clear explanation.
- Fix a regression in 0.14 when not using default features. I hit this
compile failure when trying to build bevy_framepace for 0.14.0-rc.4
```
error[E0432]: unresolved import `crate::core_3d::DEPTH_TEXTURE_SAMPLING_SUPPORTED`
--> /Users/aevyrie/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_core_pipeline-0.14.0-rc.4/src/dof/mod.rs:59:19
|
59 | Camera3d, DEPTH_TEXTURE_SAMPLING_SUPPORTED,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `DEPTH_TEXTURE_SAMPLING_SUPPORTED` in `core_3d`
|
note: found an item that was configured out
--> /Users/aevyrie/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_core_pipeline-0.14.0-rc.4/src/core_3d/mod.rs:53:11
|
53 | pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = false;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: found an item that was configured out
--> /Users/aevyrie/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_core_pipeline-0.14.0-rc.4/src/core_3d/mod.rs:63:11
|
63 | pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = true;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
## Solution
- Ensure that `DEPTH_TEXTURE_SAMPLING_SUPPORTED` is either `true` or
`false`, it shouldn't be completely missing.
## Testing
- Building on WASM without default features, which now seemingly no
longer includes webgl, will panic on startup with a message saying that
no wgpu backend was selected. This is much more helpful than the compile
time failure:
```
No wgpu backend feature that is implemented for the target platform was enabled
```
- I can see an argument for making this a compile time failure, however
the current failure mode is very confusing for novice users, and
provides no clues for how to fix it. If we want this to fail at compile
time, we should do it in a way that fails with a helpful message,
similar to what this PR acheives.
# Objective
- Fixes#14059
- `morphed_skinned_mesh_layout` is the same as
`morphed_skinned_motion_mesh_layout` but shouldn't have the skin / morph
from previous frame, as they're used for motion
## Solution
- Remove the extra entries
## Testing
- Run with the glTF file reproducing #14059, it works
# Objective / Solution
Make it possible to construct `Material2dBindGroupId` for custom 2D
material pipelines by making the inner field public.
---
The 3D variant (`MaterialBindGroupId`) had this done in
e79b9b62ce
# Objective
- Fixes a correctness error introduced in
https://github.com/bevyengine/bevy/pull/14013 ...
## Solution
I've been playing around a lot of with the access code and I realized
that I introduced a soundness error when trying to simplify the code.
When we have a `Or<(With<A>, With<B>)>` filter, we cannot call
```
let mut intermediate = FilteredAccess::default();
$name::update_component_access($name, &mut intermediate);
_new_access.append_or(&intermediate);
```
because that's just equivalent to adding the new components as `Or`
clauses.
For example if the existing `filter_sets` was `vec![With<C>]`, we would
then get `vec![With<C>, With<A>, With<B>]` which translates to `A or B
or C`.
Instead what we want is `(A and B) or (A and C)`, so we need to have
each new OR clause compose with the existing access like so:
```
let mut intermediate = _access.clone();
// if we previously had a With<C> in the filter_set, this will become `With<C> AND With<A>`
$name::update_component_access($name, &mut intermediate);
_new_access.append_or(&intermediate);
```
## Testing
- Added a unit test that is broken in main, but passes in this PR
# Objective
`sickle_ui` needs `PartialEq` on components to turn them into animatable
style attributes.
## Solution
All properties of Outline is already `PartialEq`, add derive on
`Outline` as well.
## Testing
- used `sickle_ui` to test if it can be made animatable
As reported in #14004, many third-party plugins, such as Hanabi, enqueue
entities that don't have meshes into render phases. However, the
introduction of indirect mode added a dependency on mesh-specific data,
breaking this workflow. This is because GPU preprocessing requires that
the render phases manage indirect draw parameters, which don't apply to
objects that aren't meshes. The existing code skips over binned entities
that don't have indirect draw parameters, which causes the rendering to
be skipped for such objects.
To support this workflow, this commit adds a new field,
`non_mesh_items`, to `BinnedRenderPhase`. This field contains a simple
list of (bin key, entity) pairs. After drawing batchable and unbatchable
objects, the non-mesh items are drawn one after another. Bevy itself
doesn't enqueue any items into this list; it exists solely for the
application and/or plugins to use.
Additionally, this commit switches the asset ID in the standard bin keys
to be an untyped asset ID rather than that of a mesh. This allows more
flexibility, allowing bins to be keyed off any type of asset.
This patch adds a new example, `custom_phase_item`, which simultaneously
serves to demonstrate how to use this new feature and to act as a
regression test so this doesn't break again.
Fixes#14004.
## Changelog
### Added
* `BinnedRenderPhase` now contains a `non_mesh_items` field for plugins
to add custom items to.
# Objective
`StaticSystemParam` should delegate all `SystemParam` methods to the
inner param, but it looks like it was missed when the new `queue()`
method was added in #10839.
## Solution
Implement `StaticSystemParam::queue()` to delegate to the inner param.
The comment was incorrect - we are already looking at the pyramid
texture so we do not need to transform the size in any way. Doing that
resulted in a mip that was too fine to be selected in certain cases,
which resulted in a 2x2 pixel footprint not actually fully covering the
cluster sphere - sometimes this could lead to a non-conservative depth
value being computed which resulted in the cluster being marked as
invisible incorrectly.
This change updates meshopt-rs to 0.3 to take advantage of the newly
added sparse simplification mode: by default, simplifier assumes that
the entire mesh is simplified and runs a set of calculations that are
O(vertex count), but in our case we simplify many small mesh subsets
which is inefficient.
Sparse mode instead assumes that the simplified subset is only using a
portion of the vertex buffer, and optimizes accordingly. This changes
the meaning of the error (as it becomes relative to the subset, in our
case a meshlet group); to ensure consistent error selection, we also use
the ErrorAbsolute mode which allows us to operate in mesh coordinate
space.
Additionally, meshopt 0.3 runs optimizeMeshlet automatically as part of
`build_meshlets` so we no longer need to call it ourselves.
This reduces the time to build meshlet representation for Stanford Bunny
mesh from ~1.65s to ~0.45s (3.7x) in optimized builds.
# Objective
Implement `BuildChildrenTransformExt` for `EntityWorldMut`, which is
useful when working directly with a mutable `World` ref.
## Solution
I realize this isn't the most optimal implementation in that it doesn't
reuse the existing entity location for the child, but it is terse and
reuses the existing code. I can address that if needed.
## Testing
I only tested locally. There are no tests for `set_parent_in_place` and
`remove_parent_in_place` currently, but I can add some.
---
## Changelog
`BuildChildrenTransformExt` implemented for `EntityWorldMut`.
# Objective
When using combinators such as `EntityCommand::with_entity` to build
commands, it can be easy to forget to apply that command, leading to
dead code. In many cases this doesn't even lead to an unused variable
warning, which can make these mistakes difficult to track down
## Solution
Annotate the method with `#[must_use]`
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Second part of #13900
- based on #13905
## Solution
- check_dir_light_mesh_visibility defers setting the entity's
`ViewVisibility `so that Bevy can schedule it to run in parallel with
`check_point_light_mesh_visibility`.
- Reduce HashMap lookups for directional light checking as much as
possible
- Use `par_iter `to parallelize the checking process within each system.
---------
Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
# Objective
The trait method `with_entity` is used to add an `EntityCommand` to the
command queue. Currently this method returns `WithEntity<C>` which pairs
a command with an `Entity`. By replacing this explicit type with an
opaque type, implementors can override this default implementation by
returning a custom command or closure that does the same thing with a
lower memory footprint.
# Solution
Return an opaque type from the method. As a bonus this file is now
cleaner without the `WithEntity` boilerplate
# Objective
Numerous people have been confused that Bevy runs slowly, when the
reason is that the `llvmpipe` software rendered is being used.
## Solution
Printing a warning could reduce the confusion.
# Objective
- Fixes#13728
## Solution
- add a new feature `smaa_luts`. if enables, it also enables `ktx2` and
`zstd`. if not, it doesn't load the files but use placeholders instead
- adds all the resources needed in the same places that system that uses
them are added.
# Objective
Fixes https://github.com/bevyengine/bevy/issues/13993
PR inspired by https://github.com/bevyengine/bevy/pull/14007 to
accomplish the same thing, but maybe in a clearer fashion.
@Gingeh feel free to take my changes and add them to your PR, I don't
want to steal any credit
---------
Co-authored-by: Gingeh <39150378+Gingeh@users.noreply.github.com>
Co-authored-by: Bob Gardner <rgardner@inworld.ai>
Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
# Objective
In Bevy 0.13, `BackgroundColor` simply tinted the image of any
`UiImage`. This was confusing: in every other case (e.g. Text), this
added a solid square behind the element. #11165 changed this, but
removed `BackgroundColor` from `ImageBundle` to avoid confusion, since
the semantic meaning had changed.
However, this resulted in a serious UX downgrade / inconsistency, as
this behavior was no longer part of the bundle (unlike for `TextBundle`
or `NodeBundle`), leaving users with a relatively frustrating upgrade
path.
Additionally, adding both `BackgroundColor` and `UiImage` resulted in a
bizarre effect, where the background color was seemingly ignored as it
was covered by a solid white placeholder image.
Fixes#13969.
## Solution
Per @viridia's design:
> - if you don't specify a background color, it's transparent.
> - if you don't specify an image color, it's white (because it's a
multiplier).
> - if you don't specify an image, no image is drawn.
> - if you specify both a background color and an image color, they are
independent.
> - the background color is drawn behind the image (in whatever pixels
are transparent)
As laid out by @benfrankel, this involves:
1. Changing the default `UiImage` to use a transparent texture but a
pure white tint.
2. Adding `UiImage::solid_color` to quickly set placeholder images.
3. Changing the default `BorderColor` and `BackgroundColor` to
transparent.
4. Removing the default overrides for these values in the other assorted
UI bundles.
5. Adding `BackgroundColor` back to `ImageBundle` and `ButtonBundle`.
6. Adding a 1x1 `Image::transparent`, which can be accessed from
`Assets<Image>` via the `TRANSPARENT_IMAGE_HANDLE` constant.
Huge thanks to everyone who helped out with the design in the linked
issue and [the Discord
thread](https://discord.com/channels/691052431525675048/1255209923890118697/1255209999278280844):
this was very much a joint design.
@cart helped me figure out how to set the UiImage's default texture to a
transparent 1x1 image, which is a much nicer fix.
## Testing
I've checked the examples modified by this PR, and the `ui` example as
well just to be sure.
## Migration Guide
- `BackgroundColor` no longer tints the color of images in `ImageBundle`
or `ButtonBundle`. Set `UiImage::color` to tint images instead.
- The default texture for `UiImage` is now a transparent white square.
Use `UiImage::solid_color` to quickly draw debug images.
- The default value for `BackgroundColor` and `BorderColor` is now
transparent. Set the color to white manually to return to previous
behavior.
# Objective
- Fixes#13811 (probably, I lost my test code...)
## Solution
- Turns out that Queue and PrepareAssets are _not_ ordered. We should
probably either rethink our system sets (again), or improve the
documentation here. For reference, I've included the current ordering
below.
- The `prepare_meshlet_meshes_X` systems need to run after
`prepare_assets::<PreparedMaterial<M>>`, and have also been moved to
QueueMeshes.
```rust
schedule.configure_sets(
(
ExtractCommands,
ManageViews,
Queue,
PhaseSort,
Prepare,
Render,
Cleanup,
)
.chain(),
);
schedule.configure_sets((ExtractCommands, PrepareAssets, Prepare).chain());
schedule.configure_sets(QueueMeshes.in_set(Queue).after(prepare_assets::<GpuMesh>));
schedule.configure_sets(
(PrepareResources, PrepareResourcesFlush, PrepareBindGroups)
.chain()
.in_set(Prepare),
);
```
## Testing
- Ambiguity checker to make sure I don't have ambiguous system ordering
# Objective
#12469 changed the `Debug` impl for `Entity`, making sure it's actually
accurate for debugging. To ensure that its can still be readily logged
in error messages and inspectors, this PR added a more concise and
human-friendly `Display` impl.
However, users found this form too verbose: the `to_bits` information
was unhelpful and too long. Fixes#13980.
## Solution
- Don't include `Entity::to_bits` in the `Display` implementation for
`Entity`. This information can readily be accessed and logged for users
who need it.
- Also clean up the implementation of `Display` for `DebugName`,
introduced in https://github.com/bevyengine/bevy/pull/13760, to simply
use the new `Display` impl (since this was the desired format there).
## Testing
I've updated an existing test to verify the output of `Entity::display`.
---------
Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
# Objective
- Fix issue #13821
## Solution
- Rewrote the test to ensure that it actually tests the functionality
correctly. Then made the par_read function correctly change the values
of self.reader.last_event_count.
## Testing
- Rewrote the test for par_read to run the system schedule twice,
checking the output each time
---------
Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/14003
## Solution
- Expose an API to perform updates for a specific sub-app, so we can
avoid mutable borrow the app twice.
## Testing
- I have tested the API by modifying the code in the `many_lights`
example with the following changes:
```rust
impl Plugin for LogVisibleLights {
fn build(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app.add_systems(Render, print_visible_light_count.in_set(RenderSet::Prepare));
}
fn finish(&self, app: &mut App) {
app.update_sub_app_by_label(RenderApp);
}
}
```
---
## Changelog
- add the `update_sub_app_by_label` API to `App` and `SubApps`.
---------
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
# Objective
- When writing "in game" debugging tools, quite often you need the name
of an entity (for example an entity tree). DebugName is the usual way of
doing that.
- A recent change to Entity's Debug implementation meant it was no
longer a minimal {index}v{generation} but instead a more verbose auto
generated Debug.
- This made DebugName's Debug implementation also verbose
## Solution
- I changed DebugName to derive Debug automatically and added a new
(preferred) Display implementation for it which is the preferred name
for an entity. If the entity has a Name component its the contents of
that, otherwise it is {index}v{generation} (though this does not use
Display of the Entity as that is more verbose than this).
## Testing
- I've added a new test in name.rs which tests the Display
implementation for DebugName by using to_string.
---
## Migration Guide
- In code which uses DebugName you should now use the Display
implementation rather than the Debug implementation (ie {} instead of
{:?} if you were printing it out).
---------
Co-authored-by: John Payne <20407779+johngpayne@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
Co-authored-by: Andres O. Vela <andresovela@users.noreply.github.com>
fixes#13944
I literally just added `Did you forget to call SystemState::apply?` to
the error message. I tested it with the code snipped from the Issue and
yeah it works
# Objective
Fixes#13982
## Solution
~~Adds a new field to `bevy_log::LogPlugin`: `ansi: bool`~~
Documents the use of `std::env::set_var("NO_COLOR", "1");` to disable
colour output in terminals.
## Testing
Yes, all tests passed when I ran `cargo run -p ci -- test` and `cargo
run -p ci -- lints`
I have only tested the code on my Mac, though I doubt this change would
have any affect on other platforms.
---
# Objective
Closes#5943. Seems like Assets v2 solved this one.
## Solution
Added a test to confirm that using `Reflect::clone_value` and then
`FromReflect::from_reflect` on a `Handle<T>` both increment the strong
count.
## Testing
A new test was added to confirm behavior.
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
Tight, in-frame generation, re-parenting, despawning, etc., UI
operations could sometime lead taffy to panic (invalid SlotMap key used)
when an entity with an invalid state later despawned.
Fixes#12403
## Solution
Move the `remove_entities` call after children updates.
## Testing
`sickle_ui` had a case that always caused the panic. Tested before this
change, after this change, and before the change again to make sure the
error is there without the fix. The fix worked. Test steps and used
commit described in issue #12403.
I have also ran every bevy UI example, though none of them deal with
entity re-parenting or removal. No regression detected on them.
Tested on Windows only.
* Fixes https://github.com/bevyengine/bevy/issues/13813
* Fixes https://github.com/bevyengine/bevy/issues/13810
Tested a combined scene with both regular meshes and meshlet meshes
with:
* Regular forward setup
* Forward + normal/motion vector prepasses
* Deferred (with depth prepass since that's required)
* Deferred + depth/normal/motion vector prepasses
Still broken:
* Using meshlet meshes rendering in deferred and regular meshes
rendering in forward + depth/normal prepass. I don't know how to fix
this at the moment, so for now I've just add instructions to not mix
them.
# Objective
`with_event` will result in unsafe casting of event data of the given
type to the type expected by the Observer system. This is inherently
unsafe.
## Solution
Flag `Observer::with_event` and `ObserverDescriptor::with_events` as
unsafe. This will not affect normal workflows as `with_event` is
intended for very specific (largely internal) use cases.
This _should_ be backported to 0.14 before release.
---
## Changelog
- `Observer::with_event` is now unsafe.
- Rename `ObserverDescriptor::with_triggers` to
`ObserverDescriptor::with_events` and make it unsafe.
# Objective
- Fixes#13702
- When creating a new window, its scale was changed to match the one
returned by winit, but its size was not which resulted in an incorrect
size until the event with the correct size was received, at least 1
frame later
## Solution
- Apply the window scale to its size when creating it
I updated my 'main' branch, which accidentally closed the original PR
#13747. I'm reopening the this from an actual branch on my repo like I
should have done in the first place. Here's the original info from the
first PR:
* * *
# Problem
The `file_watcher` feature panics if the file_watcher's path "assets" is
not present. I stumbled upon this behavior when I was actually testing
against `embedded_watcher`. I had no "assets" directory and didn't need
one for [my project](https://github.com/shanecelis/bevy_plane_cut).
```text
$ cargo run --example simple; # Runs fine.
$ cargo run --example simple --feature embedded_watcher; # Panics
thread 'main' panicked at /Users/shane/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_asset-0.14.0-rc.2/src/io/source.rs:503:21:
Failed to create file watcher from path "assets", Error { kind: PathNotFound, paths: ["/Users/shane/Projects/bevy_plane_cut/assets"] }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
# Opinion
If a project runs without panicing, then adding the `file_watcher`
feature shouldn't cause it to panic.
# Suggested Solution
This PR suggests if the "assets" path does not exist, emit a warning
stating that the file watcher could not be created and why. All other
errors will be treated as before with a panic and a message.
```text
$ cargo run --example simple --feature embedded_watcher; # Panics
2024-06-08T08:55:11.385249Z WARN bevy_asset::io::source: Skip creating file watcher because path "assets" does not exist.
2024-06-08T08:55:11.385291Z WARN bevy_asset::io::source: AssetSourceId::Default does not have an AssetWatcher configured. Consider enabling the `file_watcher` feature.
```
The second warning is new and I'd prefer it didn't emit under this
condition, but I'll wait to see whether this is actually regarded as a
bug.
# Testing
No tests added. Compiled against my project and it demonstrated the
suggested behavior.
* * *
I changed the second warning to the following when the `file_watcher`
feature is present. When it's not present, it uses the same warning as
before.
```
024-06-09T01:22:16.880619Z WARN bevy_asset::io::source: Skip creating file watcher because path "assets" does not exist.
2024-06-09T01:22:16.880660Z WARN bevy_asset::io::source: AssetSourceId::Default does not have an AssetWatcher configured. Consider adding an "assets" directory.
```
This is an attempt to address issue #13725, which was about the
geometric primitives in the bevy_math crate lacking some detail in the
docs.
# Objective
Fixes#13725
## Solution
Added details to the docstrings. Mostly this consisted of specifying
that the primitives are centered on the origin, or describing how
they're defined (e.g., a circle is the set of all points some distance
from the origin).
## Testing
No testing, since the only changes were to docs.
Fixes#13701
After `winit` upgrade to `0.31`, windows were no longer correctly
resizing. This appears to just have been a simple mistake, where the new
physical size was being sourced from the `winit` window rather than on
the incoming `Window` component.
## Testing
Tested on macOS, but I'm curious whether this was also broken on other
platforms.
# Objective
Fixes#13866
## Solution
Add `insert_before` in **FixedMainScheduleOrder** and
**MainScheduleOrder**, add `insert_startup_before` in
**MainScheduleOrder**, applying the same logic as `insert_after`, except
for parameters naming and insertion index.
This is a followup to https://github.com/bevyengine/bevy/pull/13904
based on the discussion there, and switches two HashMaps that used
meshlet ids as keys to Vec.
In addition to a small further performance boost for `from_mesh` (1.66s
=> 1.60s), this makes processing deterministic modulo threading issues
wrt CRT rand described in the linked PR. This is valuable for debugging,
as you can visually or programmatically inspect the meshlet distribution
before/after making changes that should not change the output, whereas
previously every asset rebuild would change the meshlet structure.
Tested with https://github.com/bevyengine/bevy/pull/13431; after this
change, the visual output of meshlets is consistent between asset
rebuilds, and the MD5 of the output GLB file does not change either,
which was not the case before.
# Objective
- Make primitive meshing behavior consisten across platforms
- Avoid using sizes bigger than `u32` since these aren't even supported
for meshes
## Solution
- Use `u32` instead of `usize` for resolution/subdivisions/segments/etc
fields
---
## Changelog
- Change resolutions in primitive mesh builders from `usize` to `u32`
## Migration Guide
- All primitive mesh builders now take `u32` instead of `usize` for
their resolution/subdivision/segment counts
# Objective
Fixes#13920
## Solution
As described in the issue.
## Testing
Moved a custom transition plugin in example before any of the app-state
methods.
# Objective
Fixes#13933.
## Solution
Changed the return type.
## Testing
Fixed and reused the pre-existing tests for `inspect_entity`.
---
## Migration Guide
- `World::inspect_entity` now returns an `Iterator` instead of a `Vec`.
If you need a `Vec`, immediately collect the iterator:
`world.inspect_entity(entity).collect<Vec<_>>()`
# Objective
Fixes#13845
## Solution
Fix inline docs links inside `init_state` and `insert_state`.
## Testing
- Did you test these changes? If so, how?
Manually checked on `cargo doc` and `rust-analyzer lsp`.
# Objective
Fix a 9-slice asymmetric border issue that
[QueenOfSquiggles](https://blobfox.coffee/@queenofsquiggles/112639035165575222)
found. Here's the behavior before:
<img width="340" alt="the-bug"
src="https://github.com/bevyengine/bevy/assets/54390/81ff1847-b2ea-4578-9fd0-af6ee96c5438">
## Solution
Here's the behavior with the fix.
<img width="327" alt="the-fix"
src="https://github.com/bevyengine/bevy/assets/54390/33a4e3f0-b6a8-448e-9654-1197218ea11d">
## Testing
I used QueenOfSquiggles
[repo](https://github.com/QueenOfSquiggles/my-bevy-learning-project) to
exercise the code. I manually went through a number of variations of the
border and caught a few other issues after the first pass. I added some
code to create random borders and though they often looked funny there
weren't any gaps like before.
### Unit Tests
I did add some tests to `slicer.rs` mostly as an exploratory programming
exercise. So they currently act as a limited, incomplete,
"golden-file"-ish approach. Perhaps they're not worth keeping.
In order to write the tests, I did add a `PartialEq` derive for
`TextureSlice`.
I only tested these changes on macOS.
---
## Changelog
Make 9-slice textures work with asymmetric borders.