Commit Graph

8533 Commits

Author SHA1 Message Date
JaySpruce
058497e0bb
Change Commands::get_entity to return Result and remove panic from Commands::entity (#18043)
## Objective

Alternative to #18001.

- Now that systems can handle the `?` operator, `get_entity` returning
`Result` would be more useful than `Option`.
- With `get_entity` being more flexible, combined with entity commands
now checking the entity's existence automatically, the panic in `entity`
isn't really necessary.

## Solution

- Changed `Commands::get_entity` to return `Result<EntityCommands,
EntityDoesNotExistError>`.
- Removed panic from `Commands::entity`.
2025-02-27 21:05:16 +00:00
Tim Overbeek
ccb7069e7f
Change ChildOf to Childof { parent: Entity} and support deriving Relationship and RelationshipTarget with named structs (#17905)
# Objective

fixes #17896 

## Solution

Change ChildOf ( Entity ) to ChildOf { parent: Entity }

by doing this we also allow users to use named structs for relationship
derives, When you have more than 1 field in a struct with named fields
the macro will look for a field with the attribute #[relationship] and
all of the other fields should implement the Default trait. Unnamed
fields are still supported.

When u have a unnamed struct with more than one field the macro will
fail.
Do we want to support something like this ? 

```rust
 #[derive(Component)]
 #[relationship_target(relationship = ChildOf)]
 pub struct Children (#[relationship] Entity, u8);
```
I could add this, it but doesn't seem nice.
## Testing

crates/bevy_ecs - cargo test


## Showcase


```rust

use bevy_ecs::component::Component;
use bevy_ecs::entity::Entity;

 #[derive(Component)]
 #[relationship(relationship_target = Children)]
 pub struct ChildOf {
     #[relationship]
     pub parent: Entity,
     internal: u8,
 };

 #[derive(Component)]
 #[relationship_target(relationship = ChildOf)]
 pub struct Children {
     children: Vec<Entity>
 };

```

---------

Co-authored-by: Tim Overbeek <oorbecktim@Tims-MacBook-Pro.local>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-042.client.nl.eduvpn.org>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-059.client.nl.eduvpn.org>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-054.client.nl.eduvpn.org>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-027.client.nl.eduvpn.org>
2025-02-27 19:22:17 +00:00
JaySpruce
67146bdef7
Add missing unsafe to entity_command::insert_by_id and make it more configurable (#18052)
## Objective

`insert_by_id` is unsafe, but I forgot to add that to the
manually-queueable version in `entity_command`.

It also can only insert using `InsertMode::Replace`, when it could
easily be configurable by threading an `InsertMode` parameter to the
final `BundleInserter::insert` call.

## Solution

- Add `unsafe` and safety comment.
- Add `InsertMode` parameter to `entity_command::insert_by_id`,
`EntityWorldMut::insert_by_id_with_caller`, and
`EntityWorldMut::insert_dynamic_bundle`.
- Add `InsertMode` parameter to `entity_command::insert` and remove
`entity_command::insert_if_new`, for consistency with the other
manually-queued insertion commands.
2025-02-27 06:20:32 +00:00
Zachary Harrold
ad016cb850
Improve bevy_reflect no_std support (#18060)
# Objective

- Fixes #18051

## Solution

- Switched function registry to use `bevy_platform_support::sync`
instead of `std::sync`
- Also documented that `debug_stack` (and transitively `debug`) require
`std`
- Also removed `std` from `wgpu-types` since that crate is now `no_std`
compatible

## Testing

- `cargo check -p bevy_reflect --no-default-features --features
critical-section,documentation,glam,glam/libm,smallvec,wgpu-types,functions
--target thumbv6m-none-eabi`

---

## Notes

With these changes, `bevy_reflect`'s feature support looks like this:

| Feature | `no_std` (Before) | `no_std` (After) | Notes |
| - | - | - | - |
| `default` |  |  | |
| `std` |  |  | |
| `documentation` | ✔️ | ✔️ | |
| `functions` |  | ✔️ | |
| `critical-section` | ✔️ | ✔️ | |
| `bevy` | ✔️* | ✔️* | Partial due to `smol_str` |
| `debug` |  |  | |
| `debug_stack` |  |  | |
| `petgraph` |  |  | |
| `glam` | ✔️* | ✔️* | Requires enabling `glam/libm` |
| `smallvec` | ✔️ | ✔️ | |
| `uuid` | ✔️* | ✔️* | Requires setting up `getrandom` backend |
| `wgpu-types ` |  | ✔️ | |
| `smol_str` | ✔️* | ✔️* | Partial due to `smol_str` not supporting
`portable-atomic` |
2025-02-27 06:16:10 +00:00
urben1680
2f384643c3
Bubble sync points if ignore_deferred, do not ignore if target system is exclusive (#17880)
# Objective

Fixes #17828

This fixes two bugs:

1. Exclusive systems should see the effect of all commands queued to
that point. That does not happen when the system is configured with
`*_ignore_deferred` which may lead to surprising situations. These
configurations should not behave like that.
2. If `*_ignore_deferred` is used, no sync point may be added at all
**after** the config. Currently this can happen if the last nodes in
that config have no deferred parameters themselves. Instead, sync points
should always be added after such a config, so long systems have
deferred parameters.

## Solution

1. When adding sync points on edges, do not consider
`AutoInsertApplyDeferredPass::no_sync_edges` if the target is an
exclusive system.
2. when going through the nodes in a directed way, store the information
that `AutoInsertApplyDeferredPass::no_sync_edges` suppressed adding a
sync point at the target node. Then, when the target node is evaluated
later by the iteration and that prior suppression was the case, the
target node will behave like it has deferred parameters even if the
system itself does not.

## Testing

I added a test for each bug, please let me know if more are wanted and
if yes, which cases you would want to see.
These tests also can be read as examples how the current code would
fail.
2025-02-26 20:39:23 +00:00
Ruslan Baynazarov
c7531074bc
Improve cubic segment bezier functionality (#17645)
# Objective

- Fixes #17642

## Solution

- Implemented method `new_bezier(points: [P; 4]) -> Self` for
`CubicSegment<P>`
- Old implementation of `new_bezier` is now `new_bezier_easing(p1: impl
Into<Vec2>, p2: impl Into<Vec2>) -> Self` (**breaking change**)
- ~~added method `new_bezier_with_anchor`, which can make a bezier curve
between two points with one control anchor~~
- added methods `iter_positions`, `iter_velocities`,
`iter_accelerations`, the same as in `CubicCurve` (**copied code,
potentially can be reduced)**
- bezier creation logic is moved from `CubicCurve` to `CubicSegment`,
removing the unneeded allocation

## Testing

- Did you test these changes? If so, how?
  - Run tests inside `crates/bevy_math/`
  - Tested the functionality in my project
- Are there any parts that need more testing?
  - Did not run `cargo test` on the whole bevy directory because of OOM
- Performance improvements are expected when creating `CubicCurve` with
`new_bezier` and `new_bezier_easing`, but not tested
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
  - Use in any code that works created `CubicCurve::new_bezier`
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  - I don't think relevant

---

## Showcase

```rust
// Imagine a car goes towards a local target

// Create a simple `CubicSegment`, without using heap
let planned_path = CubicSegment::new_bezier([
    car_pos,
    car_pos + car_dir * turn_radius,
    target_point - target_dir * turn_radius,
    target_point,
]);

// Check if the planned path itersect other entities
for pos in planned_path.iter_positions(8) {
   // do some collision checks
}
```

## Migration Guide

> This section is optional. If there are no breaking changes, you can
delete this section.

- Replace `CubicCurve::new_bezier` with `CubicCurve::new_bezier_easing`
2025-02-26 20:36:54 +00:00
Chris Russell
94e6fa168f
Fix unsoundness in QueryIter::sort_by (#17826)
# Objective

`QueryIter::sort_by()` is unsound. It passes the lens items with the
full `'w` lifetime, and a malicious user could smuggle them out of the
closure where they could alias with the query results.

## Solution

Make the sort closures generic in the lifetime parameter of the lens
item. This ensures the lens items cannot outlive the call to the
closure.

## Testing

Added a compile-fail test that demonstrates the unsound pattern.

## Migration Guide

The `sort` family of methods on `QueryIter` unsoundly gave access
`L::Item<'w>` with the full `'w` lifetime. It has been shortened to
`L::Item<'w>` so that items cannot escape the comparer. If you get
lifetime errors using these methods, you will need to make the comparer
generic in the new lifetime. Often this can be done by replacing named
`'w` with `'_`, or by replacing the use of a function item with a
closure.

```rust
// Before: Now fails with "error: implementation of `FnMut` is not general enough"
query.iter().sort_by::<&C>(Ord::cmp);
// After: Wrap in a closure
query.iter().sort_by::<&C>(|l, r| Ord::cmp(l, r));

query.iter().sort_by::<&C>(comparer);
// Before: Uses specific `'w` lifetime from some outer scope
// now fails with "error: implementation of `FnMut` is not general enough"
fn comparer(left: &&'w C, right: &&'w C) -> Ordering { /* ... */ }
// After: Accepts any lifetime using inferred lifetime parameter
fn comparer(left: &&C, right: &&C) -> Ordering { /* ... */ }
2025-02-26 20:36:37 +00:00
François Mockers
23cf8ffe6c
update CI patch for EventWriter::send deprecation (#18044)
# Objective

- EventWriter::send has been deprecated, but it was used by one of the
CI patch

## Solution

- Use EventWriter::write instead
2025-02-26 20:36:15 +00:00
Matty Weatherley
4b1745f813
BRP resource methods (#17423)
# Objective

So far, built-in BRP methods allow users to interact with entities'
components, but global resources have remained beyond its reach. The
goal of this PR is to take the first steps in rectifying this shortfall.

## Solution

Added five new default methods to BRP:
- `bevy/get_resource`: Extracts the value of a given resource from the
world.
- `bevy/insert_resource`: Serializes an input value to a given resource
type and inserts it into the world.
- `bevy/remove_resource`: Removes the given resource from the world.
- `bevy/mutate_resource`: Replaces the value of a field in a given
resource with the result of serializing a given input value.
- `bevy/list_resources`: Lists all resources in the type registry with
an available `ReflectResource`.

## Testing

Added a test resource to the `server` example scene that you can use to
mess around with the new BRP methods.

## Showcase

Resources can now be retrieved and manipulated remotely using a handful
of new BRP methods. For example, a resource that looks like this:
```rust
#[derive(Resource, Reflect, Serialize, Deserialize)]
#[reflect(Resource, Serialize, Deserialize)]
pub struct PlayerSpawnSettings {
  pub location: Vec2,
  pub lives: u8,
}
```

can be manipulated remotely as follows.

Retrieving the value of the resource:
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "bevy/get_resource",
  "params": {
    "resource": "path::to::my::module::PlayerSpawnSettings"
  }
}
```

Inserting a resource value into the world:
```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "bevy/insert_resource",
  "params": {
    "resource": "path::to::my::module::PlayerSpawnSettings",
    "value": {
      "location": [
        2.5, 
        2.5
      ],
      "lives": 25
    }
  }
}
```

Removing the resource from the world:
```json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "bevy/remove_resource",
  "params": {
    "resource": "path::to::my::module::PlayerSpawnSettings"
  }
}
```

Mutating a field of the resource specified by a path:
```json
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "bevy/mutate_resource",
  "params": {
    "resource": "path::to::my::module::PlayerSpawnSettings",
    "path": ".location.x",
    "value": -3.0
  }
}
```

Listing all manipulable resources in the type registry:
```json
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "bevy/list_resources"
}
```
2025-02-26 20:29:47 +00:00
Lucas Franca
11db71727d
Refactor bevy_gltf (#15994)
# Objective

Refactor `bevy_gltf`, the criteria for the split is kind of arbitrary
but at least it is not a 2.6k line file.

## Solution

Move methods and structs found in `bevy_gltf/loader.rs` into multiple
new modules.

## Testing

`cargo run -p ci`
2025-02-26 01:00:11 +00:00
Aevyrie
831ecf030c
TaskPool: Prefer task completion over executing new tasks (#18009)
# Objective

- Systems that use the task pool, either explicitly or implicitly using
parallel queries, will often end up executing tasks from different
systems.
- This can cause random tasks to block the main or render schedule at
random, adding frame variance and increasing frame times when CPU bound.
- This profile is a common occurrence on `main`.
`propagate_parent_transforms` takes more than twice as long as it
should, blocking the main schedule for that time, because it uses `task
pool.scope`, which has decided to execute tasks from the render schedule
on the main schedule.

![image](https://github.com/user-attachments/assets/c363be40-82ce-451e-ba29-3eb4ee367e0b)


## Solution

- In task pool scope execution, prefer to check if the current task is
complete instead of ticking the executor to find new work.

## Testing

- Ran the scene viewer with tracy to look for images like the one in the
objective section.
- Things look much, much better, and I could not find any occurrences: 

![image](https://github.com/user-attachments/assets/18b79394-1a7c-49c1-820a-f5207e81bbac)

![image](https://github.com/user-attachments/assets/e7d4831d-66c3-41c1-ae2c-a624724c9965)
2025-02-26 00:08:36 +00:00
Sou1gh0st
f2b37c733e
Deduplicate register_inherited_required_components (#16519)
# Objective
- Fixes #16416 

## Solution
- Add a intermediate temporary mutable `RequiredComponents` to get avoid
of the borrowing issues.

## Testing

- I have run `cargo test --package bevy_ecs -- --exact --show-output`
and past all the tests.
2025-02-25 23:59:58 +00:00
Martín Maita
05bad0673f
Removes compile_fail glob pattern (#18040)
# Objective

- Attempts to fix #17876.

## Solution

- Reverted some changes that added a glob pattern to match all
`compile_fail` crates. This should enable Dependabot to create PRs
again.
- Added a TODO comment to not forget that this glob matching failure
should also be fixed in the Dependabot repo.
2025-02-25 23:53:17 +00:00
SpecificProtagonist
25cee420e4
do_not_recommend interned Labels (#17950)
# Objective

Follow up on #17441 now that `do_not_recommend` is stable.

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-02-25 23:46:21 +00:00
JaySpruce
36a2f7fdf1
Remove unnecessary bounds on EntityClonerBuilder::without_required_components (#17969)
## Objective

The closure argument for
`EntityClonerBuilder::without_required_components` has `Send + Sync +
'static` bounds, but the closure immediately gets called and never needs
to be sent anywhere. (This was my fault :P )

## Solution

Remove the bounds so that users aren't unnecessarily restricted.

I also took the opportunity to expand the tests a little.
2025-02-25 23:34:46 +00:00
François Mockers
2f633c18ba
Split example runs to their own GitHub workflow (#18039)
# Objective

- next step for #15918 

## Solution

- Move jobs for macOS, Linux and Windows to their own workflow
- Remove running on push to `main` from workflows CI and validation
2025-02-25 23:30:31 +00:00
Tristan Maindron
0f153ffb44
Prevent last_trigger_id from overflowing (#17978)
# Objective

This prevents overflowing the `last_trigger_id` property that leads to a
panic in debug mode.

```bash
panicked at C:\XXX\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.15.2\src\world\unsafe_world_cell.rs:630:18:
attempt to add with overflow
Encountered a panic when applying buffers for system `bevy_sprite::calculate_bounds_2d`!
Encountered a panic in system `bevy_ecs::schedule::executor::apply_deferred`!
```

## Solution

As this value is only used for detecting a change, we can wrap when it
reaches max value.

## Testing

This can be verified by running `cargo run --example observers`
2025-02-25 23:12:51 +00:00
Brezak
b43c8f8c4f
Add methods to add single entity relationships (#18038)
# Objective

Closes #17572

## Solution

Add the `add_one_related` methods to `EntityCommands` and
`EntityWorldMut`.

## Testing

Clippy

---

## Showcase

The `EntityWorldMut` and `FilteredResourcesMut` now include the
`add_one_related` method if you just want to relate 2 entities.
2025-02-25 23:07:44 +00:00
Brezak
5961df7c89
Automatically close weekly ci issue if weekly ci succeeds (#18016)
# Objective

It's not always obvious when the issue created by the weekly CI run is
safe to close.

## Solution

Automatically close it when a weekly CI run succeeds so it doesn't get
forgotten.

## Testing

Hope.
2025-02-25 19:21:04 +00:00
Patrick Walton
df5e3a7b96
Load each glTF skin at most once. (#18026)
Currently, we reload a glTF skin each time we encounter a node that
references it. By checking for duplicates, PR #18013 turned this into a
fatal error. But this was always wasteful. This commit fixes the issue
by caching each skin by its index as we load it.

The Maya babylon.js export plugin likes to emit glTFs with multiple
nodes that reference the same skin, so this effectively unbreaks Maya
rigs.
2025-02-25 01:27:29 +00:00
Zachary Harrold
20813aed64
Handle TriggerTargets that are combinations for components/entities (#18024)
# Objective

* Fixes https://github.com/bevyengine/bevy/issues/14074
* Applies CI fixes for #16326

It is currently not possible to issues a trigger that targets a specific
list of components AND a specific list of entities

## Solution

We can now use `((A, B), (entity_1, entity_2))` as a trigger target, as
well as the reverse

## Testing

Added a unit test.

The triggering rules for observers are quite confusing:

Triggers once per entity target

For each entity target, an observer system triggers if any of its
components matches the trigger target components (but it triggers at
most once, since we use an internal counter to make sure that an
observer can run at most once per entity target)

(copied from #14563)
(copied from #16326)

## Notes

All credit to @BenjaminBrienen and @cBournhonesque! Just applying a
small fix to this PR so it can be merged.

---------

Co-authored-by: Benjamin Brienen <Benjamin.Brienen@outlook.com>
Co-authored-by: Christian Hughes <xdotdash@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-02-24 23:57:34 +00:00
andriyDev
ed1143b26b
Make adding a subasset label return a result for if there is a duplicate label. (#18013)
# Objective

- Makes #18010 more easily debuggable. This doesn't solve that issue,
but protects us from it in the future.

## Solution

- Make `LoadContext::add_labeled_asset` and friends return an error if
it finds a duplicate asset.

## Testing

- Added a test - it fails before the fix.

---

## Migration Guide

- `AssetLoader`s must now handle the case of a duplicate subasset label
when using `LoadContext::add_labeled_asset` and its variants. If you
know your subasset labels are unique by construction (e.g., they include
an index number), you can simply unwrap this result.
2025-02-24 21:51:40 +00:00
VitalyR
6bae04ab36
Add usage notes for register_component (#18011)
# Objective

- Add usage notes for `register_component`, fixes #16447


## Testing

CI
2025-02-24 21:47:25 +00:00
Patrick Walton
172c020b60
Cache opaque deferred entities so we don't have to continuously re-queue them. (#18007)
Even though opaque deferred entities aren't placed into the `Opaque3d`
bin, we still want to cache them as though they were, so that we don't
have to re-queue them every frame. This commit implements that logic,
reducing the time of `queue_material_meshes` to near-zero on Caldera.
2025-02-24 21:44:24 +00:00
Patrick Walton
5d7a60592d
Add a new #[data] attribute to AsBindGroup that allows packing data for multiple materials into a single array. (#17965)
Currently, the structure-level `#[uniform]` attribute of `AsBindGroup`
creates a binding array of individual buffers, each of which contains
data for a single material. A more efficient approach would be to
provide a single buffer with an array containing all of the data for all
materials in the bind group. Because `StandardMaterial` uses
`#[uniform]`, this can be notably inefficient with large numbers of
materials.

This patch introduces a new attribute on `AsBindGroup`, `#[data]`, which
works identically to `#[uniform]` except that it concatenates all the
data into a single buffer that the material bind group allocator itself
manages. It also converts `StandardMaterial` to use this new
functionality. This effectively provides the "material data in arrays"
feature.
2025-02-24 21:38:55 +00:00
Vic
a1717331e4
implement UniqueEntityArray (#17954)
# Objective

Continuation of #17589 and #16547.

`get_many` is last of the `many` methods with a missing `unique`
counterpart.
It both takes and returns arrays, thus necessitates a matching
`UniqueEntityArray` type!
Plus, some slice methods involve returning arrays, which are currently
missing from `UniqueEntitySlice`.

## Solution

Add the type, the related methods and trait impls.

Note that for this PR, we abstain from some methods/trait impls that
create `&mut UniqueEntityArray`, because it can be successfully
mem-swapped. This can potentially invalidate a larger slice, which is
the same reason we punted on some mutable slice methods in #17589. We
can follow-up on all of these together in a following PR.

The new `unique_array` module is not glob-exported, because the trait
alias `unique_array::IntoIter` would conflict with
`unique_vec::IntoIter`.
The solution for this is to make the various `unique_*` modules public,
which I intend to do in yet another PR.
2025-02-24 21:36:59 +00:00
Matty Weatherley
1cbaabaa64
Incorporate OIT into MeshPipelineKey used by the LineGizmoPipeline (#17946)
# Objective

Fixes #17945 

## Solution

Check if the view being extracted has OIT enabled and incorporate the
associated bit into the mesh pipeline key.

I basically have no idea what's going on in the renderer, so let me know
if I missed something, which is extraordinarily possible.

## Testing

I modified the `order_independent_transparency` example to put
everything on the default render layer and render a gizmo at the origin.
Previously, this would cause the application to panic.
2025-02-24 21:31:54 +00:00
andriyDev
bb09751cf0
Fix observer/hook OnReplace and OnRemove triggering when removing a bundle even when the component is not present on the entity (#17942)
# Objective

- Fixes #17897.

## Solution

- When removing components, we filter the list of components in the
removed bundle based on whether they are actually in the archetype.

## Testing

- Added a test.
2025-02-24 21:25:31 +00:00
Florian Poncabaré
910e405ea9
Allow prepass to run without ATTRIBUTE_NORMAL (#17881)
# Objective

Allow prepass to run without ATTRIBUTE_NORMAL. 
This is needed for custom materials with non-standard vertex attributes.
For example a voxel material with manually packed vertex data.

Fixes #13054.

This PR covers the first part of the **stale** PR #13569 to only focus
on fixing #13054.

## Solution

- Only push normals `vertex_attributes` when the layout contains
`Mesh::ATTRIBUTE_NORMAL`

## Testing

- Did you test these changes? If so, how?
**Tested the fix on my own project with a mesh without normal
attribute.**
- Are there any parts that need more testing?
  **I don't think so.**
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
**Prepass should not be blocked on a mesh without normal attributes
(with or without custom material).**
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  **Probably irrelevant, but Windows/Vulkan.**
2025-02-24 21:22:34 +00:00
Lucas Franca
7d7c43dd62
Add uv_transform to ColorMaterial (#17879)
# Objective

Implements and closes #17515

## Solution

Add `uv_transform` to `ColorMaterial`

## Testing

Create a example similar to `repeated_texture` but for `Mesh2d` and
`MeshMaterial2d<ColorMaterial>`

## Showcase


![image](https://github.com/user-attachments/assets/72943b9b-59a6-489a-96a2-f9c245f0dd53)

## Migration Guide

Add `uv_transform` field to constructors of `ColorMaterial`
2025-02-24 21:17:26 +00:00
Carter Weinberg
fa85a14de1
Adding More Comments to the Embedded Assets Example (#17865)
# Objective

I noticed when I was looking at the embedded assets example that there
wasn't any comments on it to indicate what an embedded asset is and why
anyone would want to make one.

## Solution

I added some more comments to the example that gives more detail about
embedded assets and how they work. Feel free to be aggressive with
rewriting these comments however, I just think the example could use
something haha.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-02-24 21:13:24 +00:00
notmd
f7b2a02224
Make sprite picking opt-in (#17842)
# Objective

Fix https://github.com/bevyengine/bevy/issues/17108
See
https://github.com/bevyengine/bevy/issues/17108#issuecomment-2653020889

## Solution

- Make the query match `&Pickable` instead `Option<&Pickable>`

## Testing

- Run the `sprite_picking` example and everything still work


## Migration Guide

- Sprite picking are now opt-in, make sure you insert `Pickable`
component when using sprite picking.
```diff
-commands.spawn(Sprite { .. } );
+commands.spawn((Sprite { .. }, Pickable::default());
```
2025-02-24 21:09:39 +00:00
Chanceler Shaffer
cb628516d1
Add core Error to InvalidDirectionError (#17820)
# Objective

Fixes #17761 

## Solution
- Added core error to InvalidDirectionError

## Testing

- Did you test these changes? If so, how?
- An added test that pulls in anyhow as a dev dependency to ensure the
conversion is accounted for in creation via From
- Are there any parts that need more testing?
  - I'm unsure but probably not due to being a trivial change 
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- I did not try a fully built version of Bevy. Relied purely on tests.
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  - Only windows

---------

Co-authored-by: Chanceler Shaffer <cshaffer2@lululemon.com>
Co-authored-by: Chanceler Shaffer <chancelershaffer@lululemon.com>
2025-02-24 21:04:22 +00:00
ickshonpe
d76c782f39
Remove camera from UiBatch (#17663)
# Objective

A `TransparentUI` phase's items all target the same camera so there is
no need to store the current camera entity in `UiBatch` and ending the
current `UiBatch` on camera changes is pointless as the camera doesn't
change.

## Solution

Remove the `camera` fields from `UiBatch`, `UiShadowsBatch` and
`UiTextureSliceBatch`.
Remove the camera changed check from `prepare_uinodes`.

## Testing
The `multiple_windows` and `split_screen` examples both render UI
elements to multiple cameras and can be used to test these changes.

The UI material plugin already didn't store the camera entity per batch
and worked fine without it.
2025-02-24 20:55:30 +00:00
Zachary Harrold
76e9bf9c99
Automatically enable portable-atomic when required (#17570)
# Objective

- Contributes to #15460
- Reduce quantity and complexity of feature gates across Bevy

## Solution

- Used `target_has_atomic` configuration variable to automatically
detect impartial atomic support and automatically switch to
`portable-atomic` over the standard library on an as-required basis.

## Testing

- CI

## Notes

To explain the technique employed here, consider getting `Arc` either
from `alloc::sync` _or_ `portable-atomic-util`. First, we can inspect
the `alloc` crate to see that you only have access to `Arc` _if_
`target_has_atomic = "ptr"`. We add a target dependency for this
particular configuration _inverted_:

```toml
[target.'cfg(not(target_has_atomic = "ptr"))'.dependencies]
portable-atomic-util = { version = "0.2.4", default-features = false }
```

This ensures we only have the dependency when it is needed, and it is
entirely excluded from the dependency graph when it is not. Next, we
adjust our configuration flags to instead of checking for `feature =
"portable-atomic"` to instead check for `target_has_atomic = "ptr"`:

```rust
// `alloc` feature flag hidden for brevity

#[cfg(not(target_has_atomic = "ptr"))]
use portable_atomic_util as arc;

#[cfg(target_has_atomic = "ptr")]
use alloc::sync as arc;

pub use arc::{Arc, Weak};
```

The benefits of this technique are three-fold:

1. For platforms without full atomic support, the functionality is
enabled automatically.
2. For platforms with atomic support, the dependency is never included,
even if a feature was enabled using `--all-features` (for example)
3. The `portable-atomic` feature no longer needs to virally spread to
all user-facing crates, it's instead something handled within
`bevy_platform_support` (with some extras where other dependencies also
need their features enabled).
2025-02-24 20:52:46 +00:00
andriyDev
7f14581495
Use explicitly added ApplyDeferred stages when computing automatically inserted sync points. (#16782)
# Objective

- The previous implementation of automatically inserting sync points did
not consider explicitly added sync points. This created additional sync
points. For example:

```
A-B
C-D-E
```

If `A` and `B` needed a sync point, and `D` was an `ApplyDeferred`, an
additional sync point would be generated between `A` and `B`.

```
A-D2-B
C-D -E
```

This can result in the following system ordering:
```
A-D2-(B-C)-D-E
```
Where only `B` and `C` run in parallel. If we could reuse `D` as the
sync point, we would get the following ordering:
```
(A-C)-D-(B-E)
```
Now we have two more opportunities for parallelism!

## Solution

- In the first pass, we:
    - Compute the number of sync points before each node
- This was already happening but now we consider `ApplyDeferred` nodes
as creating a sync point.
- Pick an arbitrary explicit `ApplyDeferred` node for each "sync point
index" that we can (some required sync points may be missing!)
- In the second pass, we:
- For each edge, if two nodes have a different number of sync points
before them then there must be a sync point between them.
- Look for an explicit `ApplyDeferred`. If one exists, use it as the
sync point.
    - Otherwise, generate a new sync point.

I believe this should also gracefully handle changes to the
`ScheduleGraph`. Since automatically inserted sync points are inserted
as systems, they won't look any different to explicit sync points, so
they are also candidates for "reusing" sync points.

One thing this solution does not handle is "deduping" sync points. If
you add 10 sync points explicitly, there will be at least 10 sync
points. You could keep track of all the sync points at the same
"distance" and then hack apart the graph to dedup those, but that could
be a follow-up step (and it's more complicated since you have to worry
about transferring edges between nodes).

## Testing

- Added a test to test the feature.
-  The existing tests from all our crates still pass.

## Showcase

- Automatically inserted sync points can now reuse explicitly inserted
`ApplyDeferred` systems! Previously, Bevy would add new sync points
between systems, ignoring the explicitly added sync points. This would
reduce parallelism of systems in some situations. Now, the parallelism
has been improved!
2025-02-24 20:51:34 +00:00
Lucien Menassol
7c7b1e9fc0
Load and convert RGB8 dds textures (#12952)
# Objective

- Closes #12944.

## Solution

- Load `R8G8B8` textures by transcoding to an rgba format since `wgpu`
does not support texture formats with 3 channels.
- Switch to erroring out instead of panicking on an invalid dds file.

---

## Changelog

### Added

- DDS Textures with the `R8G8B8` format are now supported. They require
an additional conversion step, so using `R8G8B8A8` or a similar format
is preferable for texture loading performance.
2025-02-24 20:45:56 +00:00
dependabot[bot]
0855a0e8ad
Bump crate-ci/typos from 1.29.7 to 1.29.9 (#18012)
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.29.7 to
1.29.9.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.29.9</h2>
<h2>[1.29.9] - 2025-02-20</h2>
<h3>Fixes</h3>
<ul>
<li><em>(action)</em> Correctly get binary for some aarch64 systems</li>
</ul>
<h2>v1.29.8</h2>
<h2>[1.29.8] - 2025-02-19</h2>
<h3>Features</h3>
<ul>
<li>Attempt to build Linux aarch64 binaries</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h2>[1.29.9] - 2025-02-20</h2>
<h3>Fixes</h3>
<ul>
<li><em>(action)</em> Correctly get binary for some aarch64 systems</li>
</ul>
<h2>[1.29.8] - 2025-02-19</h2>
<h3>Features</h3>
<ul>
<li>Attempt to build Linux aarch64 binaries</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="212923e4ff"><code>212923e</code></a>
chore: Release</li>
<li><a
href="659bf55253"><code>659bf55</code></a>
docs: Update changelog</li>
<li><a
href="092b7056bb"><code>092b705</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1239">#1239</a>
from codingskynet/fix/support-aarch64</li>
<li><a
href="298a143ed0"><code>298a143</code></a>
chore(gh): Fix links</li>
<li><a
href="d7059d7796"><code>d7059d7</code></a>
chore(gh): Fix links</li>
<li><a
href="636d59beef"><code>636d59b</code></a>
chore(gh): Encourage people to check for dupes</li>
<li><a
href="51cd88f328"><code>51cd88f</code></a>
chore(gh): Add a data template</li>
<li><a
href="c11cf6c0e1"><code>c11cf6c</code></a>
chore(gh): Try to clarify template</li>
<li><a
href="3bcb919148"><code>3bcb919</code></a>
fix: add aarch64 on arm64 cond</li>
<li><a
href="1ea66fdf4d"><code>1ea66fd</code></a>
docs(readme): Call out that the readme is not exhaustive</li>
<li>Additional commits viewable in <a
href="https://github.com/crate-ci/typos/compare/v1.29.7...v1.29.9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crate-ci/typos&package-manager=github_actions&previous-version=1.29.7&new-version=1.29.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-24 11:27:55 +00:00
Zachary Harrold
5241e09671
Upgrade to Rust Edition 2024 (#17967)
# Objective

- Fixes #17960

## Solution

- Followed the [edition upgrade
guide](https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html)

## Testing

- CI

---

## Summary of Changes

### Documentation Indentation

When using lists in documentation, proper indentation is now linted for.
This means subsequent lines within the same list item must start at the
same indentation level as the item.

```rust
/* Valid */
/// - Item 1
///   Run-on sentence.
/// - Item 2
struct Foo;

/* Invalid */
/// - Item 1
///     Run-on sentence.
/// - Item 2
struct Foo;
```

### Implicit `!` to `()` Conversion

`!` (the never return type, returned by `panic!`, etc.) no longer
implicitly converts to `()`. This is particularly painful for systems
with `todo!` or `panic!` statements, as they will no longer be functions
returning `()` (or `Result<()>`), making them invalid systems for
functions like `add_systems`. The ideal fix would be to accept functions
returning `!` (or rather, _not_ returning), but this is blocked on the
[stabilisation of the `!` type
itself](https://doc.rust-lang.org/std/primitive.never.html), which is
not done.

The "simple" fix would be to add an explicit `-> ()` to system
signatures (e.g., `|| { todo!() }` becomes `|| -> () { todo!() }`).
However, this is _also_ banned, as there is an existing lint which (IMO,
incorrectly) marks this as an unnecessary annotation.

So, the "fix" (read: workaround) is to put these kinds of `|| -> ! { ...
}` closuers into variables and give the variable an explicit type (e.g.,
`fn()`).

```rust
// Valid
let system: fn() = || todo!("Not implemented yet!");
app.add_systems(..., system);

// Invalid
app.add_systems(..., || todo!("Not implemented yet!"));
```

### Temporary Variable Lifetimes

The order in which temporary variables are dropped has changed. The
simple fix here is _usually_ to just assign temporaries to a named
variable before use.

### `gen` is a keyword

We can no longer use the name `gen` as it is reserved for a future
generator syntax. This involved replacing uses of the name `gen` with
`r#gen` (the raw-identifier syntax).

### Formatting has changed

Use statements have had the order of imports changed, causing a
substantial +/-3,000 diff when applied. For now, I have opted-out of
this change by amending `rustfmt.toml`

```toml
style_edition = "2021"
```

This preserves the original formatting for now, reducing the size of
this PR. It would be a simple followup to update this to 2024 and run
`cargo fmt`.

### New `use<>` Opt-Out Syntax

Lifetimes are now implicitly included in RPIT types. There was a handful
of instances where it needed to be added to satisfy the borrow checker,
but there may be more cases where it _should_ be added to avoid
breakages in user code.

### `MyUnitStruct { .. }` is an invalid pattern

Previously, you could match against unit structs (and unit enum
variants) with a `{ .. }` destructuring. This is no longer valid.

### Pretty much every use of `ref` and `mut` are gone

Pattern binding has changed to the point where these terms are largely
unused now. They still serve a purpose, but it is far more niche now.

### `iter::repeat(...).take(...)` is bad

New lint recommends using the more explicit `iter::repeat_n(..., ...)`
instead.

## Migration Guide

The lifetimes of functions using return-position impl-trait (RPIT) are
likely _more_ conservative than they had been previously. If you
encounter lifetime issues with such a function, please create an issue
to investigate the addition of `+ use<...>`.

## Notes

- Check the individual commits for a clearer breakdown for what
_actually_ changed.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2025-02-24 03:54:47 +00:00
JoshValjosh
2953db7f8f
impl Eq/PartialEq for MeshMaterial{2|3}d (#17990)
# Objective

`Eq`/`PartialEq` are currently implemented for `MeshMaterial{2|3}d` only
through the derive macro. Since we don't have perfect derive yet, the
impls are only present for `M: Eq` and `M: PartialEq`. On the other
hand, I want to be able to compare material components for my toy
reactivity project.

## Solution

Switch to manual `Eq`/`PartialEq` impl.

## Testing

Boy I hope this didn't break anything!
2025-02-23 23:58:10 +00:00
aloucks
8122b35ce2
Fix window freezing when dragged or resized on Windows (#18004)
# Objective

Fixes #17488

## Solution

The world update logic happened in the the `about_to_wait` winit window
callback, but this is is not correct as (1) the winit documentation
states that the callback should not be used for that purpose and (2) the
callback is not fired when the window is resized or being dragged.
However, that callback was used in #11245 to fix an iOS bug (which
caused the regression). The solution presented here is a workaround
until the event loop code can be re-written.

## Testing

I confirmed that the `eased_motion` example continued to be animated
when dragging or resizing the window.


https://github.com/user-attachments/assets/ffaf0abf-4cd7-479b-83e9-e1850aaf3513
2025-02-23 23:56:10 +00:00
JaySpruce
283654cf4d
Small Commands error handling cleanup (#17904)
- Remove references to the short-lived `CommandError` type.
- Add a sentence to the explanation of error handlers.
- Clean up spacing/linebreaks.
- Use `where` notation for command-related trait `impl`s to make the big
ones easier to parse.
2025-02-23 22:41:43 +00:00
AlephCubed
726d8ac4b0
Added top level reflect_documentation feature flag. (#17892)
Fixes #17811.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2025-02-23 21:21:50 +00:00
AlephCubed
5f86668bbb
Renamed EventWriter::send methods to write. (#17977)
Fixes #17856.

## Migration Guide
- `EventWriter::send` has been renamed to `EventWriter::write`.
- `EventWriter::send_batch` has been renamed to
`EventWriter::write_batch`.
- `EventWriter::send_default` has been renamed to
`EventWriter::write_default`.

---------

Co-authored-by: François Mockers <mockersf@gmail.com>
2025-02-23 21:18:52 +00:00
Aevyrie
dba1f7a7b6
Parallel Transform Propagation (#17840)
# Objective

- Make transform propagation faster.

## Solution

- Work sharing worker threads
- Parallel tree traversal excluding leaves
- Second cache friendly wide pass over all leaves
- 3-10x faster than main

## Testing

- Tracy
- Caldera hotel is showing 3-7x faster on my M4 Max. Timing for bevy's
existing transform system shifts wildly run to run, so I don't know that
I would advertise a particular number. But this implementation is faster
in a... statistically significant way.

![image](https://github.com/user-attachments/assets/b4a48fc6-86b8-4b9c-8c5e-5b746c1d163b)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2025-02-23 20:43:09 +00:00
François Mockers
e4e70a7473
don't update mesa for wasm example run (#17999)
# Objective

- running wasm examples in CI currently timeout, this blocks merging PRs

## Solution

- Don't update mesa but uses the version provided by the latest ubuntu
- Alternative to #17998

## Testing

run in a docker container: `docker run --rm -it ubuntu`
```
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y curl git software-properties-common nodejs npm build-essential
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
. "$HOME/.cargo/env"
rustup target install wasm32-unknown-unknown

curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cargo binstall wasm-bindgen-cli -y


git clone https://github.com/bevyengine/bevy
cd bevy

cd .github/start-wasm-example
npm install
npx playwright install --with-deps
cd ../..

python3 -m http.server --directory examples/wasm &

xvfb-run cargo run -p build-wasm-example -- --browsers firefox --frames 25 --test 2d_shapes
```
2025-02-23 20:09:12 +00:00
Patrick Walton
ad3817cc1b
Reallocate materials when they change. (#17979)
PR #17898 regressed this, causing much of #17970. This commit fixes the
issue by freeing and reallocating materials in the
`MaterialBindGroupAllocator` on change. Note that more efficiency is
possible, but I opted for the simple approach because (1) we should fix
this bug ASAP; (2) I'd like #17965 to land first, because that unlocks
the biggest potential optimization, which is not recreating the bind
group if it isn't necessary to do so.
2025-02-22 08:19:43 +00:00
Patrick Walton
465306bc5e
Reextract a mesh on the next frame if its material couldn't be prepared on the frame we first encountered it. (#17963)
We might not be able to prepare a material on the first frame we
encounter a mesh using it for various reasons, including that the
material hasn't been loaded yet or that preparing the material is
exceeding the per-frame cap on number of bytes to load. When this
happens, we currently try to find the material in the
`MaterialBindGroupAllocator`, fail, and then fall back to group 0, slot
0, the default `MaterialBindGroupId`, which is obviously incorrect.
Worse, we then fail to dirty the mesh and reextract it when we *do*
finish preparing the material, so the mesh will continue to be rendered
with an incorrect material.

This patch fixes both problems. In `collect_meshes_for_gpu_building`, if
we fail to find a mesh's material in the `MeshBindGroupAllocator`, then
we detect that case, bail out, and add it to a list,
`MeshesToReextractNextFrame`. On subsequent frames, we process all the
meshes in `MeshesToReextractNextFrame` as though they were changed. This
ensures both that we don't render a mesh if its material hasn't been
loaded and that we start rendering the mesh once its material does load.

This was first noticed in the intermittent Pixel Eagle failures in the
`testbed_3d` patch in #17898, although the problem has actually existed
for some time. I believe it just so happened that the changes to the
allocator in that PR caused the problem to appear more commonly than it
did before.
2025-02-22 08:19:25 +00:00
Patrick Walton
fffe623297
Fix bugs in the new non-bindless mesh material allocator. (#17980)
This patch fixes two bugs in the new non-bindless material allocator
that landed in PR #17898:

1. A debug assertion to prevent double frees had been flipped: we
checked to see whether the slot was empty before freeing, while we
should have checked to see whether the slot was full.

2. The non-bindless allocator returned `None` when querying a slab that
hadn't been prepared yet instead of returning a handle to that slab.
This resulted in a 1-frame delay when modifying materials. In the
`animated_material` example, this resulted in the meshes never showing
up at all, because that example changes every material every frame.

Together with #17979, this patch locally fixes the problems with
`animated_material` on macOS that were reported in #17970.
2025-02-22 06:29:00 +00:00
Rob Parrett
9046859ca8
Fix 1x1 dds textures being interpreted as 1-dimensional (#17890)
# Objective

Fixes #8615

## Solution

Bevy currently interprets 1x1 dds textures as 1-dimensional. I think it
might be more common for game engines to assume two dimensions in this
ambiguous case. [citation needed]

I reworked the dimension choosing logic to only use 1d if there's a
dimension > 1, and assume 2d otherwise. I kept the assumption that
compressed textures are probably 2d.

## Testing

Modified `sprite.rs` to use `Tex_0012_0.dds` from the linked issue.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-02-22 01:59:51 +00:00