Commit Graph

5271 Commits

Author SHA1 Message Date
robtfm
6e2f96f222
check sampler type in as_bind_group derives (#12637)
# Objective

currently if we use an image with the wrong sampler type in a material,
wgpu panics with an invalid texture format. turn this into a warning and
fail more gracefully.

## Solution

the expected sampler type is specified in the AsBindGroup derive, so we
can just check the image sampler is what it should be.

i am not totally sure about the mapping of image sampler type to
#[sampler(type)], i assumed:

```
    "filtering" => [ TextureSampleType::Float { filterable: true } ],
    "non_filtering" => [
        TextureSampleType::Float { filterable: false },
        TextureSampleType::Sint,
        TextureSampleType::Uint,
    ],
    "comparison" => [ TextureSampleType::Depth ],
```
2024-08-21 01:41:31 +00:00
Zachary Harrold
f59a6a971a
Added Documentation to all_tuples_with_size (#14832)
# Objective

- Fixes #14684

## Solution

- Added documentation to `all_tuples_with_size` based on existing
`all_tuples` documentation.
- Updated `all_tuples` documentation to match formatting of and link
back to `all_tuples_with_size`

## Testing

- Doctests ran locally.

## Notes

Formatting changes I have proposed make the documentation a little
cleaner in my opinion, but I am open to reverting them and amending
`all_tuples_with_size` to match if there are any reasonable objections.
2024-08-20 11:12:44 +00:00
Alice Cecile
ba2847929f
Revert "Add conversions between Visibility and bool (#14784)" (#14830)
This reverts commit e37bf18e2b, added in
#14784.

# Objective

The PR was fine, but the work was very poorly motivated and the
resulting API is not actually very nice. The actual user need is likely
better addressed by #14825.

## Solution

Revert the offending PR.
2024-08-20 11:08:46 +00:00
Zachary Harrold
491aec8e5b
Generalized Into<AssetSourceId> and Into<AssetPath> Implementations over Lifetime (#10823)
# Objective

- Fixes #10478

## Solution

Generalised `From/Into` implementations over `&str` and `Option<&str>`
for `AssetSourceId` and `AssetPath` across all lifetimes, not just
static. To maintain access to the `'static`-only specialisation, these
types (and `CowArc`) now include an `as_static` method which will apply
the specialisation.

```rust
// Snipped from `AssetApp`
fn register_asset_source(
    &mut self,
    id: impl Into<AssetSourceId<'static>>,
    //                          ^^^^^^^
    //                          | as_static is only available for 'static lifetimes
    source: AssetSourceBuilder,
) -> &mut Self {
    let id = id.into().as_static();
    //          ^^^^^^ ^^^^^^^^^
    //          |      | Specialized (internally storing CowArc::Static)
    //          | Generic Into (internally storing CowArc::Borrowed)
    
    // ...
}
```

This post-fix specialisation is available here because the actual
specialisation performed is only a marker for if/when modification or
ownership is required, making the transform a very cheap operation. For
cleanliness, I've also added `from_static`, which wraps this behaviour
in a clean shorthand designed to replace `from` calls.

---

## Changelog

- Generalised the following implementations over a generic lifetime:
  - `From<&'static str> for AssetSourceId<'static>`
  - `From<Option<&'static str>> for AssetSourceId<'static>`
  - `From<&'static str> for AssetPath<'static>`
  - `From<&'static Path> for AssetPath<'static>`
- Added `as_static` specialisation to:
  - `CowArc`
  - `AssetSourceId`
  - `AssetPath`
- Added `from_static` specialised constructor to:
  - `AssetSourceId`
  - `AssetPath`

## Migration Guide

In areas where these implementations where being used, you can now add
`from_static` in order to get the original specialised implementation
which avoids creating an `Arc` internally.

```rust
// Before
let asset_path = AssetPath::from("my/path/to/an/asset.ext");

// After
let asset_path = AssetPath::from_static("my/path/to/an/asset.ext");
```

To be clear, this is only required if you wish to maintain the
performance benefit that came with the specialisation. Existing code is
_not_ broken by this change.
2024-08-19 23:41:46 +00:00
Gino Valente
2b4180ca8f
bevy_reflect: Function reflection terminology refactor (#14813)
# Objective

One of the changes in #14704 made `DynamicFunction` effectively the same
as `DynamicClosure<'static>`. This change meant that the de facto
function type would likely be `DynamicClosure<'static>` instead of the
intended `DynamicFunction`, since the former is much more flexible.

We _could_ explore ways of making `DynamicFunction` implement `Copy`
using some unsafe code, but it likely wouldn't be worth it. And users
would likely still reach for the convenience of
`DynamicClosure<'static>` over the copy-ability of `DynamicFunction`.

The goal of this PR is to fix this confusion between the two types.

## Solution

Firstly, the `DynamicFunction` type was removed. Again, it was no
different than `DynamicClosure<'static>` so it wasn't a huge deal to
remove.

Secondly, `DynamicClosure<'env>` and `DynamicClosureMut<'env>` were
renamed to `DynamicFunction<'env>` and `DynamicFunctionMut<'env>`,
respectively.

Yes, we still ultimately kept the naming of `DynamicFunction`, but
changed its behavior to that of `DynamicClosure<'env>`. We need a term
to refer to both functions and closures, and "function" was the best
option.


[Originally](https://discord.com/channels/691052431525675048/1002362493634629796/1274091992162242710),
I was going to go with "callable" as the replacement term to encompass
both functions and closures (e.g. `DynamciCallable<'env>`). However, it
was
[suggested](https://discord.com/channels/691052431525675048/1002362493634629796/1274653581777047625)
by @SkiFire13 that the simpler "function" term could be used instead.

While "callable" is perhaps the better umbrella term—being truly
ambiguous over functions and closures— "function" is more familiar, used
more often, easier to discover, and is subjectively just
"better-sounding".

## Testing

Most changes are purely swapping type names or updating documentation,
but you can verify everything still works by running the following
command:

```
cargo test --package bevy_reflect
```
2024-08-19 21:52:36 +00:00
robtfm
75738ed80f
catch asset loader panics (#14809)
# Objective

currently if an asset loader panics, the asset is left in a perpetual
`Loading` state. this can occur with external crates (eg the image crate
panics on bad data). catch this panic and resolve the asset to `Failed`

## Solution

`AssertUnwindSafe(loader.load).catch_unwind()` and map the panic to an
`AssetLoadError`

separated out from #13170
2024-08-19 21:50:39 +00:00
Rob Parrett
618cf7f51d
Remove useless Direction field (#14793)
# Objective

Delete some code that isn't actually doing anything. This was actually
discovered way back in this obsolete PR: #5513.

Also Fixes #6286

## Solution

Delete it

## Alternatives

Make `Direction` do things. But it's not totally clear to me if it's
possible to override cosmic-text's unicode bidi stuff.

## Migration Guide

`Style` no longer has a `direction` field, and `Direction` has been
deleted. They didn't do anything, so you can delete any references to
them as well.
2024-08-19 21:45:28 +00:00
Stanisław Kawulok
e37bf18e2b
Add conversions between Visibility and bool (#14784)
# Objective

Fixes #14521. 

## Solution

Added to methods to the VIsibility. 
```rs
is_visible() -> Result<bool, String>
```
 and 
```rs
visbility_from_bool(bool) -> Visibility
```

## Testing

Ran 
* `cargo run -p ci -- lints`
* `cargo run -p ci -- test`
* `cargo run -p ci -- compile`
it seems to be working. 
However I got few error messages :`ERROR bevy_log: could not set global
logger and tracing subscriber as they are already set. Consider
disabling LogPlugin` in `cargo run -p ci -- test`, even though all test
passed. I'm not sure if that's expected behaviour

Ps. I'm new to contributing, please correct me if anything is wrong
2024-08-19 21:40:54 +00:00
Robert Walter
d2fa55db6b
New utility methods on InfinitePlane3d (#14651)
# Objective

Some algorithms don't really work well or are not efficient in 3D space.
When we know we have points on an `InfinitePlane3d` it would be helpful
to have some utility methods to reversibly transform points on the plane
to 2D space to apply some algorithms there.

## Solution

This PR adds a few of methods to project 3D points on a plane to 2D
points and inject them back. Additionally there are some other small
common helper methods.

## Testing

- added some tests that cover the new methods

---------

Co-authored-by: Matty <weatherleymatthew@gmail.com>
2024-08-19 21:36:18 +00:00
Periwink
eaa805102d
add docs explaining the two accesses of a System meta (#14580)
# Objective

When reading the ECS code it is sometimes confusing to understand why we
have 2 accesses, one of ComponentId and one of ArchetypeComponentId


## Solution

Make the usage of these 2 accesses more explicit

---------

Co-authored-by: Pascal Hertleif <killercup@gmail.com>
2024-08-19 21:32:45 +00:00
Luca Della Vedova
6d3b2faf8a
Fix commands not being Send / Sync in 0.14 (#14392)
# Objective

Fixes Commands not being `Send` or `Sync` anymore in 0.14 by
implementing `Send` and `Sync` for `RawCommandQueue`.

## Solution

Reference discussion in
[discord](https://discord.com/channels/691052431525675048/691052431974465548/1259464518539411570).
It seems that in https://github.com/bevyengine/bevy/pull/13249, when
adding a `RawCommandQueue` variant to the `InternalQueue`, the `Send /
Sync` traits were not implemented for it, which bubbled up all the way
to `Commands` not being `Send / Sync` anymore.
I am not very familiar with the ECS internals so I can't say whether the
`RawCommandQueue` is safe to be shared between threads, but I know for
sure that before the linked PR `Commands` were indeed `Send` and `Sync`
so that PR broke "some workflows" (mandatory
[xkcd](https://xkcd.com/1172/)).

## Testing

This PR itself includes a compile test to make sure `Commands` will
implement `Send` and `Sync`. The test itself fails without the
implementation and succeeds with it.
Furthermore, if I cherry pick the test to a previous release (i.e. 0.13)
it indeed succeeds, showing that this is a regression specific to 0.14.

---------

Signed-off-by: Luca Della Vedova <lucadv@intrinsic.ai>
2024-08-19 21:29:30 +00:00
Robin KAY
defeeb375b
Fix size of MeshVertexAttributeId to be platform independent (#6624)
# Objective

`MeshVertexAttributeId` is currently a wrapper type around a `usize`.
Application developers are exposed to the `usize` whenever they need to
define a new custom vertex attribute, which requires them to generate a
random `usize` ID to avoid clashes with any other custom vertex
attributes in the same application. As the range of a `usize` is
platform dependent, developers on 64-bit machines may inadvertently
generate random values which will fail to compile for a 32-bit target.
The use of a `usize` here encourages non-portable behaviour and should
be replaced with a fixed width type.

## Solution

In this PR I have changed the ID type from `usize` to `u64`, but equally
a `u32` could be used at the risk of breaking some extant non-portable
programs and increasing the chance of an ID collision.
2024-08-19 21:09:20 +00:00
Gino Valente
423285cf1c
bevy_reflect: Store functions as DynamicClosure<'static> in FunctionRegistry (#14704)
# Objective

#14098 added the `FunctionRegistry` for registering functions such that
they can be retrieved by name and used dynamically. One thing we chose
to leave out in that initial PR is support for closures.

Why support closures? Mainly, we don't want to prohibit users from
injecting environmental data into their registered functions. This
allows these functions to not leak their internals to the public API.

For example, let's say we're writing a library crate that allows users
to register callbacks for certain actions. We want to perform some
actions before invoking the user's callback so we can't just call it
directly. We need a closure for this:

```rust
registry.register("my_lib::onclick", move |event: ClickEvent| {
    // ...other work...

    user_onclick.call(event); // <-- Captured variable
});
```

We could have made our callback take a reference to the user's callback.
This would remove the need for the closure, but it would change our
desired API to place the burden of fetching the correct callback on the
caller.

## Solution

Modify the `FunctionRegistry` to store registered functions as
`DynamicClosure<'static>` instead of `DynamicFunction` (now using
`IntoClosure` instead of `IntoFunction`).

Due to limitations in Rust and how function reflection works,
`DynamicClosure<'static>` is functionally equivalent to
`DynamicFunction`. And a normal function is considered a subset of
closures (it's a closure that doesn't capture anything), so there
shouldn't be any difference in usage: all functions that satisfy
`IntoFunction` should satisfy `IntoClosure`.

This means that the registration API introduced in #14098 should require
little-to-no changes on anyone following `main`.

### Closures vs Functions

One consideration here is whether we should keep closures and functions
separate.

This PR unifies them into `DynamicClosure<'static>`, but we can consider
splitting them up. The reasons we might want to do so are:

- Simplifies mental model and terminology (users don't have to
understand that functions turn into closures)
- If Rust ever improves its function model, we may be able to add
additional guarantees to `DynamicFunction` that make it useful to
separate the two
- Adding support for generic functions may be less confusing for users
since closures in Rust technically can't be generic

The reasons behind this PR's unification approach are:

- Reduces the number of methods needed on `FunctionRegistry`
- Reduces the number of lookups a user may have to perform (i.e.
"`get_function` or else `get_closure`")
- Establishes `DynamicClosure<'static>` as the de facto dynamic callable
(similar to how most APIs in Rust code tend to prefer `impl Fn() ->
String` over `fn() -> String`)

I'd love to hear feedback on this matter, and whether we should continue
with this PR's approach or switch to a split model.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```

---

## Showcase

Closures can now be registered into the `FunctionRegistry`:

```rust
let punct = String::from("!!!");

registry.register_with_name("my_crate::punctuate", move |text: String| {
  format!("{}{}", text, punct)
});
```
2024-08-17 00:20:47 +00:00
Alice Cecile
da529ff09e
Ignore PipelineCache ambiguities (#14772)
# Objective

The `prepare_view_upscaling_pipelines` system has dozens of ambiguities,
which makes it harder to spot and prevent new ambiguities.

Closes https://github.com/bevyengine/bevy/issues/14770.

## Solution

Just exclude the system from ambiguity detection. See the linked issue
for more context on why this resolution was chosen.

## Testing

Running the `ambiguity_detection` example now reports dozens fewer
`Render` app ambiguities.
2024-08-16 23:43:40 +00:00
Vitaliy Sapronenko
bc445bb5c6
Add feature requirement info to image loading docs (#13712)
# Objective

- Add "Available on crate feature <image format> only." for docs of
image format related types/functions
- Add warning "WARN bevy_render::texture::image: feature "<image
format>" is not enabled" on load attempt
- Fixes #13468 .

## Solution

- Added #[cfg(feature = "<image format>")] for types and warn!("feature
\"<image format>\" is not enabled"); for ImageFormat enum conversions

## Testing

ran reproducing example from issue #13468 and saw in logs
`WARN bevy_render::texture::image: feature "exr" is not enabled`

generated docs with command `RUSTDOCFLAGS="-Zunstable-options
--cfg=docsrs" cargo +nightly doc --workspace --all-features --no-deps
--document-private-items --open` and saw

![image](https://github.com/bevyengine/bevy/assets/17225606/820262bb-b4e6-4a5e-a306-bddbe9c40852)
that docs contain `Available on crate feature <image format> only.`
marks

![image](https://github.com/bevyengine/bevy/assets/17225606/57463440-a2ea-435f-a2c2-50d34f7f55a9)

## Migration Guide
Image format related entities are feature gated, if there are
compilation errors about unknown names there are some of features in
list (`exr`, `hdr`, `basis-universal`, `png`, `dds`, `tga`, `jpeg`,
`bmp`, `ktx2`, `webp` and `pnm`) should be added.
2024-08-16 23:43:20 +00:00
Robert Walter
d7cb781977
Switch rotation & translation in grid gizmos (#14656)
# Objective

- Fixes #14655

## Solution

Rotation should happen first as this is more easier to conceptualize in
the mind: We rotate around the coordinate origin `Vec3::ZERO` and then
we just shift the geometry so that its center is exactly on the
specified position

## Testing && Showcase

Code:

```rust
    gizmos.grid(
        Vec3::ONE * 10.0,
        Quat::from_rotation_x(PI / 3. * 2.),
        UVec2::splat(20),
        Vec2::new(2., 2.),
        PURPLE,
    );
    gizmos.sphere(Vec3::ONE * 10.0, Quat::default(), 1.0, PURPLE);
```

Before picture:


![image](https://github.com/user-attachments/assets/7fea2e71-e62b-4763-9f9f-7a1ecd630ada)

After picture:


![image](https://github.com/user-attachments/assets/899dad64-010a-4e4b-86ae-53b85fef0bbc)


## Migration Guide

- Users might have to double check their already existing calls to all
the `grid` methods. It should be more intuitive now though.
2024-08-16 23:40:06 +00:00
nsarlin
313db39912
Add try_insert_with_new (#14787)
# Objective
Fix #14771 by adding a `try_insert_if_new` method to the
`EntityCommands`

## Solution
This simply calls the  `try_insert` function with `InsertMode::Keep`

## Testing
I did not add any test because `EntityCommands::try_insert` does not
seem to be tested either. I can add some if needed.
2024-08-16 21:25:11 +00:00
Nihilistas
ae74df3464
#14143 - fix bevy_ui padding (#14777)
# Objective

fixes #14143

## Solution

- removed the temporary blocker if statement when setting padding in
`Style`
- adjusted the `layout_location` and `layout_size` so they use
`layout.padding` which we already get from Taffy

## Testing

- this is the test code I used:
```rust
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
){
    let font = asset_server.load("fonts/FiraSans-Bold.ttf");
    commands.spawn(Camera2dBundle::default());

    commands
        .spawn(NodeBundle {
            style: Style {
                width: Val::Px(200.),
                height: Val::Px(100.),
                align_items: AlignItems::Center,
                justify_content: JustifyContent::Center,
                align_self: AlignSelf::Center,
                justify_self: JustifySelf::Center,
                ..Default::default()
            },
            background_color: BackgroundColor(Color::srgb(0.,1., 1.)),
            ..Default::default()
        })
        .with_children(|builder| {
            builder.spawn((TextBundle::from_section(
                    "Hello World",
                    TextStyle {
                        font,
                        font_size: 32.0,
                        color: Color::WHITE,
                        },
                ).with_style(Style {
                    padding: UiRect::all(Val::Px(10.)),
                    width: Val::Px(100.),
                    height: Val::Px(100.),
                    ..Default::default()
                }).with_background_color(Color::srgb(1.,0., 0.)),
            ));
            // spawn an image bundle
            builder.spawn(ImageBundle {
                style: Style {
                    padding: UiRect::all(Val::Px(10.)),
                    width: Val::Px(100.),
                    height: Val::Px(100.),
                    ..Default::default()
                },
                image: asset_server.load("square.png").into(),
                ..Default::default()
            });
        });
}
```

- I tested 5 cases: 10px padding from all sides, and 10px padding from
left, right, bottom, and top separately

- **For reviewers**: please check more cases or try to run it on some
more complicated real-world UI

## Showcase

<img width="374" alt="Screenshot 2024-08-16 at 09 28 04"
src="https://github.com/user-attachments/assets/59b85b00-e255-4669-be13-a287ef35d4d9">
<img width="288" alt="Screenshot 2024-08-16 at 09 28 47"
src="https://github.com/user-attachments/assets/170a79b1-ec9c-45f9-82f5-ba7fa4029334">
<img width="274" alt="Screenshot 2024-08-16 at 09 45 16"
src="https://github.com/user-attachments/assets/e3fd9b59-b41f-427d-8c07-5acdf1dc5ecf">
<img width="292" alt="Screenshot 2024-08-16 at 09 45 36"
src="https://github.com/user-attachments/assets/c4f708aa-3f0d-4ff3-b779-0d4ed5f6ba73">
<img width="261" alt="Screenshot 2024-08-16 at 09 45 58"
src="https://github.com/user-attachments/assets/eba1e26f-04ca-4178-87c8-3a79daff3a9a">

---------

Co-authored-by: dpeke <dpekelis@funstage.com>
2024-08-16 21:22:44 +00:00
Robert Walter
f88ab5a1f2
add consts to curve module functions (#14785)
Just a really minor polish of the ongoing curve RFC implementation
effort
2024-08-16 19:28:29 +00:00
Sam
cf69488982
Enables bevy_render feature for bevy_gizmos dependency in bevy_dev_tools (#14765)
# Objective

Fixes #14736

## Solution

Enables feature `bevy_render` for dependency `bevy_gizmos` in
`bevy_dev_tools` cargo.

`bevy_dev_tools` has `bevy_render` as a required dependency, whereas it
is optional for `bevy_gizmos`. When building with no default features,
this causes gizmos to not compile with `bevy_render` features, meaning
some fields and code are not available. Since these features are
required in dev tools, it makes sense to ensure they are enabled. Making
`bevy_render` optional would introduce additional and potentially
unwanted change wake. in dev tools.

## Testing
Reproed and tested on Windows 10, issue originally reported on Ubuntu
and MacOS.

- Original issue command completed without error: `cargo c -p bevy
--no-default-features -F bevy_dev_tools`
- Ran full ci validations with `cargo run -p ci`
2024-08-15 21:53:55 +00:00
Matty
20a9b921a0
A Curve trait for general interoperation — Part II (#14700)
# Objective

Finish what we started in #14630. The Curve RFC is
[here](https://github.com/bevyengine/rfcs/blob/main/rfcs/80-curve-trait.md).

## Solution

This contains the rest of the library from my branch. The main things
added here are:
- Bulk sampling / resampling methods on `Curve` itself
- Data structures supporting the above
- The `cores` submodule that those data structures use to encapsulate
sample interpolation

The weirdest thing in here is probably `ChunkedUnevenCore` in `cores`,
which is not used by anything in the Curve library itself but which is
required for efficient storage of glTF animation curves. (See #13105.)
We can move it into a different PR if we want to; I don't have strong
feelings either way.

## Testing

New tests related to resampling are included. As I write this, I realize
we could use some tests in `cores` itself, so I will add some on this
branch before too long.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Robert Walter <26892280+RobWalt@users.noreply.github.com>
2024-08-15 21:49:02 +00:00
Alice Cecile
5243fe6956
Remove manual apply_deferred in bevy_ui (#14768)
# Objective

This `apply_deferred` doesn't seem to have any effect, pointlessly
restricts parallelism and is responsible for a large number of system
order ambiguities. Spotted as part of #7386.

## Solution

Remove it.

This is the *only* manual apply_deferred in the code base currently.

## Testing

I've checked various UI examples and `split_screen`, and couldn't
discern any difference.

This looks like a remnant of a `(a, apply_deferred, b).chain()` pattern
where `b` got removed, leaving us with a weird vestige.
2024-08-15 20:51:25 +00:00
Jeff Petkau
b2529bf100
feat: add insert_if_new (#14397) (#14646)
# Objective

Often there are reasons to insert some components (e.g. Transform)
separately from the rest of a bundle (e.g. PbrBundle). However `insert`
overwrites existing components, making this difficult.

See also issue #14397

Fixes #2054.

## Solution

This PR adds the method `insert_if_new` to EntityMut and Commands, which
is the same as `insert` except that the old component is kept in case of
conflicts.

It also renames some internal enums (from `ComponentStatus::Mutated` to
`Existing`), to reflect the possible change in meaning.

## Testing

*Did you test these changes? If so, how?*

Added basic unit tests; used the new behavior in my project.

*Are there any parts that need more testing?*

There should be a test that the change time isn't set if a component is
not overwritten; I wasn't sure how to write a test for that case.

*How can other people (reviewers) test your changes? Is there anything
specific they need to know?*

`cargo test` in the bevy_ecs project.

*If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?*

Only tested on Windows, but it doesn't touch anything platform-specific.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
2024-08-15 20:31:41 +00:00
Alice Cecile
a2fc9de16d
Add RenderSet::FinalCleanup for World::clear_entities (#14764)
# Objective

`World::clear_entities` is ambiguous with all of the other systems in
`RenderSet::Cleanup` because it access `&mut World`.

## Solution

I've added another system set variant, and made sure that this runs
after everything else.
 
## Testing

The `ambiguity_detection` example

## Migration Guide

`World::clear_entities` is now part of `RenderSet::PostCleanup` rather
than `RenderSet::Cleanup`. Your cleanup systems should likely stay in
`RenderSet::Cleanup`.

## Additional context

Spotted when working on #7386: this was responsible for a large number
of ambiguities.

This should be removed if / when #14449 is merged: there's no need to
call `clear_entities` at all if the rendering world is retained!
2024-08-15 18:48:43 +00:00
Brian Reavis
ac29bdfc86
Fix pass_span drop panic obscuring transparent 2d render errors (#14758)
# Objective

When an item in the transparent 2d phase fails to render, bevy crashes
with _"PassSpanScope::end was never called"_ instead of outputting the
actual error to the console. This PR fixes this so that phase errors are
output to the console. It also makes bevy not crash.

```
thread '<unnamed>' panicked at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/diagnostic/mod.rs:157:9:
PassSpanScope::end was never called
stack backtrace:
   0: rust_begin_unwind
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/panicking.rs:72:14
   2: <bevy_render::diagnostic::PassSpanGuard<R,P> as core::ops::drop::Drop>::drop
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/diagnostic/mod.rs:157:9
   3: core::ptr::drop_in_place<bevy_render::diagnostic::PassSpanGuard<core::option::Option<alloc::sync::Arc<bevy_render::diagnostic::internal::DiagnosticsRecorder>>,bevy_render::render_phase::draw_state::TrackedRenderPass>>
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ptr/mod.rs:514:1
   4: <bevy_core_pipeline::core_2d::main_transparent_pass_2d_node::MainTransparentPass2dNode as bevy_render::render_graph::node::ViewNode>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_core_pipeline/src/core_2d/main_transparent_pass_2d_node.rs:75:9
   5: <bevy_render::render_graph::node::ViewNodeRunner<T> as bevy_render::render_graph::node::Node>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/render_graph/node.rs:406:9
   6: bevy_render::renderer::graph_runner::RenderGraphRunner::run_graph
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/graph_runner.rs:226:21
   7: bevy_render::renderer::graph_runner::RenderGraphRunner::run_graph
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/graph_runner.rs:233:21
   8: bevy_render::renderer::graph_runner::RenderGraphRunner::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/graph_runner.rs:81:9
   9: bevy_render::renderer::render_system
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/mod.rs:40:15
  10: core::ops::function::FnMut::call_mut
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:166:5
  11: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:294:13
  12: <Func as bevy_ecs::system::exclusive_function_system::ExclusiveSystemParamFunction<fn(F0) .> Out>>::run::call_inner
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:229:21
  13: <Func as bevy_ecs::system::exclusive_function_system::ExclusiveSystemParamFunction<fn(F0) .> Out>>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:232:17
  14: <bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run::{{closure}}
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:124:23
  15: bevy_ecs::world::World::last_change_tick_scope
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/world/mod.rs:2383:9
  16: <bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:116:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

## Solution

Matched the behavior of the other render phases ([like
here](9ca5540b75/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs (L98-L101)))
2024-08-15 18:41:01 +00:00
Giacomo Stevanato
e9e9e5e15d
Add query reborrowing (#14690)
# Objective

- Sometimes some method or function takes an owned `Query`, but we don't
want to give up ours;
- transmuting it technically a solution, but it more costly than
necessary.
- Make query iterators more flexible
- this would allow the equivalent of
`slice::split_first`/`slice::split_first_mut` for query iterators
  - helps with requests like #14685

## Solution

- Add a way for reborrowing queries, that is going from a `&'a mut
Query<'w, 's, D, F>` to a `Query<'a, 's, D, F>`:
- this is safe because the original query will be borrowed while the new
query exists and thus no aliased access can happen;
- it's basically the equivalent of going from `&'short mut &'long mut T`
to `&'short mut T` the the compiler automatically implements.
- Add a way for getting the remainder of a query iterator:
- this is interesting also because the original iterator keeps its
position, which was not possible before;
- this in turn requires a way to reborrow query fetches, which I had to
add to `WorldQuery`.

## Showcase

- You can now reborrow a `Query`, getting an equivalent `Query` with a
shorter lifetime. Previously this was possible for read-only queries by
using `Query::to_readonly`, now it's possible for mutable queries too;
- You can now separately iterate over the remainder of `QueryIter`.

## Migration Guide

- `WorldQuery` now has an additional `shrink_fetch` method you have to
implement if you were implementing `WorldQuery` manually.
2024-08-15 17:38:56 +00:00
callym
9d5837769c
Add Reflect derive to bevy_a11y::Focus (#14763)
Closes #14727
2024-08-15 17:33:20 +00:00
Alice Cecile
dbf0d7071e
Don't ask for ResMut in queue_view_auto_exposure_pipelines (#14762)
This was creating a spurious ambiguity: `PipelineCache` uses interior
mutability.

Spotted as part of #7386.
2024-08-15 17:15:31 +00:00
callym
ad5e8355b5
Remove Component derive for DepthOfFieldMode (#14761)
Fixes #14592
2024-08-15 17:14:49 +00:00
Chris Russell
340c749d16
Remove redundant ArchetypeComponentId lookup in Res and ResMut (#14691)
# Objective

`Res` and `ResMut` perform redundant lookups of the resource storage,
first to initialize the `ArchetypeComponentId` and then to retrieve it.

## Solution

Use the `archetype_component_id` returned from
`initialize_resource_internal` to avoid an extra lookup and `unwrap()`.
2024-08-15 16:12:03 +00:00
robtfm
9ca5540b75
apply finished animations (#14743)
# Objective

fix #14742

## Solution

the issue arises because "finished" animations (where current time >=
last keyframe time) are not applied at all.
when transitioning from a finished animation to another later-indexed
anim, the transition kind-of works because the finished anim is skipped,
then the new anim is applied with a lower weight (weight / total_weight)
when transitioning from a finished animation to another earlier-indexed
anim, the transition is instant as the new anim is applied with 1.0 (as
weight == total_weight for the first applied), then the finished
animation is skipped.

to fix this we can always apply every animation based on the nearest 2
keyframes, and clamp the interpolation between them to [0,1].

pros:
- finished animations can be transitioned out of correctly
- blended animations where some curves have a last-keyframe before the
end of the animation will blend properly
- animations will actually finish on their last keyframe, rather than a
fraction of a render-frame before the end

cons:
- we have to re-apply finished animations every frame whether it's
necessary or not. i can't see a way to avoid this.
2024-08-15 15:10:23 +00:00
TotalKrill
6adf31babf
hooking up observers and clicking for ui node (#14695)
Makes the newly merged picking usable for UI elements. 

currently it both triggers the events, as well as sends them as throught
commands.trigger_targets. We should probably figure out if this is
needed for them all.

# Objective

Hooks up obserers and picking for a very simple example

## Solution

upstreamed the UI picking backend from bevy_mod_picking

## Testing

tested with the new example picking/simple_picking.rs


---

---------

Co-authored-by: Lixou <82600264+DasLixou@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-08-15 14:43:55 +00:00
Chris Russell
0ea46663b0
Use map_unchanged in reflection instead of creating a Mut manually. (#14692)
# Objective

The code to create `ReflectComponent` and `ReflectResource` instances
manually constructs a `Mut<dyn Reflect>` by copying everything but
`value`. That can be done more concisely and better respecting
encapsulation by calling the `map_unchanged()` method.

## Solution

Use `map_unchanged` instead of creating a `Mut` manually.

---------

Co-authored-by: radiish <cb.setho@gmail.com>
2024-08-15 14:26:57 +00:00
Ben Frankel
d849941dac
Add entity .trigger() methods (#14752)
# Objective

Fix https://github.com/bevyengine/bevy/issues/14233.

## Solution

Add `EntityCommands::trigger` and `EntityWorldMut::trigger`.

## Testing

- Not tested.
2024-08-15 14:16:06 +00:00
eckz
a44278aee6
Making DynamicEnum::is_dynamic() return true (#14732)
# Objective

- Right now `DynamicEnum::is_dynamic()` is returning `false`. I don't
think this was expected, since the rest of `Dynamic*` types return
`true`.

## Solution

- Making `DynamicEnum::is_dynamic()` return true

## Testing

- Added an extra unit test to verify that `.is_dynamic()` returns
`true`.
2024-08-15 14:10:52 +00:00
IceSentry
9de25ad330
Add AlphaMask2d phase (#14724)
# Objective

- Bevy now supports an opaque phase for mesh2d, but it's very common for
2d textures to have a transparent alpha channel.

## Solution

- Add an alpha mask phase identical to the one in 3d. It will do the
alpha masking in the shader before drawing the mesh.
- Uses the BinnedRenderPhase
- Since it's an opaque draw it also correctly writes to depth

## Testing

- Tested the mes2d_alpha_mode example and the bevymark example with
alpha mask mode enabled

---

## Showcase


![image](https://github.com/user-attachments/assets/9e5e4561-d0a7-4aa3-b049-d4b1247d5ed4)

The white logo on the right is rendered with alpha mask enabled.

Running the bevymark example I can get 65fps for 120k mesh2d all using
alpha mask.

## Notes

This is one more step for mesh2d improvements
https://github.com/bevyengine/bevy/issues/13265

---------

Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-08-15 14:10:37 +00:00
re0312
3bd039e821
Skip empty archetype/table (#14749)
# Objective

- As sander commneted on discord
[link](https://discord.com/channels/691052431525675048/749335865876021248/1273414144091230228),

![image](https://github.com/user-attachments/assets/62f2b6f3-1aaf-49d9-bafa-bf62b83b10be)





## Performance

![image](https://github.com/user-attachments/assets/11122940-1547-42ae-9576-0e1a93fd9f5f)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
2024-08-15 14:07:20 +00:00
Ben Frankel
6da2305e49
Add Command and co. to prelude (#14751)
# Objective

Make it easier to write and work with custom `Command`s and
`EntityCommand`s. See
https://discord.com/channels/691052431525675048/692572690833473578/1273030340235100214
for (brief) context.

## Solution

Re-export `Command`, `EntityCommand`, and `EntityCommands` in the
`bevy_ecs::prelude`, where `Commands` is already re-exported.
2024-08-15 13:33:32 +00:00
Christian Hughes
7d3068e6c3
Fix world borrow for DeferredWorld::query (#14744)
# Objective

As is, calling
[`DeferredWorld::query`](https://docs.rs/bevy/latest/bevy/ecs/world/struct.DeferredWorld.html#method.query)
requires you to first `reborrow()` the world in order to use it at all.

Simple reproduction:
```rust
fn test<'w>(mut world: DeferredWorld<'w>, mut state: QueryState<(), ()>) {
    let query = world.query(&mut state);
    // let query = world.reborrow().query(&mut state); // << Required
}
```

Error message:
```
error[E0597]: `world` does not live long enough
    |
444 | fn test<'w>(mut world: DeferredWorld<'w>, mut state: QueryState<(), ()>) {
    |         --  --------- binding `world` declared here
    |         |
    |         lifetime `'w` defined here
445 |     let query = world.query(&mut state);
    |                 ^^^^^------------------
    |                 |
    |                 borrowed value does not live long enough
    |                 argument requires that `world` is borrowed for `'w`
446 | }
    |  - `world` dropped here while still borrowed

```

## Solution

Fix the world borrow lifetime on the `query` method, which now correctly
allows the above usage.
2024-08-14 18:59:19 +00:00
eckz
46e8c6b662
Consistency between Wireframe2d and Wireframe (#14720)
# Objective

- Wireframe plugins have inconsistencies between 3D and 2D versions.
This PR addresses the following
  - 2d version uses `Srgba` for colors, 3d version uses `Color`.

  
## Solution

- This PR brings consistency by doing the following change
  - `Wireframe2d` now uses `Color` instead of `Srgba`

## Testing

- `wireframe_2d` and `wireframe` examples were verified and they work as
before.

---

## Migration Guide

- `Wireframe2dConfig`.`default_color` type is now `Color` instead of
`Srgba`. Use `.into()` to convert between them.
- `Wireframe2dColor`.`color` type is now `Color` instead of `Srgba`. Use
`.into()` to convert between them.
2024-08-13 18:57:47 +00:00
Josiah Putman
882973a528
Expose max_mip_dimension and uv_offset in BloomSettings. (#14512)
# Objective

By default, Bevy's bloom effect shows square artifacts on small bright
particles due to a low max mip resolution. This PR makes this
configurable via BloomSettings so users can customize these parameters
instead of having them in private module constants.

## Solution

Expose max_mip_dimension and uv_offset in BloomSettings.

## Testing

I tested these changes by running the Bloom 2D / 3D examples.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-13 15:01:42 +00:00
Gino Valente
6183b56b5d
bevy_reflect: Reflect remote types (#6042)
# Objective

The goal with this PR is to allow the use of types that don't implement
`Reflect` within the reflection API.

Rust's [orphan
rule](https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type)
prevents implementing a trait on an external type when neither type nor
trait are owned by the implementor. This means that if a crate,
`cool_rust_lib`, defines a type, `Foo`, then a user cannot use it with
reflection. What this means is that we have to ignore it most of the
time:

```rust
#[derive(Reflect)]
struct SomeStruct {
  #[reflect(ignore)]
  data: cool_rust_lib::Foo
}
```

Obviously, it's impossible to implement `Reflect` on `Foo`. But does it
*have* to be?

Most of reflection doesn't deal with concrete types— it's almost all
using `dyn Reflect`. And being very metadata-driven, it should
theoretically be possible. I mean,
[`serde`](https://serde.rs/remote-derive.html) does it.

## Solution

> Special thanks to @danielhenrymantilla for their help reviewing this
PR and offering wisdom wrt safety.

Taking a page out of `serde`'s book, this PR adds the ability to easily
use "remote types" with reflection. In this context, a "remote type" is
the external type for which we have no ability to implement `Reflect`.

This adds the `#[reflect_remote(...)]` attribute macro, which is used to
generate "remote type wrappers". All you have to do is define the
wrapper exactly the same as the remote type's definition:

```rust
// Pretend this is our external crate
mod cool_rust_lib {
  #[derive(Default)]
  struct Foo {
    pub value: String
  }
}

#[reflect_remote(cool_rust_lib::Foo)]
struct FooWrapper {
  pub value: String
}
```

> **Note:** All fields in the external type *must* be public. This could
be addressed with a separate getter/setter attribute either in this PR
or in another one.

The macro takes this user-defined item and transforms it into a newtype
wrapper around the external type, marking it as `#[repr(transparent)]`.
The fields/variants defined by the user are simply used to build out the
reflection impls.

Additionally, it generates an implementation of the new trait,
`ReflectRemote`, which helps prevent accidental misuses of this API.

Therefore, the output generated by the macro would look something like:

```rust
#[repr(transparent)]
struct FooWrapper(pub cool_rust_lib::Foo);

impl ReflectRemote for FooWrapper {
  type Remote = cool_rust_lib::Foo;

  // transmutation methods...
}

// reflection impls...
// these will acknowledge and make use of the `value` field
```

Internally, the reflection API will pass around the `FooWrapper` and
[transmute](https://doc.rust-lang.org/std/mem/fn.transmute.html) it
where necessary. All we have to do is then tell `Reflect` to do that. So
rather than ignoring the field, we tell `Reflect` to use our wrapper
using the `#[reflect(remote = ...)]` field attribute:

```rust
#[derive(Reflect)]
struct SomeStruct {
  #[reflect(remote = FooWrapper)]
  data: cool_rust_lib::Foo
}
```

#### Other Macros & Type Data

Because this macro consumes the defined item and generates a new one, we
can't just put our macros anywhere. All macros that should be passed to
the generated struct need to come *below* this macro. For example, to
derive `Default` and register its associated type data:

```rust
//  GOOD
#[reflect_remote(cool_rust_lib::Foo)]
#[derive(Default)]
#[reflect(Default)]
struct FooWrapper {
  pub value: String
}

//  BAD
#[derive(Default)]
#[reflect_remote(cool_rust_lib::Foo)]
#[reflect(Default)]
struct FooWrapper {
  pub value: String
}
```

#### Generics

Generics are forwarded to the generated struct as well. They should also
be defined in the same order:

```rust
#[reflect_remote(RemoteGeneric<'a, T1, T2>)]
struct GenericWrapper<'a, T1, T2> {
  pub foo: &'a T1,
  pub bar: &'a T2,
}
```

> Naming does *not* need to match the original definition's. Only order
matters here.

> Also note that the code above is just a demonstration and doesn't
actually compile since we'd need to enforce certain bounds (e.g. `T1:
Reflect`, `'a: 'static`, etc.)

#### Nesting

And, yes, you can nest remote types:

```rust
#[reflect_remote(RemoteOuter)]
struct OuterWrapper {
  #[reflect(remote = InnerWrapper)]
  pub inner: RemoteInner
}

#[reflect_remote(RemoteInner)]
struct InnerWrapper(usize);
```

#### Assertions

This macro will also generate some compile-time assertions to ensure
that the correct types are used. It's important we catch this early so
users don't have to wait for something to panic. And it also helps keep
our `unsafe` a little safer.

For example, a wrapper definition that does not match its corresponding
remote type will result in an error:

```rust
mod external_crate {
  pub struct TheirStruct(pub u32);
}

#[reflect_remote(external_crate::TheirStruct)]
struct MyStruct(pub String); // ERROR: expected type `u32` but found `String`
```

<details>
<summary>Generated Assertion</summary>

```rust
const _: () = {
  #[allow(non_snake_case)]
  #[allow(unused_variables)]
  #[allow(unused_assignments)]
  #[allow(unreachable_patterns)]
  #[allow(clippy::multiple_bound_locations)]
  fn assert_wrapper_definition_matches_remote_type(
    mut __remote__: external_crate::TheirStruct,
  ) {
    __remote__.0 = (|| -> ::core::option::Option<String> { None })().unwrap();
  }
};
```

</details>

Additionally, using the incorrect type in a `#[reflect(remote = ...)]`
attribute should result in an error:

```rust
mod external_crate {
  pub struct TheirFoo(pub u32);
  pub struct TheirBar(pub i32);
}

#[reflect_remote(external_crate::TheirFoo)]
struct MyFoo(pub u32);

#[reflect_remote(external_crate::TheirBar)]
struct MyBar(pub i32);

#[derive(Reflect)]
struct MyStruct {
  #[reflect(remote = MyBar)] // ERROR: expected type `TheirFoo` but found struct `TheirBar`
  foo: external_crate::TheirFoo
}
```

<details>
<summary>Generated Assertion</summary>

```rust
const _: () = {
    struct RemoteFieldAssertions;
    impl RemoteFieldAssertions {
        #[allow(non_snake_case)]
        #[allow(clippy::multiple_bound_locations)]
        fn assert__foo__is_valid_remote() {
            let _: <MyBar as bevy_reflect::ReflectRemote>::Remote = (|| -> ::core::option::Option<external_crate::TheirFoo> {
              None
            })().unwrap();
        }
    }
};
```

</details>

### Discussion

There are a couple points that I think still need discussion or
validation.

- [x] 1. `Any` shenanigans

~~If we wanted to downcast our remote type from a `dyn Reflect`, we'd
have to first downcast to the wrapper then extract the inner type. This
PR has a [commit](b840db9f74cb6d357f951cb11b150d46bac89ee2) that
addresses this by making all the `Reflect::*any` methods return the
inner type rather than the wrapper type. This allows us to downcast
directly to our remote type.~~

~~However, I'm not sure if this is something we want to do. For
unknowing users, it could be confusing and seemingly inconsistent. Is it
worth keeping? Or should this behavior be removed?~~

I think this should be fine. The remote wrapper is an implementation
detail and users should not need to downcast to the wrapper type. Feel
free to let me know if there are other opinions on this though!

- [x] 2. Implementing `Deref/DerefMut` and `From`

~~We don't currently do this, but should we implement other traits on
the generated transparent struct? We could implement `Deref`/`DerefMut`
to easily access the inner type. And we could implement `From` for
easier conversion between the two types (e.g. `T: Into<Foo>`).~~ As
mentioned in the comments, we probably don't need to do this. Again, the
remote wrapper is an implementation detail, and should generally not be
used directly.
     
- [x] 3. ~~Should we define a getter/setter field attribute in this PR
as well or leave it for a future one?~~ I think this should be saved for
a future PR

- [ ] 4. Any foreseeable issues with this implementation?

#### Alternatives

One alternative to defining our own `ReflectRemote` would be to use
[bytemuck's
`TransparentWrapper`](https://docs.rs/bytemuck/1.13.1/bytemuck/trait.TransparentWrapper.html)
(as suggested by @danielhenrymantilla).

This is definitely a viable option, as `ReflectRemote` is pretty much
the same thing as `TransparentWrapper`. However, the cost would be
bringing in a new crate— though, it is already in use in a few other
sub-crates like bevy_render.

I think we're okay just defining `ReflectRemote` ourselves, but we can
go the bytemuck route if we'd prefer offloading that work to another
crate.

---

## Changelog

* Added the `#[reflect_remote(...)]` attribute macro to allow `Reflect`
to be used on remote types
* Added `ReflectRemote` trait for ensuring proper remote wrapper usage
2024-08-12 19:12:53 +00:00
Tau Gärtli
aab1f8e435
Use #[doc(fake_variadic)] to improve docs readability (#14703)
# Objective

- Fixes #14697

## Solution

This PR modifies the existing `all_tuples!` macro to optionally accept a
`#[doc(fake_variadic)]` attribute in its input. If the attribute is
present, each invocation of the impl macro gets the correct attributes
(i.e. the first impl receives `#[doc(fake_variadic)]` while the other
impls are hidden using `#[doc(hidden)]`.
Impls for the empty tuple (unit type) are left untouched (that's what
the [standard
library](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html#impl-PartialEq-for-())
and
[serde](https://docs.rs/serde/latest/serde/trait.Serialize.html#impl-Serialize-for-())
do).

To work around https://github.com/rust-lang/cargo/issues/8811 and to get
impls on re-exports to correctly show up as variadic, `--cfg docsrs_dep`
is passed when building the docs for the toplevel `bevy` crate.

`#[doc(fake_variadic)]` only works on tuples and fn pointers, so impls
for structs like `AnyOf<(T1, T2, ..., Tn)>` are unchanged.

## Testing

I built the docs locally using `RUSTDOCFLAGS='--cfg docsrs'
RUSTFLAGS='--cfg docsrs_dep' cargo +nightly doc --no-deps --workspace`
and checked the documentation page of a trait both in its original crate
and the re-exported version in `bevy`.
The description should correctly mention for how many tuple items the
trait is implemented.

I added `rustc-args` for docs.rs to the `bevy` crate, I hope there
aren't any other notable crates that re-export `#[doc(fake_variadic)]`
traits.

---

## Showcase

`bevy_ecs::query::QueryData`:
<img width="1015" alt="Screenshot 2024-08-12 at 16 41 28"
src="https://github.com/user-attachments/assets/d40136ed-6731-475f-91a0-9df255cd24e3">

`bevy::ecs::query::QueryData` (re-export):
<img width="1005" alt="Screenshot 2024-08-12 at 16 42 57"
src="https://github.com/user-attachments/assets/71d44cf0-0ab0-48b0-9a51-5ce332594e12">

## Original Description

<details>

Resolves #14697

Submitting as a draft for now, very WIP.

Unfortunately, the docs don't show the variadics nicely when looking at
reexported items.
For example:

`bevy_ecs::bundle::Bundle` correctly shows the variadic impl:

![image](https://github.com/user-attachments/assets/90bf8af1-1d1f-4714-9143-cdd3d0199998)

while `bevy::ecs::bundle::Bundle` (the reexport) shows all the impls
(not good):

![image](https://github.com/user-attachments/assets/439c428e-f712-465b-bec2-481f7bf5870b)

Built using `RUSTDOCFLAGS='--cfg docsrs' cargo +nightly doc --workspace
--no-deps` (`--no-deps` because of wgpu-core).

Maybe I missed something or this is a limitation in the *totally not
private* `#[doc(fake_variadic)]` thingy. In any case I desperately need
some sleep now :))

</details>
2024-08-12 18:54:33 +00:00
radiish
6ab8767d3b
reflect: implement the unique reflect rfc (#7207)
# Objective

- Implements the [Unique Reflect
RFC](https://github.com/nicopap/rfcs/blob/bevy-reflect-api/rfcs/56-better-reflect.md).

## Solution

- Implements the RFC.
- This implementation differs in some ways from the RFC:
- In the RFC, it was suggested `Reflect: Any` but `PartialReflect:
?Any`. During initial implementation I tried this, but we assume the
`PartialReflect: 'static` in a lot of places and the changes required
crept out of the scope of this PR.
- `PartialReflect::try_into_reflect` originally returned `Option<Box<dyn
Reflect>>` but i changed this to `Result<Box<dyn Reflect>, Box<dyn
PartialReflect>>` since the method takes by value and otherwise there
would be no way to recover the type. `as_full` and `as_full_mut` both
still return `Option<&(mut) dyn Reflect>`.

---

## Changelog

- Added `PartialReflect`.
- `Reflect` is now a subtrait of `PartialReflect`.
- Moved most methods on `Reflect` to the new `PartialReflect`.
- Added `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect}`.
- Added `PartialReflect::{try_as_reflect, try_as_reflect_mut,
try_into_reflect}`.
- Added `<dyn PartialReflect>::{try_downcast_ref, try_downcast_mut,
try_downcast, try_take}` supplementing the methods on `dyn Reflect`.

## Migration Guide

- Most instances of `dyn Reflect` should be changed to `dyn
PartialReflect` which is less restrictive, however trait bounds should
generally stay as `T: Reflect`.
- The new `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect, try_as_reflect, try_as_reflect_mut,
try_into_reflect}` methods as well as `Reflect::{as_reflect,
as_reflect_mut, into_reflect}` will need to be implemented for manual
implementors of `Reflect`.

## Future Work

- This PR is designed to be followed up by another "Unique Reflect Phase
2" that addresses the following points:
- Investigate making serialization revolve around `Reflect` instead of
`PartialReflect`.
- [Remove the `try_*` methods on `dyn PartialReflect` since they are
stop
gaps](https://github.com/bevyengine/bevy/pull/7207#discussion_r1083476050).
- Investigate usages like `ReflectComponent`. In the places they
currently use `PartialReflect`, should they be changed to use `Reflect`?
- Merging this opens the door to lots of reflection features we haven't
been able to implement.
- We could re-add [the `Reflectable`
trait](8e3488c880/crates/bevy_reflect/src/reflect.rs (L337-L342))
and make `FromReflect` a requirement to improve [`FromReflect`
ergonomics](https://github.com/bevyengine/rfcs/pull/59). This is
currently not possible because dynamic types cannot sensibly be
`FromReflect`.
  - Since this is an alternative to #5772, #5781 would be made cleaner.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-08-12 17:01:41 +00:00
callym
7b81ae7e40
Update WGPU to version 22 (#14401)
Upgrading to WGPU 22.

Needs `naga_oil` to upgrade first, I've got a fork that compiles but
fails tests, so until that's fixed and the crate is officially
updated/released this will be blocked.

---------

Co-authored-by: Elabajaba <Elabajaba@users.noreply.github.com>
2024-08-12 16:55:18 +00:00
re0312
032fd486c7
View filter for batch_and_prepare_render_phase (#14713)
# Objective
- batch_and_prepare_render_phase will iterate all living entities ,which
potentially causes a lot of unnecessary look up
- from
https://github.com/bevyengine/bevy/pull/14449#issuecomment-2282876034

## Solution

- added View filter
2024-08-12 16:15:54 +00:00
Matty
61a1530c56
Make bevy_math's libm feature use libm for all f32methods with unspecified precision (#14693)
# Objective

Closes #14474

Previously, the `libm` feature of bevy_math would just pass the same
feature flag down to glam. However, bevy_math itself had many uses of
floating-point arithmetic with unspecified precision. For example,
`f32::sin_cos` and `f32::powi` have unspecified precision, which means
that the exact details of their output are not guaranteed to be stable
across different systems and/or versions of Rust. This means that users
of bevy_math could observe slightly different behavior on different
systems if these methods were used.

The goal of this PR is to make it so that the `libm` feature flag
actually guarantees some degree of determinacy within bevy_math itself
by switching to the libm versions of these functions when the `libm`
feature is enabled.

## Solution

bevy_math now has an internal module `bevy_math::ops`, which re-exports
either the standard versions of the operations or the libm versions
depending on whether the `libm` feature is enabled. For example,
`ops::sin` compiles to `f32::sin` without the `libm` feature and to
`libm::sinf` with it.

This approach has a small shortfall, which is that `f32::powi` (integer
powers of floating point numbers) does not have an equivalent in `libm`.
On the other hand, this method is only used for squaring and cubing
numbers in bevy_math. Accordingly, this deficit is covered by the
introduction of a trait `ops::FloatPow`:
```rust
pub(crate) trait FloatPow {
    fn squared(self) -> Self;
    fn cubed(self) -> Self;
}
```

Next, each current usage of the unspecified-precision methods has been
replaced by its equivalent in `ops`, so that when `libm` is enabled, the
libm version is used instead. The exception, of course, is that
`.powi(2)`/`.powi(3)` have been replaced with `.squared()`/`.cubed()`.

Finally, the usage of the plain `f32` methods with unspecified precision
is now linted out of bevy_math (and hence disallowed in CI). For
example, using `f32::sin` within bevy_math produces a warning that tells
the user to use the `ops::sin` version instead.

## Testing

Ran existing tests. It would be nice to check some benchmarks on NURBS
things once #14677 merges. I'm happy to wait until then if the rest of
this PR is fine.

---

## Discussion

In the future, it might make sense to actually expose `bevy_math::ops`
as public if any downstream Bevy crates want to provide similar
determinacy guarantees. For now, it's all just `pub(crate)`.

This PR also only covers `f32`. If we find ourselves using `f64`
internally in parts of bevy_math for better robustness, we could extend
the module and lints to cover the `f64` versions easily enough.

I don't know how feasible it is, but it would also be nice if we could
standardize the bevy_math tests with the `libm` feature in CI, since
their success is currently platform-dependent (e.g. 8 of them fail on my
machine when run locally).

---------

Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
2024-08-12 16:13:36 +00:00
databasedav
c8d30edf1a
add SystemIdMarker Component to enable filtering for SystemId Entitys (#14584)
# Objective

Enables writing queries like `Query<Entity, With<SystemIdMarker>>` to
filter `Entity`s that are, or are not (with `Without`), `SystemId`s.

## Solution

Simple unit struct `SystemIdMarker` added during
`World::register_boxed_system`; `World::remove_system` already despawns
the entity, removing the marker.

## Testing

No tests, but happy to write some with direction.

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-12 16:11:06 +00:00
databasedav
c3111bebb8
document using ObserverState as filter for Observer Entitys (#14669)
# Objective

~~Enables writing queries like `Query<Entity, With<ObserverMarker>>` to
filter `Entity`s that are, or are not (with `Without`), `Observer`s.~~

~~`Observer` version of [similar
PR](https://github.com/bevyengine/bevy/pull/14584) for `SystemId`s.~~

just adding a line to the docs :)

## Solution

~~Simple unit struct `ObserverMarker` added in `Observer`'s `.on_add`
component hook.~~

## Testing

No tests, but happy to write some with direction.
2024-08-12 16:07:03 +00:00
Sarthak Singh
2c4ef37b76
Changed Mesh::attributes* functions to return MeshVertexAttribute (#14394)
# Objective

Fixes #14365 

## Migration Guide

- When using the iterator returned by `Mesh::attributes` or
`Mesh::attributes_mut` the first value of the tuple is not the
`MeshVertexAttribute` instead of `MeshVertexAttributeId`. To access the
`MeshVertexAttributeId` use the `MeshVertexAttribute.id` field.

Signed-off-by: Sarthak Singh <sarthak.singh99@gmail.com>
2024-08-12 15:54:28 +00:00
Eero Lehtinen
47c4e3084a
Add custom cursors (#14284)
# Objective

- Add custom images as cursors
- Fixes #9557 

## Solution

- Change cursor type to accommodate both native and image cursors
- I don't really like this solution because I couldn't use
`Handle<Image>` directly. I would need to import `bevy_assets` and that
causes a circular dependency. Alternatively we could use winit's
`CustomCursor` smart pointers, but that seems hard because the event
loop is needed to create those and is not easily accessable for users.
So now I need to copy around rgba buffers which is sad.
- I use a cache because especially on the web creating cursor images is
really slow
- Sorry to #14196 for yoinking, I just wanted to make a quick solution
for myself and thought that I should probably share it too.

Update:
- Now uses `Handle<Image>`, reads rgba data in `bevy_render` and uses
resources to send the data to `bevy_winit`, where the final cursors are
created.

## Testing

- Added example which works fine at least on Linux Wayland (winit side
has been tested with all platforms).
- I haven't tested if the url cursor works.

## Migration Guide

- `CursorIcon` is no longer a field in `Window`, but a separate
component can be inserted to a window entity. It has been changed to an
enum that can hold custom images in addition to system icons.
- `Cursor` is renamed to `CursorOptions` and `cursor` field of `Window`
is renamed to `cursor_options`
- `CursorIcon` is renamed to `SystemCursorIcon`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-08-12 15:49:03 +00:00
Chris Russell
d4ec80d5d2
Support more kinds of system params in buildable systems. (#14050)
# Objective

Support more kinds of system params in buildable systems, such as a
`ParamSet` or `Vec` containing buildable params or tuples of buildable
params.

## Solution

Replace the `BuildableSystemParam` trait with `SystemParamBuilder` to
make it easier to compose builders. Provide implementations for existing
buildable params, plus tuples, `ParamSet`, and `Vec`.

## Examples

```rust
// ParamSet of tuple: 
let system = (ParamSetBuilder((
    QueryParamBuilder::new(|builder| { builder.with::<B>(); }),
    QueryParamBuilder::new(|builder| { builder.with::<C>(); }),
)),)
    .build_state(&mut world)
    .build_system(|mut params: ParamSet<(Query<&mut A>, Query<&mut A>)>| {
        params.p0().iter().count() + params.p1().iter().count()
    });
	
// ParamSet of Vec:
let system = (ParamSetBuilder(vec![
    QueryParamBuilder::new_box(|builder| { builder.with::<B>(); }),
    QueryParamBuilder::new_box(|builder| { builder.with::<C>(); }),
]),)
    .build_state(&mut world)
    .build_system(|mut params: ParamSet<Vec<Query<&mut A>>>| {
        let mut count = 0;
        params.for_each(|mut query| count += query.iter_mut().count());
        count
    });
```

## Migration Guide

The API for `SystemBuilder` has changed. Instead of constructing a
builder with a world and then adding params, you first create a tuple of
param builders and then supply the world.

```rust
// Before
let system = SystemBuilder::<()>::new(&mut world)
    .local::<u64>()
    .builder::<Local<u64>>(|x| *x = 10)
    .builder::<Query<&A>>(|builder| { builder.with::<B>(); })
    .build(system);

// After
let system = (
    ParamBuilder,
    LocalBuilder(10),
    QueryParamBuilder::new(|builder| { builder.with::<B>(); }),
)
    .build_state(&mut world)
    .build_system(system);
```

## Possible Future Work

Here are a few possible follow-up changes. I coded them up to prove that
this API can support them, but they aren't necessary for this PR.

* chescock/bevy#1
* chescock/bevy#2
* chescock/bevy#3
2024-08-12 15:45:35 +00:00
IceSentry
9d6a4fbc85
Use BinnedRenderPhase for Opaque2d (#13091)
Based on top of #12982  and #13069 

# Objective

- Opaque2d was implemented with SortedRenderPhase but BinnedRenderPhase
should be much faster

## Solution

- Implement BinnedRenderPhase for Opaque2d

## Notes

While testing this PR, before the change I had ~14 fps in bevymark with
100k entities. After this change I get ~71 fps, compared to using
sprites where I only get ~63 fps. This means that after this PR mesh2d
with opaque meshes will be faster than the sprite path. This is not a 1
to 1 comparison since sprites do alpha blending.
2024-08-12 15:38:24 +00:00
Christian Hughes
7f658cabf7
Replace UnsafeCell<World> usage with UnsafeWorldCell in CombinatorSystem (#14706)
# Objective

Replace usage of `UnsafeCell<World>` with our standard `UnsafeWorldCell`
that seemed to have been missed.

## Solution

Do just that.
2024-08-11 13:58:10 +00:00
TotalKrill
3e10fd8534
Mod picking upstream 2 (#14686)
Ci fixed  version of: #14541 

Upstream the remainder of bevy_picking_core and all of
bevy_picking_input.

This work is intentionally nonfunctional and has minimal changes, but
does compile. More work is necessary to replace bevy_eventlistener with
propagating observers.

This work is being coordinated as part of "bevy_mod_picking upstream"
working group. Come say hi on discord!

---------

Co-authored-by: Miles Silberling-Cook <nth.tensor@gmail.com>
Co-authored-by: Aevyrie <aevyrie@gmail.com>
2024-08-09 23:16:37 +00:00
re0312
e490b919df
inline iter_combinations (#14680)
# Objective
- fix #14679 
- bevy's performance highly depends on compiler optimization,inline hot
function could greatly help compiler to optimize our program
2024-08-09 17:44:37 +00:00
Matty
23e87270df
A Curve trait for general interoperation — Part I (#14630)
# Objective

This PR implements part of the [Curve
RFC](https://github.com/bevyengine/rfcs/blob/main/rfcs/80-curve-trait.md).
See that document for motivation, objectives, etc.

## Solution

For purposes of reviewability, this PR excludes the entire part of the
RFC related to taking multiple samples, resampling, and interpolation
generally. (This means the entire `cores` submodule is also excluded.)
On the other hand, the entire `Interval` type and all of the functional
`Curve` adaptors are included.

## Testing

Test modules are included and can be run locally (but they are also
included in CI).

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-09 14:19:44 +00:00
re0312
66bf160ec5
Explicit using clone_from (#14670)
# Objective

- after #14502 ,explicit using clone_from should has better performance
because it could reuse the resources to avoid unnecessary allocations.
2024-08-09 14:17:13 +00:00
AFKessen
e14f3cf402
Fix 3D Gizmo webgpu rendering (#14653)
# Objective

The changes made in https://github.com/bevyengine/bevy/pull/12252
introduced an previously fixed bug in webgpu rendering.

## Solution

This fix is based on https://github.com/bevyengine/bevy/pull/8910 and
applies the same vertex buffer layout assignment for the LineGizmo
Pipeline.

## Testing

- Tested the 3D Gizmo example in webgpu and webgl environments

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-09 02:55:56 +00:00
Gino Valente
297c0a3954
bevy_reflect: Add DynamicSet to dynamic_types example (#14665)
# Objective

The `dynamic_types` example was missing a reference to the newly added
`DynamicSet` type.

## Solution

Add `DynamicSet` to the `dynamic_types` example.

For parity with the other dynamic types, I also implemented
`FromIterator<T: Reflect>`, `FromIterator<Box<dyn Reflect>>`, and
`IntoIterator for &DynamicSet`.

## Testing

You can run the example locally:

```
cargo run --example dynamic_types
```
2024-08-08 22:26:18 +00:00
Gino Valente
aeef1c0f20
bevy_reflect: Update internal docs regarding anonymous function type names (#14666)
# Objective

As pointed out by @SkiFire13 on
[Discord](https://discord.com/channels/691052431525675048/1002362493634629796/1270624366119485441),
I was incorrect in #14641 regarding the type name of anonymous
functions. I had stated that they will return something like `fn(i32,
i32) -> i32`, but this is wrong. They actually behave like closures
(despite not technically being closures) and return something more like
`foo::bar::{{closure}}`.

This isn't a major issue because the reasoning behind #14641 still
stands. However, the internal documentation should probably be updated
so future contributors don't believe the lies I left behind.

## Solution

Updated the internal documentation for `create_info` to reflect the
actual type name of an anonymous function.

In that same module, I also added a test for function pointers and
updated all tests to include sanity checks for the `std::any::type_name`
of each category of callable.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```
2024-08-08 22:01:42 +00:00
Gino Valente
3f47273b72
bevy_state: Make reflect module public (#14667)
# Objective

CI is
[failing](https://github.com/bevyengine/bevy/actions/runs/10308658332/job/28536587448)
due to certain methods not being used.

## Solution

Make the `reflect` module public so that these warnings go away and so
that the `pub` items in these modules can be used.

## Testing

CI should pass.
2024-08-08 20:15:38 +00:00
eckz
8c2e70b744
Adding Reflect data types for States and FreelyMutableState. (#14643)
# Objective

- While developing a debug tool I saw the gap where it was not possible
to get all existing states from a World using reflection.
- This PR allows to iterate over all `States` types that exist in a
world, and modify them in case they implement `FreelyMutableState`.
- Two new methods are available on `App` and `SubApp` as helper to
register the data types:
  -  `register_state_reflect` and `register_mutable_state_reflect`

## Solution

- Two new data types are added:
- `ReflectState`: Allows to extract the current value of a state from
the World.
- `ReflectFreelyMutableState`: Allows to set the next state in a world,
similar to call `NextState::set`.
- There is no distinction between `States`, `SubStates` and
`ComputedStates`:
- `States` can register both `ReflectState` and
`ReflectFreelyMutableState`.
- `SubStates` can register both `ReflectState` and
`ReflectFreelyMutableState`.
  -  `ComputedStates` can register only `ReflectState` .

## Testing

- Added tests inside the `bevy_state` crate.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-08-08 00:07:00 +00:00
charlotte
994312ac6d
Fix TAA on camera with viewport (#14582)
# Objective

Closes #14526 

## Solution

The history texture was being created incorrectly with the viewport size
rather than target size. When viewport < target, this meant that the
render attachments would differer in size which causes a wgpu validation
error.

## Testing

Example in linked issue works.
2024-08-07 23:59:38 +00:00
Gino Valente
a0cc636ea3
bevy_reflect: Anonymous function parsing (#14641)
# Objective

### TL;DR

#14098 added the `FunctionRegistry` but had some last minute
complications due to anonymous functions. It ended up going with a
"required name" approach to ensure anonymous functions would always have
a name.

However, this approach isn't ideal for named functions since, by
definition, they will always have a name.

Therefore, this PR aims to modify function reflection such that we can
make function registration easier for named functions, while still
allowing anonymous functions to be registered as well.

### Context

Function registration (#14098) ran into a little problem: anonymous
functions.

Anonymous functions, including function pointers, have very non-unique
type names. For example, the anonymous function `|a: i32, b: i32| a + b`
has the type name of `fn(i32, i32) -> i32`. This obviously means we'd
conflict with another function like `|a: i32, b: i32| a - b`.

The solution that #14098 landed on was to always require a name during
function registration.

The downside with this is that named functions (e.g. `fn add(a: i32, b:
i32) -> i32 { a + b }`) had to redundantly provide a name. Additionally,
manually constructed `DynamicFunction`s also ran into this ergonomics
issue.

I don't entirely know how the function registry will be used, but I have
a strong suspicion that most of its registrations will either be named
functions or manually constructed `DynamicFunction`s, with anonymous
functions only being used here and there for quick prototyping or adding
small functionality.

Why then should the API prioritize the anonymous function use case by
always requiring a name during registration?

#### Telling Functions Apart

Rust doesn't provide a lot of out-of-the-box tools for reflecting
functions. One of the biggest hurdles in attempting to solve the problem
outlined above would be to somehow tell the different kinds of functions
apart.

Let's briefly recap on the categories of functions in Rust:

| Category           | Example                                   |
| ------------------ | ----------------------------------------- |
| Named function     | `fn add(a: i32, b: i32) -> i32 { a + b }` |
| Closure            | `\|a: i32\| a + captured_variable`          |
| Anonymous function | `\|a: i32, b: i32\| a + b`                  |
| Function pointer   | `fn(i32, i32) -> i32`                     |

My first thought was to try and differentiate these categories based on
their size. However, we can see that this doesn't quite work:

| Category           | `size_of` |
| ------------------ | --------- |
| Named function     | 0         |
| Closure            | 0+        |
| Anonymous function | 0         |
| Function pointer   | 8         |

Not only does this not tell anonymous functions from named ones, but it
struggles with pretty much all of them.

My second then was to differentiate based on type name:

| Category           | `type_name`             |
| ------------------ | ----------------------- |
| Named function     | `foo::bar::baz`         |
| Closure            | `foo::bar::{{closure}}` |
| Anonymous function | `fn() -> String`        |
| Function pointer   | `fn() -> String`        |

This is much better. While it can't distinguish between function
pointers and anonymous functions, this doesn't matter too much since we
only care about whether we can _name_ the function.

So why didn't we implement this in #14098?

#### Relying on `type_name`

While this solution was known about while working on #14098, it was left
out from that PR due to it being potentially controversial.

The [docs](https://doc.rust-lang.org/stable/std/any/fn.type_name.html)
for `std::any::type_name` state:

> The returned string must not be considered to be a unique identifier
of a type as multiple types may map to the same type name. Similarly,
there is no guarantee that all parts of a type will appear in the
returned string: for example, lifetime specifiers are currently not
included. In addition, the output may change between versions of the
compiler.

So that's it then? We can't use `type_name`?

Well, this statement isn't so much a rule as it is a guideline. And Bevy
is no stranger to bending the rules to make things work or to improve
ergonomics. Remember that before `TypePath`, Bevy's scene system was
entirely dependent on `type_name`. Not to mention that `type_name` is
being used as a key into both the `TypeRegistry` and the
`FunctionRegistry`.

Bevy's practices aside, can we reliably use `type_name` for this?

My answer would be "yes".

Anonymous functions are anonymous. They have no name. There's nothing
Rust could do to give them a name apart from generating a random string
of characters. But remember that this is a diagnostic tool, it doesn't
make sense to obfuscate the type by randomizing the output. So changing
it to be anything other than what it is now is very unlikely.

The only changes that I could potentially see happening are:

1. Closures replace `{{closure}}` with the name of their variable
2. Lifetimes are included in the output

I don't think the first is likely to happen, but if it does then it
actually works out in our favor: closures are now named!

The second point is probably the likeliest. However, adding lifetimes
doesn't mean we can't still rely on `type_name` to determine whether or
not a function is named. So we should be okay in this case as well.

## Solution

Parse the `type_name` of the function in the `TypedFunction` impl to
determine if the function is named or anonymous.

This once again makes `FunctionInfo::name` optional. For manual
constructions of `DynamicFunction`, `FunctionInfo::named` or
``FunctionInfo::anonymous` can be used.

The `FunctionRegistry` API has also been reworked to account for this
change.

`FunctionRegistry::register` no longer takes a name and instead takes it
from the supplied function, returning a
`FunctionRegistrationError::MissingName` error if the name is `None`.
This also doubles as a replacement for the old
`FunctionRegistry::register_dynamic` method, which has been removed.

To handle anonymous functions, a `FunctionRegistry::register_with_name`
method has been added. This works in the same way
`FunctionRegistry::register` used to work before this PR.

The overwriting methods have been updated in a similar manner, with
modifications to `FunctionRegistry::overwrite_registration`, the removal
of `FunctionRegistry::overwrite_registration_dynamic`, and the addition
of `FunctionRegistry::overwrite_registration_with_name`.

This PR also updates the methods on `App` in a similar way:
`App::register_function` no longer requires a name argument and
`App::register_function_with_name` has been added to handle anonymous
functions (and eventually closures).

## Testing

You can run the tests locally by running:

```
cargo test --package bevy_reflect --features functions
```

---

## Internal Migration Guide

> [!important]
> Function reflection was introduced as part of the 0.15 dev cycle. This
migration guide was written for developers relying on `main` during this
cycle, and is not a breaking change coming from 0.14.

> [!note]
> This list is not exhaustive. It only contains some of the most
important changes.

`FunctionRegistry::register` no longer requires a name string for named
functions. Anonymous functions, however, need to be registered using
`FunctionRegistry::register_with_name`.

```rust
// BEFORE
registry
  .register(std::any::type_name_of_val(&foo), foo)?
  .register("bar", || println!("Hello world!"));

// AFTER
registry
  .register(foo)?
  .register_with_name("bar", || println!("Hello world!"));
```

`FunctionInfo::name` is now optional. Anonymous functions and closures
will now have their name set to `None` by default. Additionally,
`FunctionInfo::new` has been renamed to `FunctionInfo::named`.
2024-08-07 03:11:08 +00:00
IceSentry
5abc32ceda
Add 2d opaque phase with depth buffer (#13069)
This PR is based on top of #12982

# Objective

- Mesh2d currently only has an alpha blended phase. Most sprites don't
need transparency though.
- For some 2d games it can be useful to have a 2d depth buffer

## Solution

- Add an opaque phase to render Mesh2d that don't need transparency
- This phase currently uses the `SortedRenderPhase` to make it easier to
implement based on the already existing transparent phase. A follow up
PR will switch this to `BinnedRenderPhase`.
- Add a 2d depth buffer
- Use that depth buffer in the transparent phase to make sure that
sprites and transparent mesh2d are displayed correctly

## Testing

I added the mesh2d_transforms example that layers many opaque and
transparent mesh2d to make sure they all get displayed correctly. I also
confirmed it works with sprites by modifying that example locally.

---

## Changelog

- Added `AlphaMode2d`
- Added `Opaque2d` render phase
- Camera2d now have a `ViewDepthTexture` component

## Migration Guide

- `ColorMaterial` now contains `AlphaMode2d`. To keep previous
behaviour, use `AlphaMode::BLEND`. If you know your sprite is opaque,
use `AlphaMode::OPAQUE`

## Follow up PRs

- See tracking issue: #13265

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2024-08-07 00:22:09 +00:00
Periwink
2334638556
Fix access conflicts for resources (#14635)
# Objective

- I made a mistake when fixing the merge conflicts here:
https://github.com/bevyengine/bevy/pull/14579#discussion_r1705377452

It wasn't caught because there's no easy way to trigger access conflicts
with resources without triggering them with components first.
2024-08-06 14:35:41 +00:00
Lubba64
8e20a3e313
Fix gizmos regression (#14633)
# Objective

- Fixes #14142

## Solution

- Make sure a regression test is written on this case that fails for the
current code base but works with the suggested patch linked in the
aforementioned issue. After this is confirmed to be working, apply the
patch.

## Testing

- Run the regression test in both contexts, outputs were as expected.
2024-08-06 14:00:32 +00:00
Zhixing Zhang
5fd0661c15
Making bevy_render an optional dependency for bevy_gizmos (#14448)
# Objective

This PR makes `bevy_render` an optional dependency for `bevy_gizmos`,
thereby allowing `bevy_gizmos` to be used with alternative rendering
backend.

Previously `bevy_gizmos` assumes that one of `bevy_pbr` or `bevy_sprite`
will be enabled. Here we introduced a new feature named `bevy_render`
which disables all rendering-related code paths. An alternative renderer
will then take the `LineGizmo` assets (made public in this PR) and issue
draw calls on their own. A new field `config_ty` was added to
`LineGizmo` to help looking up the related configuration info.

---

## Migration Guide
No user-visible changes needed from the users.
2024-08-06 13:09:10 +00:00
Periwink
e85c072372
Fix soudness issue with Conflicts involving read_all and write_all (#14579)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/14575
- There is a soundness issue because we use `conflicts()` to check for
system ambiguities + soundness issues. However since the current
conflicts is a `Vec<T>`, we cannot express conflicts where there is no
specific `ComponentId` at fault. For example `q1: Query<EntityMut>, q2:
Query<EntityMut>`
There was a TODO to handle the `write_all` case but it was never
resolved


## Solution

- Introduce an `AccessConflict` enum that is either a list of specific
ids that are conflicting or `All` if all component ids are conflicting

## Testing

- Introduced a new unit test to check for the `EntityMut` case

## Migration guide

The `get_conflicts` method of `Access` now returns an `AccessConflict`
enum instead of simply a `Vec` of `ComponentId`s that are causing the
access conflict. This can be useful in cases where there are no
particular `ComponentId`s conflicting, but instead **all** of them are;
for example `fn system(q1: Query<EntityMut>, q2: Query<EntityRef>)`
2024-08-06 10:55:31 +00:00
charlotte
3360b45153
Expose winit's MonitorHandle (#13669)
# Objective

Adds a new `Monitor` component representing a winit `MonitorHandle` that
can be used to spawn new windows and check for system monitor
information.

Closes #12955.

## Solution

For every winit event, check available monitors and spawn them into the
world as components.

## Testing

TODO:
- [x] Test plugging in and unplugging monitor during app runtime
- [x] Test spawning a window on a second monitor by entity id
- [ ] Since this touches winit, test all platforms

---

## Changelog

- Adds a new `Monitor` component that can be queried for information
about available system monitors.

## Migration Guide

- `WindowMode` variants now take a `MonitorSelection`, which can be set
to `MonitorSelection::Primary` to mirror the old behavior.

---------

Co-authored-by: Pascal Hertleif <pascal@technocreatives.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Pascal Hertleif <killercup@gmail.com>
2024-08-06 10:54:37 +00:00
Lubba64
897625c899
Add Reflect to OnReplace (#14620)
# Objective

- Fixes #14337 

## Solution

- Add a `cfg_attr` that derives `Refect` for this type. 

## Testing

- I am going to make sure the tests pass on this PR before requesting
review, If more testing is necessary let me know some good action steps
to take.
2024-08-06 01:31:13 +00:00
Gino Valente
0caeaa2ca9
bevy_reflect: Update serde tests for Set (#14616)
# Objective

Support for reflecting set-like types (e.g. `HashSet`) was added in
#13014. However, we didn't add any serialization tests to verify that
serialization works as expected.

## Solution

Update the serde tests.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```
2024-08-06 01:29:15 +00:00
Robert Walter
70a18d26e2
Glam 0.28 update - adopted (#14613)
Basically it's https://github.com/bevyengine/bevy/pull/13792 with the
bumped versions of `encase` and `hexasphere`.

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-06 01:28:00 +00:00
Christian Hughes
039bf90817
Improve documentation on Update vs FixedUpdate schedule dichotomy (#14600)
# Objective

When looking at documentation for the `Update` schedule, its not
entirely obvious that developers should actually be using the
`FixedUpdate` schedule for most of their game logic. We should directly
cross-link between the two, and give examples of which systems to put in
which schedules.

## Solution

Do just that.
2024-08-06 01:26:37 +00:00
Periwink
3a664b052d
Separate component and resource access (#14561)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/13139
- Fixes https://github.com/bevyengine/bevy/issues/7255
- Separates component from resource access so that we can correctly
handles edge cases like the issue above
- Inspired from https://github.com/bevyengine/bevy/pull/14472

## Solution

- Update access to have `component` fields and `resource` fields

## Testing

- Added some unit tests
2024-08-06 01:19:39 +00:00
Lixou
0d0f77a7ab
Add invert_winding for triangle list meshes (#14555)
# Objective

Implements #14547 

## Solution

Add a function `invert_winding` for `Mesh` that inverts the winding for
`LineList`, `LineStrip`, `TriangleList` and `TriangleStrip`.

## Testing

Tests added

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Alix Bott <bott.alix@gmail.com>
2024-08-06 01:16:43 +00:00
barsoosayque
5f2570eb4c
Export glTF skins as a Gltf struct (#14343)
# Objective

- Make skin data of glTF meshes available for users, so it would be
possible to create skinned meshes without spawning a scene.
- I believe it contributes to
https://github.com/bevyengine/bevy/issues/13681 ?

## Solution

- Add a new `GltfSkin`, representing skin data from a glTF file, new
member `skin` to `GltfNode` and both `skins` + `named_skins` to `Gltf`
(a la meshes/nodes).
- Rewrite glTF nodes resolution as an iterator which sorts nodes by
their dependencies (nodes without dependencies first). So when we create
`GltfNodes` with their associated `GltfSkin` while iterating, their
dependencies already have been loaded.
- Make a distinction between `GltfSkin` and
`SkinnedMeshInverseBindposes` in assets: prior to this PR,
`GltfAssetLabel::Skin(n)` was responsible not for a skin, but for one of
skin's components. Now `GltfAssetLabel::InverseBindMatrices(n)` will map
to `SkinnedMeshInverseBindposes`, and `GltfAssetLabel::Skin(n)` will map
to `GltfSkin`.

## Testing

- New test `skin_node` does just that; it tests whether or not
`GltfSkin` was loaded properly.

## Migration Guide

- Change `GltfAssetLabel::Skin(..)` to
`GltfAssetLabel::InverseBindMatrices(..)`.
2024-08-06 01:14:42 +00:00
Gino Valente
df61117850
bevy_reflect: Function registry (#14098)
# Objective

#13152 added support for reflecting functions. Now, we need a way to
register those functions such that they may be accessed anywhere within
the ECS.

## Solution

Added a `FunctionRegistry` type similar to `TypeRegistry`.

This allows a function to be registered and retrieved by name.

```rust
fn foo() -> i32 {
    123
}

let mut registry = FunctionRegistry::default();
registry.register("my_function", foo);

let function = registry.get_mut("my_function").unwrap();
let value = function.call(ArgList::new()).unwrap().unwrap_owned();
assert_eq!(value.downcast_ref::<i32>(), Some(&123));
```

Additionally, I added an `AppFunctionRegistry` resource which wraps a
`FunctionRegistryArc`. Functions can be registered into this resource
using `App::register_function` or by getting a mutable reference to the
resource itself.

### Limitations

#### `Send + Sync`

In order to get this registry to work across threads, it needs to be
`Send + Sync`. This means that `DynamicFunction` needs to be `Send +
Sync`, which means that its internal function also needs to be `Send +
Sync`.

In most cases, this won't be an issue because standard Rust functions
(the type most likely to be registered) are always `Send + Sync`.
Additionally, closures tend to be `Send + Sync` as well, granted they
don't capture any `!Send` or `!Sync` variables.

This PR adds this `Send + Sync` requirement, but as mentioned above, it
hopefully shouldn't be too big of an issue.

#### Closures

Unfortunately, closures can't be registered yet. This will likely be
explored and added in a followup PR.

### Future Work

Besides addressing the limitations listed above, another thing we could
look into is improving the lookup of registered functions. One aspect is
in the performance of hashing strings. The other is in the developer
experience of having to call `std::any::type_name_of_val` to get the
name of their function (assuming they didn't give it a custom name).

## Testing

You can run the tests locally with:

```
cargo test --package bevy_reflect
```

---

## Changelog

- Added `FunctionRegistry`
- Added `AppFunctionRegistry` (a `Resource` available from `bevy_ecs`)
- Added `FunctionRegistryArc`
- Added `FunctionRegistrationError`
- Added `reflect_functions` feature to `bevy_ecs` and `bevy_app`
- `FunctionInfo` is no longer `Default`
- `DynamicFunction` now requires its wrapped function be `Send + Sync`

## Internal Migration Guide

> [!important]
> Function reflection was introduced as part of the 0.15 dev cycle. This
migration guide was written for developers relying on `main` during this
cycle, and is not a breaking change coming from 0.14.

`DynamicFunction` (both those created manually and those created with
`IntoFunction`), now require `Send + Sync`. All standard Rust functions
should meet that requirement. Closures, on the other hand, may not if
they capture any `!Send` or `!Sync` variables from its environment.
2024-08-06 01:09:48 +00:00
Periwink
ec4cf024f8
Add a ComponentIndex and update QueryState creation/update to use it (#13460)
# Objective

To implement relations we will need to add a `ComponentIndex`, which is
a map from a Component to the list of archetypes that contain this
component.
One of the reasons is that with fragmenting relations the number of
archetypes will explode, so it will become inefficient to create and
update the query caches by iterating through the list of all archetypes.

In this PR, we introduce the `ComponentIndex`, and we update the
`QueryState` to make use of it:
- if a query has at least 1 required component (i.e. something other
than `()`, `Entity` or `Option<>`, etc.): for each of the required
components we find the list of archetypes that contain it (using the
ComponentIndex). Then, we select the smallest list among these. This
gives a small subset of archetypes to iterate through compared with
iterating through all new archetypes
- if it doesn't, then we keep using the current approach of iterating
through all new archetypes


# Implementation
- This breaks query iteration order, in the sense that we are not
guaranteed anymore to return results in the order in which the
archetypes were created. I think this should be fine because this wasn't
an explicit bevy guarantee so users should not be relying on this. I
updated a bunch of unit tests that were failing because of this.

- I had an issue with the borrow checker because iterating the list of
potential archetypes requires access to `&state.component_access`, which
was conflicting with the calls to
```
  if state.new_archetype_internal(archetype) {
      state.update_archetype_component_access(archetype, access);
  }
```
which need a mutable access to the state.

The solution I chose was to introduce a `QueryStateView` which is a
temporary view into the `QueryState` which enables a "split-borrows"
kind of approach. It is described in detail in this blog post:
https://smallcultfollowing.com/babysteps/blog/2018/11/01/after-nll-interprocedural-conflicts/

# Test

The unit tests pass.

Benchmark results:
```
❯ critcmp main pr
group                                  main                                   pr
-----                                  ----                                   --
iter_fragmented/base                   1.00   342.2±25.45ns        ? ?/sec    1.02   347.5±16.24ns        ? ?/sec
iter_fragmented/foreach                1.04   165.4±11.29ns        ? ?/sec    1.00    159.5±4.27ns        ? ?/sec
iter_fragmented/foreach_wide           1.03      3.3±0.04µs        ? ?/sec    1.00      3.2±0.06µs        ? ?/sec
iter_fragmented/wide                   1.03      3.1±0.06µs        ? ?/sec    1.00      3.0±0.08µs        ? ?/sec
iter_fragmented_sparse/base            1.00      6.5±0.14ns        ? ?/sec    1.02      6.6±0.08ns        ? ?/sec
iter_fragmented_sparse/foreach         1.00      6.3±0.08ns        ? ?/sec    1.04      6.6±0.08ns        ? ?/sec
iter_fragmented_sparse/foreach_wide    1.00     43.8±0.15ns        ? ?/sec    1.02     44.6±0.53ns        ? ?/sec
iter_fragmented_sparse/wide            1.00     29.8±0.44ns        ? ?/sec    1.00     29.8±0.26ns        ? ?/sec
iter_simple/base                       1.00      8.2±0.10µs        ? ?/sec    1.00      8.2±0.09µs        ? ?/sec
iter_simple/foreach                    1.00      3.8±0.02µs        ? ?/sec    1.02      3.9±0.03µs        ? ?/sec
iter_simple/foreach_sparse_set         1.00     19.0±0.26µs        ? ?/sec    1.01     19.3±0.16µs        ? ?/sec
iter_simple/foreach_wide               1.00     17.8±0.24µs        ? ?/sec    1.00     17.9±0.31µs        ? ?/sec
iter_simple/foreach_wide_sparse_set    1.06     95.6±6.23µs        ? ?/sec    1.00     90.6±0.59µs        ? ?/sec
iter_simple/sparse_set                 1.00     19.3±1.63µs        ? ?/sec    1.01     19.5±0.29µs        ? ?/sec
iter_simple/system                     1.00      8.1±0.10µs        ? ?/sec    1.00      8.1±0.09µs        ? ?/sec
iter_simple/wide                       1.05     37.7±2.53µs        ? ?/sec    1.00     35.8±0.57µs        ? ?/sec
iter_simple/wide_sparse_set            1.00     95.7±1.62µs        ? ?/sec    1.00     95.9±0.76µs        ? ?/sec
par_iter_simple/with_0_fragment        1.04     35.0±2.51µs        ? ?/sec    1.00     33.7±0.49µs        ? ?/sec
par_iter_simple/with_1000_fragment     1.00     50.4±2.52µs        ? ?/sec    1.01     51.0±3.84µs        ? ?/sec
par_iter_simple/with_100_fragment      1.02     40.3±2.23µs        ? ?/sec    1.00     39.5±1.32µs        ? ?/sec
par_iter_simple/with_10_fragment       1.14     38.8±7.79µs        ? ?/sec    1.00     34.0±0.78µs        ? ?/sec
```
2024-08-06 00:57:15 +00:00
Giacomo Stevanato
68ec6f4f50
Make QueryState::transmute&co validate the world of the &Components used (#14631)
# Objective

- Fix #14629

## Solution

- Make `QueryState::transmute`, `QueryState::transmute_filtered`,
`QueryState::join` and `QueryState::join_filtered` take a `impl
Into<UnsafeWorldCell>` instead of a `&Components` and validate their
`WorldId`

## Migration Guide

- `QueryState::transmute`, `QueryState::transmute_filtered`,
`QueryState::join` and `QueryState::join_filtered` now take a `impl
Into<UnsafeWorldCell>` instead of a `&Components`

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-08-05 22:39:31 +00:00
Rob Parrett
e164e5a873
Add link to with_children in with_child doc (#14604)
# Objective

Discourage users from using `with_child` for spawning multiple children.

## Solution

Add link to `with_children` in docs for `with_child`.
2024-08-04 13:36:52 +00:00
Ben Frankel
9b254aab1e
Explicitly order CameraUpdateSystem before UiSystem::Prepare (#14609)
# Objective

Fixes https://github.com/bevyengine/bevy/issues/14277.

May also fix https://github.com/bevyengine/bevy/issues/14255, needs
verification.

## Solution

Explicitly order `CameraUpdateSystem` before `UiSystem::Prepare`, so
that when the window resizes, `camera_system` will update the `Camera`'s
viewport size before `ui_layout_system` also reacts to the window resize
and tries to read the new `Camera` viewport size to set UI node sizes
accordingly.

## Testing

I tested that explicitly ordering `CameraUpdateSystem` _after_ triggers
the buggy behavior, and explicitly ordering it _before_ does not trigger
the buggy behavior or crash the app (which also demonstrates that the
system sets are ambiguous).

---

## Migration Guide

`CameraUpdateSystem` is now explicitly ordered before
`UiSystem::Prepare` instead of being ambiguous with it.
2024-08-04 13:34:51 +00:00
radiish
4b20d822e9
update hashbrown to 0.14.2 (#14603)
# Objective

- We previously had a dependency in `bevy_utils`, `hashbrown = 0.14`,
and used the `hashbrown::hash_table` api, which was introduced in
`0.14.2`.

## Solution

- Bump `hashbrown` to `0.14.2`

## Testing

- Now compiles with the minimum declared `hashbrown` version.

---
2024-08-04 13:23:28 +00:00
re0312
8235daaea0
Opportunistically use dense iteration for archetypal iteration (#14049)
# Objective
- currently, bevy employs sparse iteration if any of the target
components in the query are stored in a sparse set. it may lead to
increased cache misses in some cases, potentially impacting performance.
- partial fixes #12381 

## Solution

- use dense iteration when an archetype and its table have the same
entity count.
- to avoid introducing complicate unsafe noise, this pr only implement
for `for_each ` style iteration.
- added a benchmark to test performance for hybrid iteration.


## Performance


![image](https://github.com/bevyengine/bevy/assets/45868716/5cce13cf-6ff2-4861-9576-e75edc63bd46)

nearly 2x win in specific scenarios, and no performance degradation in
other test cases.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Christian Hughes <9044780+ItsDoot@users.noreply.github.com>
2024-08-02 21:18:15 +00:00
Lixou
7c80ae7313
Add depth_ndc_to_view_z for cpu-side (#14590)
# Objective

I want to get the visual depth (after view proj matrix stuff) of the
object beneath my cursor.
Even when having a write-back of the depth texture, you would still need
to convert the NDC depth to a logical value.

## Solution

This is done on shader-side by [this
function](e6261b0f5f/crates/bevy_pbr/src/render/view_transformations.wgsl (L151)),
which I ported over to the cpu-side.

I also added `world_to_viewport_with_depth` to get a `Vec3` instead of
`Vec2`.

---

If anyone knows a smarter solution to get the visual depth instead of
going `screen -> viewport ray -> screen`, please let me know :>
2024-08-02 15:37:29 +00:00
Rob Parrett
5b29402cc8
Add with_child to simplify spawning when there will only be one child (#14594)
# Objective

This idea came up in the context of a hypothetical "text sections as
entities" where text sections are children of a text bundle.

```rust
commands
    .spawn(TextBundle::default())
    .with_children(|parent} {
        parent.spawn(TextSection::from("Hello"));
    });
```

This is a bit cumbersome (but powerful and probably the way things are
headed). [`bsn!`](https://github.com/bevyengine/bevy/discussions/14437)
will eventually make this nicer, but in the mean time, this might
improve ergonomics for the common case where there is only one
`TextSection`.

## Solution

Add a `with_child` method to the `BuildChildren` trait that spawns a
single bundle and adds it as a child to the entity.

```rust
commands
    .spawn(TextBundle::default())
    .with_child(TextSection::from("Hello"));
```

## Testing

I added some tests, and modified the `button` example to use the new
method.

If any potential co-authors want to improve the tests, that would be
great.

## Alternatives

- Some sort of macro. See
https://github.com/tigregalis/bevy_spans_ent/blob/main/examples/macro.rs#L20.
I don't love this, personally, and it would probably be obsoleted by
`bsn!`.
- Wait for `bsn!`
- Add `with_children_batch` that takes an `Into<Iterator>` of bundles.
  ```rust
  with_children_batch(vec![TextSection::from("Hello")])
  ```
This is maybe not as useful as it sounds -- it only works with
homogeneous bundles, so no marker components or styles.
- If this doesn't seem valuable, doing nothing is cool with me.
2024-08-02 15:37:15 +00:00
Lixou
4c2cef2223
Reflection for DepthOfFieldSettings (#14588)
# Objective

I can't mutate the dof settings via tools like `bevy_inspector_egui`

## Solution

Add `Reflect` for `DepthOfFieldSettings` and `DepthOfFieldMode`
2024-08-02 15:36:39 +00:00
Joona Aalto
e6261b0f5f
Add Dir2::from_xy_unchecked and Dir3::from_xyz_unchecked (#14587)
# Objective

Bevy's direction types have `new` and `new_unchecked` constructors, but
no unchecked variant for the `Dir2::from_xy` and `Dir3::from_xyz`
methods.

For me, this has several times lead to constructing directions like
this, in cases where the components of the direction are already known
to be normalized:

```rust
let normal = Dir2::new_unchecked(Vec2::new(-ray.direction.x.signum(), 0.0));
```

```rust
segment.direction =
    Dir2::new_unchecked(Vec2::new(-segment.direction.x, segment.direction.y));
```

For consistency and ergonomics, it would be nice to have unchecked
variants of `Dir2::from_xy` and `Dir3::from_xyz`:

```rust
let normal = Dir2::from_xy_unchecked(-ray.direction.x.signum(), 0.0);
```

```rust
segment.direction = Dir2::from_xy_unchecked(-segment.direction.x, segment.direction.y);
```

## Solution

Add `Dir2::from_xy_unchecked` and `Dir3::from_xyz_unchecked`.
2024-08-02 13:10:13 +00:00
James O'Brien
b98d15f278
Skip batching for phase items from other pipelines (#14296)
# Objective

- Fix #14295

## Solution

- Early out when `GFBD::get_index_and_compare_data` returns None.

## Testing

- Tested on a selection of examples including `many_foxes` and
`3d_shapes`.
- Resolved the original issue in `bevy_vector_shapes`.
2024-08-02 00:15:42 +00:00
JJJimbo1
56c9d4489b
fix asymmetrical 9-slicing (#14148)
# Objective

Fixes #14147.

## Solution

Modify the slicing checks and algorithm to fully allow asymmetrical
textures to work.
Some opinionated code cleanup.

## Testing

Tested using the ui_texture_slice example and a custom asymmetrical
texture.

Before:

![asymmetrical_texture_slice_before](https://github.com/bevyengine/bevy/assets/88861660/00dafce1-904a-41ac-b5d9-faaf087b0681)

After:

![asymmetrical_texture_slice_after](https://github.com/bevyengine/bevy/assets/88861660/f3d742f3-6157-4d35-b383-aee4b8f6e7d0)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-01 20:03:23 +00:00
Brian Reavis
4c4a6c4506
Don’t prepare lights (and shadow map textures) for 2D cameras (#14574)
# Objective

When running the Metal debugger I noticed that 2D cameras have shadow
map textures from `bevy_pbr` built for them. For a 2560x1440 2D camera,
this PR saves about 40mb of texture memory.


![image](https://github.com/user-attachments/assets/925e9392-2721-41bb-83e9-25c84fd563cd)


![image](https://github.com/user-attachments/assets/0cc3c0a9-cbf7-431c-b444-952c28d4e9d0)


## Solution

- Added `With<Camera3d>` filter to the appropriate view queries.

## Testing

- This is a trivial fix (the examples still work)
2024-08-01 19:29:18 +00:00
Brezak
0c7df881e7
Properly handle repeated window close requests (#14573)
# Objective

Spamming the window close button on window may trigger a panic.

```
thread 'main' panicked at <Bevy repo>\crates\bevy_ecs\src\system\commands\mod.rs:1320:13:
error[B0003]: Could not insert a bundle (of type `bevy_window:🪟:ClosingWindow`) for entity 0v1#4294967296 because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic when applying buffers for system `bevy_window::system::close_when_requested`!
2024-08-01T15:00:29.742612Z  WARN bevy_ecs::world::command_queue: CommandQueue has un-applied commands being dropped. Did you forget to call SystemState::apply?
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
error: process didn't exit successfully: `target\debug\bevy.exe` (exit code: 101)
```

## Solution

Don't panic when trying to insert the `ClosingWindow` component into a
entity.

## Testing

Found and tested on windows. I haven't checked if this bug happens on
linux or macos.
For testing I ran this code:

```rust
use std::{thread, time::Duration};

use bevy::prelude::*;

fn lag() {
    thread::sleep(Duration::from_millis(300));
}

fn main() -> AppExit {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Update, lag)
        .run()
}
```

Then spammed the window close button. The panic no longer occurs.
2024-08-01 16:15:28 +00:00
SpecificProtagonist
0685d2da4d
B0003: Print caller (#14556)
# Objective

B0003 indicates that you tried to act upon a nonexistant entity, but
does not mention where the error occured:
```
2024-07-31T15:46:25.954840Z  WARN bevy_ecs::world: error[B0003]: Could not despawn entity Entity { index: 4294967295, generation: 1 } because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
```

## Solution

Include caller location:

```
2024-07-31T15:46:25.954840Z  WARN bevy_ecs::world: error[B0003]: src/main.rs:18:11: Could not despawn entity Entity { index: 4294967295, generation: 1 } because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
```

Open question: What should the exact message format be?

## Testing

None, this doesn't change any logic.
2024-08-01 00:14:48 +00:00
Guillaume Gomez
0e86675177
Add freebsd support for sysinfo (#14553)
I'm not sure if bevy works on FreeBSD or not. But in case it does,
better allow `sysinfo` to be used as well if users want.
2024-07-31 21:41:40 +00:00
Jan Hohenheim
6f7c554daa
Fix common capitalization errors in documentation (#14562)
WASM -> Wasm
MacOS -> macOS

Nothing important, just something that annoyed me for a while :)
2024-07-31 21:16:05 +00:00
Lixou
20264d0810
Make AnimationPlayer::start and ::play work accordingly to documentation (#14546)
# Objective

While scrolling through the animation crate, I was confused by the docs
and code for the two methods. One does nothing for resetting an
animation, the other just resets the weights for whatever reason.

## Solution

Made the functions work accordingly to their documentation.
`start` now replays the animation.
And `play` doesn't reset the weight anymore. I have no clue why it
should. `play` is there to don't do anything to an already existing
animation.

## Testing

I tested the current 0.14 code with bevy playground in the Animated Fox
exampled and changed it such that on pressing space, either `play` or
`start` would be called. Neither changed anything.
I then inlined the function for start there and it restarted the
animation, so it should work.

---

## Migration Guide

`AnimationPlayer::start` now correspondingly to its docs restarts a
running animation.
`AnimationPlayer::play` doesn't reset the weight anymore.
2024-07-31 14:07:53 +00:00
Guillaume Gomez
68dc7a8b8b
Update sysinfo version to 0.31.0 (#14551)
This release will likely remove a few dependencies in bevy since you
only need the `system` feature.
2024-07-31 14:06:52 +00:00
Rich Churcher
e579622a65
time_system is ambiguous_with event_update_system (#14544)
# Objective

Resolve possible ambiguity detection panic between `time_system` and
`event_update_system`.

Fixes #14524

## Solution

Sets `.ambiguous_with(event_update_system)` on `time_system`. This is
slightly new territory for me, so please treat with scepticism.

## Testing

As described in the issue, added
```
        .configure_schedules(ScheduleBuildSettings {
            ambiguity_detection: LogLevel::Error,
            ..default()
        })
```
to the `time` example and ran it.
2024-07-31 12:13:17 +00:00
Zeenobit
023e0e5bde
Fix Entity Debug Format (#14539)
# Objective

Fixes #12139

## Solution

See this comment on original issue for my proposal:
https://github.com/bevyengine/bevy/issues/12139#issuecomment-2241915791

This PR is an implementation of this proposal.

I modified the implementation of `fmt::Debug` to instead display
`0v0#12345` to ensure entity index, generation, and raw bits are all
present in the output for debug purposes while still keeping log message
concise.

`fmt::Display` remains as is (`0v0`) to offer an even shorter output.

To me, this is the most non-intrusive fix for this issue.

## Testing

Add `fn entity_debug` test

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-31 01:36:41 +00:00