Commit Graph

1963 Commits

Author SHA1 Message Date
Giacomo Stevanato
3141342f7f
Merge remote-tracking branch 'upstream/main' into split-bundle 2025-07-06 21:22:45 +02:00
Giacomo Stevanato
8e89511e47
Remove Bundle::register_required_components (#19967)
# Objective

- `Bundle::register_required_components` is not used anywhere, let's
remove it
2025-07-06 18:15:28 +00:00
atlv
c5fe7f0975
consistently dont use smallvec default features (#19972)
# Objective

- for smallvec some crates specify default features false, other dont.
turns out we dont need them

## Solution

- remove

## Testing

- 3d_scene
2025-07-06 04:25:26 +00:00
Giacomo Stevanato
f0d8639f3b
Merge remote-tracking branch 'upstream/main' into split-bundle 2025-07-05 20:03:48 +02:00
Daniel Skates
560429ebd9
Observer trigger refactor (#19935)
# Objective

- The usage of ComponentId is quite confusing: events are not
components. By newtyping this, we can prevent stupid mistakes, avoid
leaking internal details and make the code clearer for users and engine
devs reading it.
- Adopts https://github.com/bevyengine/bevy/pull/19755

---------

Co-authored-by: oscar-benderstone <oscarbenderstone@gmail.com>
Co-authored-by: Oscar Bender-Stone <88625129+oscar-benderstone@users.noreply.github.com>
2025-07-04 16:27:21 +00:00
atlv
1380a3b7f2
add must_use to register_component_hooks (#19945)
# Objective

- I accidentally left a `register_component_hooks` without actually
adding a hook and didnt notice

## Solution

- mark it must_use so it doesnt happen to other people (maybe this is
just skill issue on me though)
2025-07-04 16:24:46 +00:00
Chris Russell
6e918f56d8
Have System::run_unsafe return Result. (#19145)
# Objective

Allow combinator and pipe systems to delay validation of the second
system, while still allowing the second system to be skipped.

Fixes #18796

Allow fallible systems to be used as one-shot systems, reporting errors
to the error handler when used through commands.

Fixes #19722

Allow fallible systems to be used as run conditions, including when used
with combinators. Alternative to #19580.

Always validate parameters when calling the safe
`run_without_applying_deferred`, `run`, and `run_readonly` methods on a
`System`.

## Solution

Have `System::run_unsafe` return a `Result`.  

We want pipe systems to run the first system before validating the
second, since the first system may affect whether the second system has
valid parameters. But if the second system skips then we have no output
value to return! So, pipe systems must return a `Result` that indicates
whether the second system ran.

But if we just make pipe systems have `Out = Result<B::Out>`, then
chaining `a.pipe(b).pipe(c)` becomes difficult. `c` would need to accept
the `Result` from `a.pipe(b)`, which means it would likely need to
return `Result` itself, giving `Result<Result<Out>>`!

Instead, we make *all* systems return a `Result`! We move the handling
of fallible systems from `IntoScheduleConfigs` and `IntoObserverSystem`
to `SystemParamFunction` and `ExclusiveSystemParamFunction`, so that an
infallible system can be wrapped before being passed to a combinator.

As a side effect, this enables fallible systems to be used as run
conditions and one-shot systems.

Now that the safe `run_without_applying_deferred`, `run`, and
`run_readonly` methods return a `Result`, we can have them perform
parameter validation themselves instead of requiring each caller to
remember to call them. `run_unsafe` will continue to not validate
parameters, since it is used in the multi-threaded executor when we want
to validate and run in separate tasks.

Note that this makes type inference a little more brittle. A function
that returns `Result<T>` can be considered either a fallible system
returning `T` or an infallible system returning `Result<T>` (and this is
important to continue supporting `pipe`-based error handling)! So there
are some cases where the output type of a system can no longer be
inferred. It will work fine when directly adding to a schedule, since
then the output type is fixed to `()` (or `bool` for run conditions).
And it will work fine when `pipe`ing to a system with a typed input
parameter.

I used a dedicated `RunSystemError` for the error type instead of plain
`BevyError` so that skipping a system does not box an error or capture a
backtrace.
2025-07-03 21:48:09 +00:00
Wuketuke
4564a5ba0d
improved the entity_index_map unit test (#19936)
...which previously used a HashSet, whos iter has no ordering guarantee

fixes #19687
i also discovered that the asserted order in the unit test is reversed,
so i fixed that. I dont know if that reversed order is intentional

Edit: i referenced the wrong issue oops
2025-07-03 20:36:09 +00:00
Christian Hughes
ebf87f56ef
Use SlotMaps to store systems and system sets in Schedules (#19352)
# Objective

- First step towards #279

## Solution

Makes the necessary internal data structure changes in order to allow
system removal to be added in a future PR: `Vec`s storing systems and
system sets in `ScheduleGraph` have been replaced with `SlotMap`s.

See the included migration guide for the required changes.

## Testing

Internal changes only and no new features *should* mean no new tests are
requried.
2025-07-03 18:50:54 +00:00
Alix Bott
ee1807395e
Implement MapEntities for arrays, HashMap, BTreeMap, IndexMap (#19908)
# Objective

- `MapEntities` is not implemented for arrays, `HashMap`, `BTreeMap`,
and `IndexMap`.

## Solution

- Implement `MapEntities` for arrays, `HashMap`, `BTreeMap`, `IndexMap`

## Testing

- I didn't add a test for this as the implementations seems pretty
trivial
2025-07-02 14:50:55 +00:00
SpecificProtagonist
9e0c66bd65
Ecs derive docs (#19892)
# Objective

Concise syntax docs on `Component`/`Event` derives. Partial fix for
#19537.

## Solution

Only document syntax. The doc tests are set to ignore because the macro
relies on the presence of `bevy_ecs`.
2025-07-02 14:44:18 +00:00
SpecificProtagonist
c6ba3d31cf
EntityEvent derive: Fix silent error (#19894)
# Objective
The `EntityEvent` derive macro only parsed the first `entity_event`
attr, resulting in the following event having auto propagation silently
turned off:
```rust
#[derive(Event, EntityEvent)]
#[entity_event(traversal = &'static ChildOf)]
#[entity_event(auto_propagate)]
struct MyEvent;
```

This should either fail to compile or be parsed correctly.

## Solution

Parse all `entity_event`.

## Testing

Cargo expand the snippet above. I haven't added an extra test for this.
2025-07-01 03:20:54 +00:00
Guillaume Wafo-Tapa
6eb6afeb2d
Spawn batch with relationship (#19519)
# Objective

Fixes #19356
Issue: Spawning a batch of entities in relationship with the same target
adds the relationship between the target and only the last entity of the
batch. `spawn_batch` flushes only after having spawned all entities.
This means each spawned entity will have run the `on_insert` hook of its
`Relationship` component. Here is the relevant part of that hook:
```Rust
            if let Some(mut relationship_target) =
                target_entity_mut.get_mut::<Self::RelationshipTarget>()
            {
                relationship_target.collection_mut_risky().add(entity);
            } else {
                let mut target = <Self::RelationshipTarget as RelationshipTarget>::with_capacity(1);
                target.collection_mut_risky().add(entity);
                world.commands().entity(target_entity).insert(target);
            }
```
Given the above snippet and since there's no flush between spawns, each
entity finds the target without a `RelationshipTarget` component and
defers the insertion of that component with the entity's id as the sole
member of its collection. When the commands are finally flushed, each
insertion after the first replaces the one before and in the process
triggers the `on_replace` hook of `RelationshipTarget` which removes the
`Relationship` component from the corresponding entity. That's how we
end up in the invalid state.

## Solution

I see two possible solutions
1. Flush after every spawn
2. Defer the whole code snippet above

I don't know enough about bevy as a whole but 2. seems much more
efficient to me. This is what I'm proposing here. I have a doubt though
because I've started to look at #19348 that 1. would fix as well.

## Testing

I added a test for the issue. I've put it in `relationship/mod.rs` but I
could see it in `world/spawn_batch.rs` or `lib.rs` because the test is
as much about `spawn_batch` as it is about relationships.
2025-06-30 22:13:38 +00:00
François Mockers
1fe559730c
bevy_ecs: remove use of needless_return (#19859)
# Objective

- bevy_ecs has a expected lint that is both needed and unneeded

## Solution

- Change the logic so that it's always not needed

## Testing

`cargo clippy -p bevy_ecs --no-default-features --no-deps -- -D
warnings`
2025-06-29 17:12:33 +00:00
Brian Reavis
795e273a9a
Don't create errors for ignored failed commands (#19718)
# Objective

1. Reduce overhead from error handling for ECS commands that
intentionally ignore errors, such as `try_despawn`. These commands
currently allocate error objects and pass them to a no-op handler
(`ignore`), which can impact performance when many operations fail.

2. Fix a hang when removing `ChildOf` components during entity
despawning. Excessive logging of these failures can cause significant
hangs (I'm noticing around 100ms).
    - Fixes https://github.com/bevyengine/bevy/issues/19777
    - Fixes https://github.com/bevyengine/bevy/issues/19753

<img width="1387" alt="image"
src="https://github.com/user-attachments/assets/5c67ab77-97bb-46e5-b287-2c502bef9358"
/>


## Solution

* Added a `ignore_error` method to the `HandleError` trait to use
instead of `handle_error_with(ignore)`. It swallows errors and does not
create error objects.
* Replaced `remove::<ChildOf>` with `try_remove::<ChildOf>` to suppress
expected (?) errors and reduce log noise.

## Testing

- I ran these changes on a local project.
2025-06-29 16:34:20 +00:00
charlotte 🌸
92e65d5eb1
Upgrade to Rust 1.88 (#19825) 2025-06-26 19:38:19 +00:00
Giacomo Stevanato
f6fe7e8a17
Merge remote-tracking branch 'upstream/main' into split-bundle 2025-06-24 17:46:38 +02:00
dependabot[bot]
c7b5bc93c3
Update derive_more requirement from 1 to 2 (#19671)
Updates the requirements on
[derive_more](https://github.com/JelteF/derive_more) to permit the
latest version.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/JelteF/derive_more/releases">derive_more's
releases</a>.</em></p>
<blockquote>
<h2>2.0.1</h2>
<p><a href="https://docs.rs/derive_more/2.0.1">API docs</a>
<a
href="https://github.com/JelteF/derive_more/blob/v2.0.1/CHANGELOG.md#201---2025-02-03">Changelog</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/JelteF/derive_more/blob/master/CHANGELOG.md">derive_more's
changelog</a>.</em></p>
<blockquote>
<h2>2.0.1 - 2025-02-03</h2>
<h3>Added</h3>
<ul>
<li>Add crate metadata for the Rust Playground. This makes sure that the
Rust
Playground will have all <code>derive_more</code> features available
once
<a
href="https://docs.rs/selectors/latest/selectors"><code>selectors</code></a>
crate updates its
<code>derive_more</code> version.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/445">#445</a>)</li>
</ul>
<h2>2.0.0 - 2025-02-03</h2>
<h3>Breaking changes</h3>
<ul>
<li><code>use derive_more::SomeTrait</code> now imports macro only.
Importing macro with
its trait along is possible now via <code>use
derive_more::with_trait::SomeTrait</code>.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/406">#406</a>)</li>
<li>Top-level <code>#[display(&quot;...&quot;)]</code> attribute on an
enum now has defaulting behavior
instead of replacing when no wrapping is possible (no
<code>_variant</code> placeholder).
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/395">#395</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Associated types of type parameters not being treated as generics in
<code>Debug</code>
and <code>Display</code> expansions.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/399">#399</a>)</li>
<li><code>unreachable_code</code> warnings on generated code when
<code>!</code> (never type) is used.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/404">#404</a>)</li>
<li>Ambiguous associated item error when deriving <code>TryFrom</code>,
<code>TryInto</code> or <code>FromStr</code>
with an associated item called <code>Error</code> or <code>Err</code>
respectively.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/410">#410</a>)</li>
<li>Top-level <code>#[display(&quot;...&quot;)]</code> attribute on an
enum being incorrectly treated
as transparent or wrapping.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/395">#395</a>)</li>
<li>Omitted raw identifiers in <code>Debug</code> and
<code>Display</code> expansions.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/431">#431</a>)</li>
<li>Incorrect rendering of raw identifiers as field names in
<code>Debug</code> expansions.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/431">#431</a>)</li>
<li>Top-level <code>#[display(&quot;...&quot;)]</code> attribute on an
enum not working transparently
for directly specified fields.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/438">#438</a>)</li>
<li>Incorrect dereferencing of unsized fields in <code>Debug</code> and
<code>Display</code> expansions.
(<a
href="https://redirect.github.com/JelteF/derive_more/pull/440">#440</a>)</li>
</ul>
<h2>0.99.19 - 2025-02-03</h2>
<ul>
<li>Add crate metadata for the Rust Playground.</li>
</ul>
<h2>1.0.0 - 2024-08-07</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a78d8ee41d"><code>a78d8ee</code></a>
chore: Release</li>
<li><a
href="2aeee4d1c0"><code>2aeee4d</code></a>
Update changelog (<a
href="https://redirect.github.com/JelteF/derive_more/issues/446">#446</a>)</li>
<li><a
href="5afbaa1d8e"><code>5afbaa1</code></a>
Add Rust Playground metadata (<a
href="https://redirect.github.com/JelteF/derive_more/issues/445">#445</a>)</li>
<li><a
href="d6c3315f12"><code>d6c3315</code></a>
Prepare 2.0.0 release (<a
href="https://redirect.github.com/JelteF/derive_more/issues/444">#444</a>)</li>
<li><a
href="c5e5e82c0a"><code>c5e5e82</code></a>
Fix unsized fields usage in <code>Display</code>/<code>Debug</code>
derives (<a
href="https://redirect.github.com/JelteF/derive_more/issues/440">#440</a>,
<a
href="https://redirect.github.com/JelteF/derive_more/issues/432">#432</a>)</li>
<li><a
href="d391493a3c"><code>d391493</code></a>
Fix field transparency for top-level shared attribute in
<code>Display</code> (<a
href="https://redirect.github.com/JelteF/derive_more/issues/438">#438</a>)</li>
<li><a
href="f14c7a759a"><code>f14c7a7</code></a>
Fix raw identifiers usage in <code>Display</code>/<code>Debug</code>
derives (<a
href="https://redirect.github.com/JelteF/derive_more/issues/434">#434</a>,
<a
href="https://redirect.github.com/JelteF/derive_more/issues/431">#431</a>)</li>
<li><a
href="7b23de3d53"><code>7b23de3</code></a>
Update <code>convert_case</code> crate from 0.6 to 0.7 version (<a
href="https://redirect.github.com/JelteF/derive_more/issues/436">#436</a>)</li>
<li><a
href="cc9957e9cd"><code>cc9957e</code></a>
Fix <code>compile_fail</code> tests and make Clippy happy for 1.84 Rust
(<a
href="https://redirect.github.com/JelteF/derive_more/issues/435">#435</a>)</li>
<li><a
href="17d61c3118"><code>17d61c3</code></a>
Fix transparency and behavior of shared formatting on enums (<a
href="https://redirect.github.com/JelteF/derive_more/issues/395">#395</a>,
<a
href="https://redirect.github.com/JelteF/derive_more/issues/377">#377</a>,
<a
href="https://redirect.github.com/JelteF/derive_more/issues/411">#411</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/JelteF/derive_more/compare/v1.0.0...v2.0.1">compare
view</a></li>
</ul>
</details>
<br />


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

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

---

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

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot 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-06-24 11:13:04 +00:00
urben1680
546711b807
Split EntityClonerBuilder in OptOut and OptIn variants (#19649)
# Objective

Further tests after #19326 showed that configuring `EntityCloner` with
required components is bug prone and the current design has several
weaknesses in it's API:

- Mixing `EntityClonerBuilder::allow` and `EntityClonerBuilder::deny`
requires extra care how to support that which has an impact on
surrounding code that has to keep edge cases in mind. This is especially
true for attempts to fix the following issues. There is no use-case
known (to me) why someone would mix those.
- A builder with `EntityClonerBuilder::allow_all` configuration tries to
support required components like `EntityClonerBuilder::deny_all` does,
but the meaning of that is conflicting with how you'd expect things to
work:
- If all components should be cloned except component `A`, do you also
want to exclude required components of `A` too? Or are these also valid
without `A` at the target entity?
- If `EntityClonerBuilder::allow_all` should ignore required components
and not add them to be filtered away, which purpose has
`EntityClonerBuilder::without_required_components` for this cloner?
- Other bugs found with the linked PR are:
- Denying `A` also denies required components of `A` even when `A` does
not exist at the source entity
- Allowing `A` also allows required components of `A` even when `A` does
not exist at the source entity
- Adding `allow_if_new` filters to the cloner faces the same issues and
require a common solution to dealing with source-archetype sensitive
cloning

Alternative to #19632 and #19635.

# Solution

`EntityClonerBuilder` is made generic and split into
`EntityClonerBuilder<OptOut>` and `EntityClonerBuilder<OptIn>`

For an overview of the changes, see the migration guide. It is generally
a good idea to start a review of that.

## Algorithm

The generic of `EntityClonerBuilder` contains the filter data that is
needed to build and clone the entity components.

As the filter needs to be borrowed mutably for the duration of the
clone, the borrow checker forced me to separate the filter value and all
other fields in `EntityCloner`. The latter are now in the
`EntityClonerConfig` struct. This caused many changed LOC, sorry.

To make reviewing easier:

1. Check the migration guide
2. Many methods of `EntityCloner` now just call identitcal
`EntityClonerConfig` methods with a mutable borrow of the filter
3. Check `EntityClonerConfig::clone_entity_internal` which changed a bit
regarding the filter usage that is now trait powered (`CloneByFilter`)
to support `OptOut`, `OptIn` and `EntityClonerFilter` (an enum combining
the first two)
4. Check `OptOut` type that no longer tracks required components but has
a `insert_mode` field
5. Check `OptIn` type that has the most logic changes

# Testing

I added a bunch of tests that cover the new logic parts and the fixed
issues.

Benchmarks are in a comment a bit below which shows ~4% to 9%
regressions, but it varied wildly for me. For example at one run the
reflection-based clonings were on-par with main while the other are not,
and redoing that swapped the situation for both.

It would be really cool if I could get some hints how to get better
benchmark results or if you could run them on your machine too.

Just be aware this is not a Performance PR but a Bugfix PR, even if I
smuggled in some more functionalities. So doing changes to
`EntityClonerBuilder` is kind of required here which might make us bite
the bullet.

---------

Co-authored-by: eugineerd <70062110+eugineerd@users.noreply.github.com>
2025-06-24 00:12:08 +00:00
Rob Parrett
d3ad66f033
Fix some typos (#19788)
# Objective

- Notice a word duplication typo
- Small quest to fix similar or nearby typos with my faithful companion
`\b(\w+)\s+\1\b`

## Solution

Fix em
2025-06-23 22:32:46 +00:00
Testare
da83232fa8
Let Component::map_entities defer to MapEntities (#19414)
# Objective

The objective of this PR is to enable Components to use their
`MapEntities` implementation for `Component::map_entities`.

With the improvements to the entity mapping system, there is definitely
a huge reduction in boilerplate. However, especially since
`(Entity)HashMap<..>` doesn't implement `MapEntities` (I presume because
the lack of specialization in rust makes `HashMap<Entity|X, Entity|X>`
complicated), when somebody has types that contain these hashmaps they
can't use this approach.

More so, we can't even depend on the previous implementation, since
`Component::map_entities` is used instead of
`MapEntities::map_entities`. Outside of implementing `Component `and
`Component::map_entities` on these types directly, the only path forward
is to create a custom type to wrap the hashmaps and implement map
entities on that, or split these components into a wrapper type that
implement `Component`, and an inner type that implements `MapEntities`.

## Current Solution
The solution was to allow adding `#[component(map_entities)]` on the
component. By default this will defer to the `MapEntities`
implementation.

```rust
#[derive(Component)]
#[component(map_entities)]
struct Inventory {
    items: HashMap<Entity, usize>
}

impl MapEntities for Inventory {
    fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
        self.items = self.items
           .drain()
           .map(|(id, count)|(entity_mapper.get_mapped(id), count))
           .collect();
    }
}

```

You can use `#[component(map_entities = <function path>)]` instead to
substitute other code in for components. This function can also include
generics, but sso far I haven't been able to find a case where they are
needed.

```rust
#[derive(Component)]
#[component(map_entities = map_the_map)]
// Also works #[component(map_entities = map_the_map::<T,_>)]
struct Inventory<T> {
    items: HashMap<Entity, T>
}

fn map_the_map<T, M: EntityMapper>(inv: &mut Inventory<T>, entity_mapper: &mut M) {
    inv.items = inv.items
       .drain()
       .map(|(id, count)|(entity_mapper.get_mapped(id), count))
       .collect();
}

```

The idea is that with the previous changes to MapEntities, MapEntities
is implemented more for entity collections than for Components. If you
have a component that makes sense as both, `#[component(map_entities)]`
would work great, while otherwise a component can use
`#[component(map_entities = <function>)]` to change the behavior of
`Component::map_entities` without opening up the component type to be
included in other components.


## (Original Solution if you want to follow the PR)

The solution was to allow adding `#[component(entities)]` on the
component itself to defer to the `MapEntities` implementation

```rust
#[derive(Component)]
#[component(entities)]
struct Inventory {
    items: HashMap<Entity, usize>
}

impl MapEntities for Inventory {
    fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
        self.items = self.items
           .drain()
           .map(|(id, count)|(entity_mapper.get_mapped(id), count))
           .collect();
    }
}

```

## Testing

I tested this by patching my local changes into my own bevy project. I
had a system that loads a scene file and executes some logic with a
Component that contains a `HashMap<Entity, UVec2>`, and it panics when
Entity is not found from another query. Since the 0.16 update this
system has reliably panicked upon attempting to the load the scene.

After patching my code in, I added `#[component(entities)]` to this
component, and I was able to successfully load the scene.

Additionally, I wrote a doc test.

## Call-outs
### Relationships
This overrules the default mapping of relationship fields. Anything else
seemed more problematic, as you'd have inconsistent behavior between
`MapEntities` and `Component`.
2025-06-23 21:05:04 +00:00
Giacomo Stevanato
9711258657
Apply suggestions 2025-06-23 19:06:56 +02:00
Giacomo Stevanato
20fef0c58d
Merge remote-tracking branch 'upstream/main' into split-bundle 2025-06-23 11:52:22 +02:00
mgi388
efd17f133d
Rename num_entities to entity_count (#19781)
As discussed in
https://github.com/bevyengine/bevy/pull/19780#issuecomment-2994554024.
2025-06-23 05:08:02 +00:00
Alice Cecile
61a5a37584
Improve module structure of observers code (#19779)
# Objective

While working on #17607, I found myself confused and frustrated by the
tangled web woven by the various modules inside of our observers code.

Rather than tackle that as part of a big rewrite PR, I've decided to do
the mature (if frustrating) thing where you split out your trivial but
noisy refactoring first.

There are a large number of moving parts, especially in terms of
storage, and these are strewn willy-nilly across the module with no
apparent ordering. To make matters worse, this was almost all just
dumped into a multi-thousand LOC mod.rs at the root.

## Solution

I've reshuffled the modules, attempting to:
- reduce the size of the mod.rs file
- organize structs so that smaller structs are found after the larger
structs that contain them
- group related functionality together
- document why modules exist, and their broad organization

No functional changes have been made here, although I've had to increase
the visibility of a few fields from private to pub(crate) or pub(super)
to keep things compiling.

During these changes, I've opted for the lazy private module, public
re-export strategy, to avoid causing any breakages, both within and
outside of `bevy` itself. I think we can do better, but I want to leave
that for a proper cleanup pass at the end. There's no sense maintaining
migration guides and forcing multiple breaking changes throughout the
cycle.

## Testing

No functional changes; relying on existing test suite and the Rust
compiler.
2025-06-22 23:25:25 +00:00
theotherphil
7645ce91ed
Add newlines before impl blocks (#19746)
# Objective

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

# Solution

Add newlines before all impl blocks.

I suspect that at least some of these will be objectionable! If there's
a desired Bevy style for this then I'll update the PR. If not then we
can just close it - it's the work of a single find and replace.
2025-06-22 23:07:02 +00:00
github-actions[bot]
a466084167
Bump Version after Release (#19774)
Bump version after release
This PR has been auto-generated

Fixes #19766

---------

Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2025-06-22 23:06:43 +00:00
Trashtalk217
6dbe3600ed
Add num_entities() to World (#19780)
# Objective

There is a lot of `world.entities().len()`, especially in tests. In
tests, usually, the assumption is made that empty worlds do not contain
any entities. This is about to change (#19711), and as such all of these
tests are failing for that PR.

## Solution

`num_entities` is a convenience method that returns the number of
entities inside a world. It can later be adapted to exclude 'unexpected'
entities, associated with internal data structures such as Resources,
Queries, Systems. In general I argue for a separation of concepts where
`World` ignores internal entities in methods such as `iter_entities()`
and `clear_entities()`, that discussion is, however, separate from this
PR.

## Testing

I replaced most occurrences of `world.entities().len()` with
`world.num_entities()` and the tests passed.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-22 22:48:35 +00:00
urben1680
c6ae964709
EntityWorldMut methods do not automatically overwrite Relationship components (#19601)
# Objective

Some methods and commands carelessly overwrite `Relationship`
components. This may overwrite additional data stored at them which is
undesired.

Part of #19589

## Solution

A new private method will be used instead of insert:
`modify_or_insert_relation_with_relationship_hook_mode`.

This method behaves different to `insert` if `Relationship` is a larger
type than `Entity` and already contains this component. It will then use
the `modify_component` API and a new `Relationship::set_risky` method to
set the related entity, keeping all other data untouched.

For the `replace_related`(`_with_difference`) methods this also required
a `InsertHookMode` parameter for efficient modifications of multiple
children. The changes here are limited to the non-public methods.

I would appreciate feedback if this is all good.

# Testing

Added tests of all methods that previously could reset `Relationship`
data.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-22 00:22:05 +00:00
eugineerd
2d897380a0
add missing #[track_caller] (#19769)
# Objective

I've noticed that some methods with `MaybeLocation::caller` don't have
`#[track_caller]` which resulted in wrong locations reported when
`track_location` is enabled.

## Solution

add `#[track_caller]` to them.
2025-06-21 18:05:58 +00:00
Lailatova
5d5a95fa6e
Fix issue 19734: add dependency on bevy_utils for the bevy_ecs test. (#19738)
Without this dependency, the bevy_ecs tests fail with missing as_string
methods.

# Objective

 - Fixes #19734

## Solution

- add bevy_utils with feature = "Debug" to dev-dependencies 

## Testing

- Ran `cargo test -p bevy_ecs`
- Ran `taplo fmt --check`

---
2025-06-21 15:05:04 +00:00
Giacomo Stevanato
5942b7af22
Fix warning 2025-06-21 11:01:37 +02:00
Giacomo Stevanato
ef88ad85cd
Add &self parameter to Bundle methods 2025-06-21 10:52:14 +02:00
Giacomo Stevanato
e683a10d74
Add support for #[bundle(dynamic)] attribute 2025-06-21 10:45:54 +02:00
Giacomo Stevanato
c33033a5e7
Switch EntityWorldMut::retain to StaticBundle 2025-06-21 10:45:53 +02:00
Giacomo Stevanato
28a21bdaf3
Switch component removal to StaticBundle 2025-06-21 10:45:53 +02:00
Giacomo Stevanato
bd30a8b219
Require StaticBundle in batch spawning 2025-06-21 10:45:53 +02:00
Giacomo Stevanato
9a176a5171
Switch EntityClonerBuilder to StaticBundle 2025-06-21 10:45:53 +02:00
Giacomo Stevanato
9b0ab87373
Require StaticBundle in ReflectBundle 2025-06-21 10:45:53 +02:00
Giacomo Stevanato
ddd69c56c4
Switch Observer and Trigger to StaticBundle 2025-06-21 10:45:53 +02:00
Giacomo Stevanato
07f6d1df90
Switch Entity{Ref,Mut}Except to StaticBundle 2025-06-21 10:45:52 +02:00
Giacomo Stevanato
e806f5e5b0
Split Bundles methods for Bundle and StaticBundle 2025-06-21 10:45:52 +02:00
Giacomo Stevanato
ebc4143515
Implement StaticBundle for SpawnRelatedBundle and SpawnOneRelated 2025-06-21 10:45:52 +02:00
Giacomo Stevanato
9bb3f3c50b
Implement StaticBundle in the derive macro 2025-06-21 10:45:52 +02:00
Giacomo Stevanato
fd5202989c
Implement StaticBundle for tuples of StaticBundles 2025-06-21 10:45:52 +02:00
Giacomo Stevanato
a015f7da1e
Implement StaticBundle for Components 2025-06-21 10:45:52 +02:00
Giacomo Stevanato
c53f10a765
Introduce StaticBundle 2025-06-21 10:45:52 +02:00
Giacomo Stevanato
35166d9029
Refactor bundle derive (#19749)
# Objective

- Splitted off from  #19491
- Make adding generated code to the `Bundle` derive macro easier
- Fix a bug when multiple fields are `#[bundle(ignore)]`

## Solution

- Instead of accumulating the code for each method in a different `Vec`,
accumulate only the names of non-ignored fields and their types, then
use `quote` to generate the code for each of them in the method body.
- To fix the bug, change the code populating the `BundleFieldKind` to
push only one of them per-field (previously each `#[bundle(ignore)]`
resulted in pushing twice, once for the correct
`BundleFieldKind::Ignore` and then again unconditionally for
`BundleFieldKind::Component`)

## Testing

- Added a regression test for the bug that was fixed
2025-06-20 16:36:08 +00:00
Emerson Coskey
8e1d0051d2
Fix QueryData derive codegen (#19750)
Custom derived `QueryData` impls currently generate `Item` structs with
the lifetimes swapped, which blows up the borrow checker sometimes.

See:
https://discord.com/channels/691052431525675048/749335865876021248/1385509416086011914

could add a regression test, TBH I don't know the error well enough to
do that minimally. Seems like it's that both lifetimes on
`QueryData::Item` need to be covariant, but I'm not sure.
2025-06-20 15:48:16 +00:00
Chris Russell
d0550f58ae
Remove 's lifetime from WorldQuery::Fetch (#19720)
# Objective

Unblock #18162.

#15396 added the `'s` lifetime to `QueryData::Item` to make it possible
for query items to borrow from the state. The state isn't passed
directly to `QueryData::fetch()`, so it also added the `'s` lifetime to
`WorldQuery::Fetch` so that we can pass the borrows through there.

Unfortunately, having `WorldQuery::Fetch` borrow from the state makes it
impossible to have owned state, because we store the state and the
`Fetch` in the same `struct` during iteration.

## Solution

Undo the change to add the `'s` lifetime to `WorldQuery::Fetch`.

Instead, add a `&'s Self::State` parameter to `QueryData::fetch()` and
`QueryFilter::filter_fetch()` so that borrows from the state can be
passed directly to query items.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Emerson Coskey <emerson@coskey.dev>
2025-06-19 00:58:21 +00:00