Commit graph

916 commits

Author SHA1 Message Date
CatThingy
89cbc78d3d
Require #[derive(Event)] on all Events (#7086)
# Objective

Be consistent with `Resource`s and `Components` and have `Event` types
be more self-documenting.
Although not susceptible to accidentally using a function instead of a
value due to `Event`s only being initialized by their type, much of the
same reasoning for removing the blanket impl on `Resource` also applies
here.

* Not immediately obvious if a type is intended to be an event
* Prevent invisible conflicts if the same third-party or primitive types
are used as events
* Allows for further extensions (e.g. opt-in warning for missed events)

## Solution

Remove the blanket impl for the `Event` trait. Add a derive macro for
it.

---

## Changelog

- `Event` is no longer implemented for all applicable types. Add the
`#[derive(Event)]` macro for events.

## Migration Guide

* Add the `#[derive(Event)]` macro for events. Third-party types used as
events should be wrapped in a newtype.
2023-06-06 14:44:32 +00:00
radiish
1efc762924
reflect: stable type path v2 (#7184)
# Objective

- Introduce a stable alternative to
[`std::any::type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html).
- Rewrite of #5805 with heavy inspiration in design.
- On the path to #5830.
- Part of solving #3327.


## Solution

- Add a `TypePath` trait for static stable type path/name information.
- Add a `TypePath` derive macro.
- Add a `impl_type_path` macro for implementing internal and foreign
types in `bevy_reflect`.

---

## Changelog

- Added `TypePath` trait.
- Added `DynamicTypePath` trait and `get_type_path` method to `Reflect`.
- Added a `TypePath` derive macro.
- Added a `bevy_reflect::impl_type_path` for implementing `TypePath` on
internal and foreign types in `bevy_reflect`.
- Changed `bevy_reflect::utility::(Non)GenericTypeInfoCell` to
`(Non)GenericTypedCell<T>` which allows us to be generic over both
`TypeInfo` and `TypePath`.
- `TypePath` is now a supertrait of `Asset`, `Material` and
`Material2d`.
- `impl_reflect_struct` needs a `#[type_path = "..."]` attribute to be
specified.
- `impl_reflect_value` needs to either specify path starting with a
double colon (`::core::option::Option`) or an `in my_crate::foo`
declaration.
- Added `bevy_reflect_derive::ReflectTypePath`.
- Most uses of `Ident` in `bevy_reflect_derive` changed to use
`ReflectTypePath`.

## Migration Guide

- Implementors of `Asset`, `Material` and `Material2d` now also need to
derive `TypePath`.
- Manual implementors of `Reflect` will need to implement the new
`get_type_path` method.

## Open Questions
- [x] ~This PR currently does not migrate any usages of
`std::any::type_name` to use `bevy_reflect::TypePath` to ease the review
process. Should it?~ Migration will be left to a follow-up PR.
- [ ] This PR adds a lot of `#[derive(TypePath)]` and `T: TypePath` to
satisfy new bounds, mostly when deriving `TypeUuid`. Should we make
`TypePath` a supertrait of `TypeUuid`? [Should we remove `TypeUuid` in
favour of
`TypePath`?](2afbd85532 (r961067892))
2023-06-05 20:31:20 +00:00
Alice Cecile
cbd4abf0fc
Rename apply_system_buffers to apply_deferred (#8726)
# Objective

- `apply_system_buffers` is an unhelpful name: it introduces a new
internal-only concept
- this is particularly rough for beginners as reasoning about how
commands work is a critical stumbling block

## Solution

- rename `apply_system_buffers` to the more descriptive `apply_deferred`
- rename related fields, arguments and methods in the internals fo
bevy_ecs for consistency
- update the docs


## Changelog

`apply_system_buffers` has been renamed to `apply_deferred`, to more
clearly communicate its intent and relation to `Deferred` system
parameters like `Commands`.

## Migration Guide

- `apply_system_buffers` has been renamed to `apply_deferred`
- the `apply_system_buffers` method on the `System` trait has been
renamed to `apply_deferred`
- the `is_apply_system_buffers` function has been replaced by
`is_apply_deferred`
- `Executor::set_apply_final_buffers` is now
`Executor::set_apply_final_deferred`
- `Schedule::apply_system_buffers` is now `Schedule::apply_deferred`

---------

Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
2023-06-02 14:04:13 +00:00
ira
5f936b42b1
Resolve clippy issues for rust 1.70.0 (#8738)
- Supress false positive `redundant_clone` lints.
- Supress inactionable `result_large_err` lint.
Most of the size(50 out of 68 bytes) is coming from
`naga::WithSpan<naga::valid::ValidationError>`
2023-06-01 21:05:05 +00:00
JoJoJet
233b26cc17
Make the Condition trait generic (#8721)
# Objective

The `Condition` trait is only implemented for systems and system
functions that take no input. This can make it awkward to write
conditions that are intended to be used with system piping.

## Solution

Add an `In` generic to the trait. It defaults to `()`.

---

## Changelog

- Made the `Condition` trait generic over system inputs.
2023-05-31 16:49:46 +00:00
JoJoJet
5472ea4a14
Improve encapsulation for commands and add docs (#8725)
# Objective

Several of our built-in `Command` types are too public:
- `GetOrSpawn` is public, even though it only makes sense to call it
from within `Commands::get_or_spawn`.
- `Remove` and `RemoveResource` contain public `PhantomData` marker
fields.

## Solution

Remove `GetOrSpawn` and use an anonymous command. Make the marker fields
private.

---

## Migration Guide

The `Command` types `Remove` and `RemoveResource` may no longer be
constructed manually.

```rust
// Before:
commands.add(Remove::<T> {
    entity: id,
    phantom: PhantomData,
});

// After:
commands.add(Remove::<T>::new(id));

// Before:
commands.add(RemoveResource::<T> { phantom: PhantomData });

// After:
commands.add(RemoveResource::<T>::new());
```

The command type `GetOrSpawn` has been removed. It was not possible to
use this type outside of `bevy_ecs`.
2023-05-31 16:45:46 +00:00
Sélène Amanita
ca81d3e435
Document query errors (#8692)
# Objective

Add documentation to `Query` and `QueryState` errors in bevy_ecs
(`QuerySingleError`, `QueryEntityError`, `QueryComponentError`)

## Solution

- Change display message for `QueryEntityError::QueryDoesNotMatch`: this
error can also happen when the entity has a component which is filtered
out (with `Without<C>`)
- Fix wrong reference in the documentation of `Query::get_component` and
`Query::get_component_mut` from `QueryEntityError` to
`QueryComponentError`
- Complete the documentation of the three error enum variants.
- Add examples for `QueryComponentError::MissingReadAccess` and
`QueryComponentError::MissingWriteAccess`
- Add reference to `QueryState` in `QueryEntityError`'s documentation.

---

## Migration Guide

Expect `QueryEntityError::QueryDoesNotMatch`'s display message to
change? Not sure that counts.

---------

Co-authored-by: harudagondi <giogdeasis@gmail.com>
2023-05-30 14:41:14 +00:00
JoJoJet
85a918a8dd
Improve safety for the multi-threaded executor using UnsafeWorldCell (#8292)
# Objective

Fix #7833.

Safety comments in the multi-threaded executor don't really talk about
system world accesses, which makes it unclear if the code is actually
valid.

## Solution

Update the `System` trait to use `UnsafeWorldCell`. This type's API is
written in a way that makes it much easier to cleanly maintain safety
invariants. Use this type throughout the multi-threaded executor, with a
liberal use of safety comments.

---

## Migration Guide

The `System` trait now uses `UnsafeWorldCell` instead of `&World`. This
type provides a robust API for interior mutable world access.
- The method `run_unsafe` uses this type to manage world mutations
across multiple threads.
- The method `update_archetype_component_access` uses this type to
ensure that only world metadata can be used.

```rust
let mut system = IntoSystem::into_system(my_system);
system.initialize(&mut world);

// Before:
system.update_archetype_component_access(&world);
unsafe { system.run_unsafe(&world) }

// After:
system.update_archetype_component_access(world.as_unsafe_world_cell_readonly());
unsafe { system.run_unsafe(world.as_unsafe_world_cell()) }
```

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2023-05-29 15:22:10 +00:00
JoJoJet
d628ae808f
Add documentation to UnsafeWorldCell::increment_change_tick (#8697)
# Objective

This function does not have documentation.

## Solution

Copy the docs from `World::increment_change_tick`.
2023-05-28 12:46:24 +00:00
bird
bc9144bcd6
implement Deref for State<S> (#8668)
# Objective

- Allow for directly call methods on states without first calling
`state.get().my_method()`

## Solution

- Implement `Deref` for `State<S>` with `Target = S`
---
*I did not implement `DerefMut` because states hold no data and should
only be changed via `NextState::set()`*
2023-05-25 10:40:43 +00:00
JoJoJet
b4e7f0899a
Add documentation to last_change_tick (#8598)
# Objective

This method has no documentation and it's extremely unclear what it
does, or what the returned tick represents.

## Solution

Write documentation.
2023-05-19 18:24:11 +00:00
JoJoJet
1da726e046
Fix a change detection test (#8605)
# Objective

The unit test `chang_tick_wraparound` is meant to ensure that change
ticks correctly deal with wrapping by setting the world's
`last_change_tick` to `u32::MAX`. However, since systems don't use* the
value of `World::last_change_tick`, this test doesn't actually involve
any wrapping behavior.

*exclusive systems do use `World::last_change_tick`; however it gets
overwritten by the system's own last tick in `System::run`.

## Solution

Use `QueryState` instead of systems in the unit test. This approach
actually uses `World::last_change_tick`, so it properly tests that
change ticks deal with wrapping correctly.
2023-05-16 01:41:24 +00:00
François
0736195a1e
update syn, encase, glam and hexasphere (#8573)
# Objective

- Fixes #8282 
- Update `syn` to 2.0, `encase` to 0.6, `glam` to 0.24 and `hexasphere`
to 9.0


Blocked ~~on https://github.com/teoxoy/encase/pull/42~~ and ~~on
https://github.com/OptimisticPeach/hexasphere/pull/17~~

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
2023-05-16 01:24:17 +00:00
JoJoJet
1644426761
Simplify the way run conditions are stored in the schedule (#8594)
# Objective

`ScheduleGraph` currently stores run conditions in a
`Option<Vec<BoxedCondition>>`. The `Option` is unnecessary, since we can
just use an empty vector instead of `None`.
2023-05-11 17:17:15 +00:00
Ame
636f711d26
Remove a repeated phrase in UnsafeWorldCell docs (#8590)
I just found a typo while reading the docs.

# Objective

- Fix `UnsafeWorldCell` docs 

## Solution

- Remove the repeated phrase
2023-05-11 05:35:27 +00:00
JoJoJet
76fe2b40c6
Improve documentation for UnsafeWorldCell::world_mut (#8587)
# Objective

The method `UnsafeWorldCell::world_mut` is a special case, since its
safety contract is more difficult to satisfy than the other methods on
`UnsafeWorldCell`. Rewrite its documentation to be specific about when
it can and cannot be used. Provide examples and emphasize that it is
unsound to call in most cases.
2023-05-11 00:31:26 +00:00
JoJoJet
35240fe4f8
Rename UnsafeWorldCell::read_change_tick (#8588)
# Objective

The method `UnsafeWorldCell::read_change_tick` is longer than it needs
to be. `World` only has a method called this because it has two methods
for getting a change tick: one that takes `&self` and one that takes
`&mut self`. Since this distinction is not applicable to
`UnsafeWorldCell`, we should just call this method `change_tick`.

## Solution

Deprecate the current method and add a new one called `change_tick`.

---

## Changelog

- Renamed `UnsafeWorldCell::read_change_tick` to `change_tick`.

## Migration Guide

The `UnsafeWorldCell` method `read_change_tick` has been renamed to
`change_tick`.
2023-05-10 23:59:04 +00:00
Nicola Papale
d319910d36
Fix wording on DetectChanges::is_changed (#8550)
# Objective

- Closes #8472 

## Solution

- Fix wording on DetectChanges::is_changed
2023-05-05 20:33:02 +00:00
konsti219
5da8af7d37
Manually implement common traits for EventId (#8529)
# Objective

Fixes #8528

## Solution

Manually implement `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash`
for `bevy_ecs::event::EventId`. These new implementations do not rely on
the `Event` implementing the same traits allowing `EventId` to be used
in more cases.
2023-05-04 12:22:25 +00:00
Testare
a29d328fe5
Rename map_entities and map_specific_entities (#7570)
# Objective

After fixing dynamic scene to only map specific entities, we want
map_entities to default to the less error prone behavior and have the
previous behavior renamed to "map_all_entities." As this is a breaking
change, it could not be pushed out with the bug fix.

## Solution

Simple rename and refactor.

## Changelog

### Changed
- `map_entities` now accepts a list of entities to apply to, with
`map_all_entities` retaining previous behavior of applying to all
entities in the map.

## Migration Guide 

- In `bevy_ecs`, `ReflectMapEntities::map_entites` now requires an
additional `entities` parameter to specify which entities it applies to.
To keep the old behavior, use the new
`ReflectMapEntities::map_all_entities`, but consider if passing the
entities in specifically might be better for your use case to avoid
bugs.
2023-05-01 21:40:19 +00:00
Illiux
eebc92a7d4
Make scene handling of entity references robust (#7335)
# Objective

- Handle dangling entity references inside scenes
- Handle references to entities with generation > 0 inside scenes
- Fix a latent bug in `Parent`'s `MapEntities` implementation, which
would, if the parent was outside the scene, cause the scene to be loaded
into the new world with a parent reference potentially pointing to some
random entity in that new world.
- Fixes #4793 and addresses #7235 

## Solution

- DynamicScenes now identify entities with a `Entity` instead of a u32,
therefore including generation
- `World` exposes a new `reserve_generations` function that despawns an
entity and advances its generation by some extra amount.
- `MapEntities` implementations have a new `get_or_reserve` function
available that will always return an `Entity`, establishing a new
mapping to a dead entity when the entity they are called with is not in
the `EntityMap`. Subsequent calls with that same `Entity` will return
the same newly created dead entity reference, preserving equality
semantics.
- As a result, after loading a scene containing references to dead
entities (or entities otherwise outside the scene), those references
will all point to different generations on a single entity id in the new
world.

---

## Changelog

### Changed
- In serialized scenes, entities are now identified by a u64 instead of
a u32.
- In serialized scenes, components with entity references now have those
references serialize as u64s instead of structs.
### Fixed
- Scenes containing components with entity references will now
deserialize and add to a world reliably.

## Migration Guide

- `MapEntities` implementations must change from a `&EntityMap`
parameter to a `&mut EntityMapper` parameter and can no longer return a
`Result`. Finally, they should switch from calling `EntityMap::get` to
calling `EntityMapper::get_or_reserve`.

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-05-01 15:49:27 +00:00
Troels Jessen
55d6c7d56e
Added reference to ParallelCommands in the Commands doc (#8510)
# Objective

Fixes #8414

---------

Co-authored-by: Sheepyhead <trojes@tuta.io>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-05-01 15:31:33 +00:00
Wybe Westra
abf12f3b3b
Fixed several missing links in docs. (#8117)
Links in the api docs are nice. I noticed that there were several places
where structs / functions and other things were referenced in the docs,
but weren't linked. I added the links where possible / logical.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-04-23 17:28:36 +00:00
Nicola Papale
e900bd9e12
Fix 1.69 CI clippy lints (#8450)
- Fix CI by implementing changes recommended by clippy
- It uncovered a bug in a `bevy_ecs` test. Nice!
2023-04-20 16:51:21 +00:00
JoJoJet
9fd867aeba
Simplify world schedule methods (#8403)
# Objective

Methods for interacting with world schedules currently have two
variants: one that takes `impl ScheduleLabel` and one that takes `&dyn
ScheduleLabel`. Operations such as `run_schedule` or `schedule_scope`
only use the label by reference, so there is little reason to have an
owned variant of these functions.

## Solution

Decrease maintenance burden by merging the `ref` variants of these
functions with the owned variants.

---

## Changelog

- Deprecated `World::run_schedule_ref`. It is now redundant, since
`World::run_schedule` can take values by reference.

## Migration Guide

The method `World::run_schedule_ref` has been deprecated, and will be
removed in the next version of Bevy. Use `run_schedule` instead.
2023-04-19 19:48:35 +00:00
JoJoJet
fe852fd0ad
Fix boxed labels (#8436)
# Objective

Label traits such as `ScheduleLabel` currently have a major footgun: the
trait is implemented for `Box<dyn ScheduleLabel>`, but the
implementation does not function as one would expect since `Box<T>` is
considered to be a distinct type from `T`. This is because the behavior
of the `ScheduleLabel` trait is specified mainly through blanket
implementations, which prevents `Box<dyn ScheduleLabel>` from being
properly special-cased.

## Solution

Replace the blanket-implemented behavior with a series of methods
defined on `ScheduleLabel`. This allows us to fully special-case
`Box<dyn ScheduleLabel>` .

---

## Changelog

Fixed a bug where boxed label types (such as `Box<dyn ScheduleLabel>`)
behaved incorrectly when compared with concretely-typed labels.

## Migration Guide

The `ScheduleLabel` trait has been refactored to no longer depend on the
traits `std::any::Any`, `bevy_utils::DynEq`, and `bevy_utils::DynHash`.
Any manual implementations will need to implement new trait methods in
their stead.

```rust
impl ScheduleLabel for MyType {
    // Before:
    fn dyn_clone(&self) -> Box<dyn ScheduleLabel> { ... }

    // After:
    fn dyn_clone(&self) -> Box<dyn ScheduleLabel> { ... }

    fn as_dyn_eq(&self) -> &dyn DynEq {
        self
    }

    // No, `mut state: &mut` is not a typo.
    fn dyn_hash(&self, mut state: &mut dyn Hasher) {
        self.hash(&mut state);
        // Hashing the TypeId isn't strictly necessary, but it prevents collisions.
        TypeId::of::<Self>().hash(&mut state);
    }
}
```
2023-04-19 02:36:44 +00:00
Hennadii Chernyshchyk
315f3cab36
Add any_component_removed condition (#8326)
Added helper extracted from #7711. that PR contains some controversy
conditions, but this one should be good to go.

---

## Changelog

### Added

- `any_component_removed` condition.

---------

Co-authored-by: François <mockersf@gmail.com>
2023-04-18 14:18:09 +00:00
JoJoJet
ce252f8cf7
Reorganize system modules (#8419)
# Objective

Follow-up to #8377.

As the system module has been refactored, there are many types that no
longer make sense to live in the files that they do:
- The `IntoSystem` trait is in `function_system.rs`, even though this
trait is relevant to all kinds of systems. Same for the `In<T>` type.
- `PipeSystem` is now just an implementation of `CombinatorSystem`, so
`system_piping.rs` no longer needs its own file.

## Solution

- Move `IntoSystem`, `In<T>`, and system piping combinators & tests into
the top-level `mod.rs` file for `bevy_ecs::system`.
- Move `PipeSystem` into `combinator.rs`.
2023-04-17 21:10:57 +00:00
JoJoJet
b03b7b557e
Simplify system piping and make it more flexible (#8377)
# Objective

- Currently, it is not possible to call `.pipe` on a system that takes
any input other than `()`.
- The `IntoPipeSystem` trait is currently very difficult to parse due to
its use of generics.

## Solution

Remove the `IntoPipeSystem` trait, and move the `pipe` method to
`IntoSystem`.

---

## Changelog

- System piping has been made more flexible: it is now possible to call
`.pipe` on a system that takes an input.

## Migration Guide

The `IntoPipeSystem` trait has been removed, and the `pipe` method has
been moved to the `IntoSystem` trait.

```rust

// Before:
use bevy_ecs::system::IntoPipeSystem;
schedule.add_systems(first.pipe(second));

// After:
use bevy_ecs::system::IntoSystem;
schedule.add_systems(first.pipe(second));
```
2023-04-17 16:08:32 +00:00
NiseVoid
65292fd559
Improve warning for Send resources marked as non_send (#8000)
# Objective

- Fixes unclear warning when `insert_non_send_resource` is called on a
Send resource

## Solution

- Add a message to the asssert statement that checks this

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2023-04-17 16:06:00 +00:00
JoJoJet
328347f44c
Add a missing safety invariant to System::run_unsafe (#7778)
# Objective

The implementation of `System::run_unsafe` for `FunctionSystem` requires
that the world is the same one used to initialize the system. However,
the `System` trait has no requirements that the world actually matches,
which makes this implementation unsound.

This was previously mentioned in
https://github.com/bevyengine/bevy/pull/7605#issuecomment-1426491871

Fixes part of #7833.

## Solution

Add the safety invariant that
`System::update_archetype_component_access` must be called prior to
`System::run_unsafe`. Since
`FunctionSystem::update_archetype_component_access` properly validates
the world, this ensures that `run_unsafe` is not called with a
mismatched world.

Most exclusive systems are not required to be run on the same world that
they are initialized with, so this is not a concern for them. Systems
formed by combining an exclusive system with a regular system *do*
require the world to match, however the validation is done inside of
`System::run` when needed.
2023-04-17 15:20:42 +00:00
Vladyslav Batyrenko
71fccb2897
Improve or-with disjoint checks (#7085)
# Objective

This PR attempts to improve query compatibility checks in scenarios
involving `Or` filters.

Currently, for the following two disjoint queries, Bevy will throw a
panic:

```
fn sys(_: Query<&mut C, Or<(With<A>, With<B>)>>, _: Query<&mut C, (Without<A>, Without<B>)>) {}
``` 

This PR addresses this particular scenario.

## Solution

`FilteredAccess::with` now stores a vector of `AccessFilters`
(representing a pair of `with` and `without` bitsets), where each member
represents an `Or` "variant".
Filters like `(With<A>, Or<(With<B>, Without<C>)>` are expected to be
expanded into `A * B + A * !C`.

When calculating whether queries are compatible, every `AccessFilters`
of a query is tested for incompatibility with every `AccessFilters` of
another query.

---

## Changelog

- Improved system and query data access compatibility checks in
scenarios involving `Or` filters

---------

Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-04-17 15:16:58 +00:00
JoJoJet
0174d632a5
Add a scope API for world schedules (#8387)
# Objective

If you want to execute a schedule on the world using arbitrarily complex
behavior, you currently need to use "hokey-pokey strats": remove the
schedule from the world, do your thing, and add it back to the world.
Not only is this cumbersome, it's potentially error-prone as one might
forget to re-insert the schedule.

## Solution

Add the `World::{try}schedule_scope{ref}` family of functions, which is
a convenient abstraction over hokey pokey strats. This method
essentially works the same way as `World::resource_scope`.

### Example

```rust
// Run the schedule five times.
world.schedule_scope(MySchedule, |world, schedule| {
    for _ in 0..5 {
        schedule.run(world);
    }
});
```

---

## Changelog

Added the `World::schedule_scope` family of methods, which provide a way
to get mutable access to a world and one of its schedules at the same
time.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2023-04-16 05:09:33 +00:00
JoJoJet
c37a53d52d
Add a regression test for change detection between piped systems (#8368)
# Objective

The behavior of change detection within `PipeSystem` is very tricky and
subtle, and is not currently covered by any of our tests as far as I'm
aware.
2023-04-13 17:59:29 +00:00
James Liu
2ec38d1467
Inline more ECS functions (#8083)
# Objective
Upon closer inspection, there are a few functions in the ECS that are
not being inlined, even with the highest optimizations and LTO enabled:

- Almost all
[WorldQuery::init_fetch](9fd5f20e25/results/query_get.s (L57))
calls. Affects `Query::get` calls in hot loops. In particular, the
`WorldQuery` implementation for `()` is used *everywhere* as the default
filter and is effectively a no-op.
-
[Entities::get](9fd5f20e25/results/query_get.s (L39)).
Affects `Query::get`, `World::get`, and any component insertion or
removal.
-
[Entities::set](9fd5f20e25/results/entity_remove.s (L2487)).
Affects any component insertion or removal.
-
[Tick::new](9fd5f20e25/results/entity_insert.s (L1368)).
I've only seen this in component insertion and spawning.
 - ArchetypeRow::new
 - BlobVec::set_len

Almost all of these have trivial or even empty implementations or have
significant opportunity to be optimized into surrounding code when
inlined with LTO enabled.

## Solution
Inline them
2023-04-12 19:52:06 +00:00
JoJoJet
f3c7ccefc6
Fix panics and docs when using World schedules (#8364)
# Objective

The method `World::try_run_schedule` currently panics if the `Schedules`
resource does not exist, but it should just return an `Err`. Similarly,
`World::add_schedule` panics unnecessarily if the resource does not
exist.

Also, the documentation for `World::add_schedule` is completely wrong.

## Solution

When the `Schedules` resource does not exist, we now treat it the same
as if it did exist but was empty. When calling `add_schedule`, we
initialize it if it does not exist.
2023-04-12 19:29:08 +00:00
Jonah Henriksson
55e9ab7c92
Cleaned up panic messages (#8219)
# Objective

Fixes #8215 and #8152. When systems panic, it causes the main thread to
panic as well, which clutters the output.

## Solution

Resolves the panic in the multi-threaded scheduler. Also adds an extra
message that tells the user the system that panicked.

Using the example from the issue, here is what the messages now look
like:

```rust
use bevy::prelude::*;

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

fn panicking_system() {
    panic!("oooh scary");
}
```
### Before
```
   Compiling bevy_test v0.1.0 (E:\Projects\Rust\bevy_test)
    Finished dev [unoptimized + debuginfo] target(s) in 2m 58s
     Running `target\debug\bevy_test.exe`
2023-03-30T22:19:09.234932Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19044", cpu: "AMD Ryzen 5 2600 Six-Core Processor", core_count: "6", memory: "15.9 GiB" }
thread 'Compute Task Pool (5)' panicked at 'oooh scary', src\main.rs:11:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'Compute Task Pool (5)' panicked at 'A system has panicked so the executor cannot continue.: RecvError', E:\Projects\Rust\bevy\crates\bevy_ecs\src\schedule\executor\multi_threaded.rs:194:60
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', E:\Projects\Rust\bevy\crates\bevy_tasks\src\task_pool.rs:376:49
error: process didn't exit successfully: `target\debug\bevy_test.exe` (exit code: 101)
```
### After
```
   Compiling bevy_test v0.1.0 (E:\Projects\Rust\bevy_test)
    Finished dev [unoptimized + debuginfo] target(s) in 2.39s
     Running `target\debug\bevy_test.exe`
2023-03-30T22:11:24.748513Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19044", cpu: "AMD Ryzen 5 2600 Six-Core Processor", core_count: "6", memory: "15.9 GiB" }
thread 'Compute Task Pool (5)' panicked at 'oooh scary', src\main.rs:11:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_test::panicking_system`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
error: process didn't exit successfully: `target\debug\bevy_test.exe` (exit code: 101)
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-04-12 18:27:28 +00:00
JoJoJet
7ec89004dd
Only trigger state transitons if next_state != old_state (#8359)
# Objective

Fix #8191.

Currently, a state transition will be triggered whenever the `NextState`
resource has a value, even if that "transition" is to the same state as
the previous one. This caused surprising/meaningless behavior, such as
the existence of an `OnTransition { from: A, to: A }` schedule.

## Solution

State transition schedules now only run if the new state is not equal to
the old state. Change detection works the same way, only being triggered
when the states compare not equal.

---

## Changelog

- State transition schedules are no longer run when transitioning to and
from the same state.

## Migration Guide

State transitions are now only triggered when the exited and entered
state differ. This means that if the world is currently in state `A`,
the `OnEnter(A)` schedule (or `OnExit`) will no longer be run if you
queue up a state transition to the same state `A`.
2023-04-12 17:07:13 +00:00
James Liu
d623731e2c
Move event traces to detailed_trace! (#7732)
# Objective
Noticed while writing #7728 that we are using `trace!` logs in our event
functions. This has shown to have significant overhead, even trace level
logs are disabled globally, as seen in #7639.

## Solution
Use the `detailed_trace!` macro introduced in #7639. Also removed the
`event_trace` function that was only used in one location.

---

## Changelog
Changed: Event trace logs are now feature gated behind the
`detailed-trace` feature.
2023-04-11 03:37:58 +00:00
Ashy
0d971a63e4
Added documentation to the fields within derived read-only types (#8334)
Fixes #8333

# Objective

Fixes issue which causes failure to compile if using
`#![deny(missing_docs)]`.

## Solution

Added some very basic commenting to the generated read-only fields.
honestly I feel this to be up for debate since the comments are very
basic and give very little useful information but the purpose of this PR
is to fix the issue at hand.

---

## Changelog

Added comments to the derive macro and the projects now successfully
compile.

---------

Co-authored-by: lupan <kallll5@hotmail.com>
2023-04-09 14:37:34 +00:00
Mikkel Rasmussen
e9312254d8
Non-breaking change* from UK spellings to US (#8291)
Fixes issue mentioned in PR #8285.

_Note: By mistake, this is currently dependent on #8285_
# Objective

Ensure consistency in the spelling of the documentation.

Exceptions:
`crates/bevy_mikktspace/src/generated.rs` - Has not been changed from
licence to license as it is part of a licensing agreement.

Maybe for further consistency,
https://github.com/bevyengine/bevy-website should also be given a look.

## Solution

### Changed the spelling of the current words (UK/CN/AU -> US) :
cancelled -> canceled (Breaking API changes in #8285)
behaviour -> behavior (Breaking API changes in #8285)
neighbour -> neighbor
grey -> gray
recognise -> recognize
centre -> center
metres -> meters
colour -> color

### ~~Update [`engine_style_guide.md`]~~ Moved to #8324 

---

## Changelog

Changed UK spellings in documentation to US

## Migration Guide

Non-breaking changes*

\* If merged after #8285
2023-04-08 16:22:46 +00:00
JoJoJet
3ead10a3e0
Suppress the clippy::type_complexity lint (#8313)
# Objective

The clippy lint `type_complexity` is known not to play well with bevy.
It frequently triggers when writing complex queries, and taking the
lint's advice of using a type alias almost always just obfuscates the
code with no benefit. Because of this, this lint is currently ignored in
CI, but unfortunately it still shows up when viewing bevy code in an
IDE.

As someone who's made a fair amount of pull requests to this repo, I
will say that this issue has been a consistent thorn in my side. Since
bevy code is filled with spurious, ignorable warnings, it can be very
difficult to spot the *real* warnings that must be fixed -- most of the
time I just ignore all warnings, only to later find out that one of them
was real after I'm done when CI runs.

## Solution

Suppress this lint in all bevy crates. This was previously attempted in
#7050, but the review process ended up making it more complicated than
it needs to be and landed on a subpar solution.

The discussion in https://github.com/rust-lang/rust-clippy/pull/10571
explores some better long-term solutions to this problem. Since there is
no timeline on when these solutions may land, we should resolve this
issue in the meantime by locally suppressing these lints.

### Unresolved issues

Currently, these lints are not suppressed in our examples, since that
would require suppressing the lint in every single source file. They are
still ignored in CI.
2023-04-06 21:27:36 +00:00
Aceeri
ed50c8b4d9
Make state private and only accessible through getter for State resource (#8009)
# Objective
State requires a kind of awkward `state.0` to get the current state and
exposes the field directly to manipulation.

## Solution
Make it accessible through a getter method as well as privatize the
field to make sure false assumptions about setting the state aren't
made.

## Migration Guide
- Use `State::get` instead of accessing the tuple field directly.
2023-04-04 01:25:54 +00:00
张林伟
5c7abb0579
Remove OnUpdate system set (#8260)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/8239.

## Solution

- Replace `OnUpdate` with `run_if(in_state(xxx))`.

---

## Migration Guide

- Replace `OnUpdate` with `run_if(in_state(xxx))`.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-04-04 00:49:41 +00:00
JoJoJet
b423e6ee15
Extend the WorldQuery macro to tuple structs (#8119)
# Objective

The `#[derive(WorldQuery)]` macro currently only supports structs with
named fields.

Same motivation as #6957. Remove sharp edges from the derive macro, make
it just work more often.

## Solution

Support tuple structs.

---

## Changelog

+ Added support for tuple structs to the `#[derive(WorldQuery)]` macro.
2023-04-04 00:49:03 +00:00
JoJoJet
086db6d22f
Update increment_change_tick to return a strongly-typed Tick (#8295)
# Objective

While migrating the engine to use the `Tick` type in #7905, I forgot to
update `UnsafeWorldCell::increment_change_tick`.

## Solution

Update the function.

---

## Changelog

- The function `UnsafeWorldCell::increment_change_tick` is now
strongly-typed, returning a value of type `Tick` instead of a raw `u32`.

## Migration Guide

The function `UnsafeWorldCell::increment_change_tick` is now
strongly-typed, returning a value of type `Tick` instead of a raw `u32`.
2023-04-03 17:42:27 +00:00
JoJoJet
3442a13d2c
Use UnsafeWorldCell to increase code quality for SystemParam (#8174)
# Objective

The type `&World` is currently in an awkward place, since it has two
meanings:
1. Read-only access to the entire world.
2. Interior mutable access to the world; immutable and/or mutable access
to certain portions of world data.

This makes `&World` difficult to reason about, and surprising to see in
function signatures if one does not know about the interior mutable
property.

The type `UnsafeWorldCell` was added in #6404, which is meant to
alleviate this confusion by adding a dedicated type for interior mutable
world access. However, much of the engine still treats `&World` as an
interior mutable-ish type. One of those places is `SystemParam`.

## Solution

Modify `SystemParam::get_param` to accept `UnsafeWorldCell` instead of
`&World`. Simplify the safety invariants, since the `UnsafeWorldCell`
type encapsulates the concept of constrained world access.

---

## Changelog

`SystemParam::get_param` now accepts an `UnsafeWorldCell` instead of
`&World`. This type provides a high-level API for unsafe interior
mutable world access.

## Migration Guide

For manual implementers of `SystemParam`: the function `get_item` now
takes `UnsafeWorldCell` instead of `&World`. To access world data, use:

* `.get_entity()`, which returns an `UnsafeEntityCell` which can be used
to access component data.
* `get_resource()` and its variants, to access resource data.
2023-04-01 15:45:07 +00:00
JoJoJet
ae39b07d26
Replace some unsafe system executor code with safe code (#8274)
# Objective

The function `SyncUnsafeCell::from_mut` returns `&SyncUnsafeCell<T>`,
even though it could return `&mut SyncUnsafeCell<T>`. This means it is
not possible to call `get_mut` on the returned value, so you need to use
unsafe code to get exclusive access back.

## Solution

Return `&mut Self` instead of `&Self` in `SyncUnsafeCell::from_mut`.
This is consistent with my proposal for `UnsafeCell::from_mut`:
https://github.com/rust-lang/libs-team/issues/198.

Replace an unsafe pointer dereference with a safe call to `get_mut`.

---

## Changelog

+ The function `bevy_utils::SyncUnsafeCell::get_mut` now returns a value
of type `&mut SyncUnsafeCell<T>`. Previously, this returned an immutable
reference.

## Migration Guide

The function `bevy_utils::SyncUnsafeCell::get_mut` now returns a value
of type `&mut SyncUnsafeCell<T>`. Previously, this returned an immutable
reference.
2023-03-31 21:56:49 +00:00
JoJoJet
711efed018
Fix inaccurate documentation on `QueryState::for_each_unchecked (#8277)
# Objective

The documentation on `QueryState::for_each_unchecked` incorrectly says
that it can only be used with read-only queries.

## Solution

Remove the inaccurate sentence.
2023-03-31 16:54:36 +00:00
JoJoJet
a954f3e150
Remove #[system_param(ignore)] and #[world_query(ignore)] (#8265)
# Objective

Follow-up to #8030.

Now that `SystemParam` and `WorldQuery` are implemented for
`PhantomData`, the `ignore` attributes are now unnecessary.

---

## Changelog

- Removed the attributes `#[system_param(ignore)]` and
`#[world_query(ignore)]`.

## Migration Guide

The attributes `#[system_param(ignore)]` and `#[world_query]` ignore
have been removed. If you were using either of these with `PhantomData`
fields, you can simply remove the attribute:

```rust
#[derive(SystemParam)]
struct MyParam<'w, 's, Marker> {
    ...
    // Before:
    #[system_param(ignore)
    _marker: PhantomData<Marker>,

    // After:
    _marker: PhantomData<Marker>,
}
#[derive(WorldQuery)]
struct MyQuery<Marker> {
    ...
    // Before:
    #[world_query(ignore)
    _marker: PhantomData<Marker>,

    // After:
    _marker: PhantomData<Marker>,
}
```

If you were using this for another type that implements `Default`,
consider wrapping that type in `Local<>` (this only works for
`SystemParam`):

```rust
#[derive(SystemParam)]
struct MyParam<'w, 's> {
    // Before:
    #[system_param(ignore)]
    value: MyDefaultType, // This will be initialized using `Default` each time `MyParam` is created.

    // After:
    value: Local<MyDefaultType>, // This will be initialized using `Default` the first time `MyParam` is created.
}
```

If you are implementing either trait and need to preserve the exact
behavior of the old `ignore` attributes, consider manually implementing
`SystemParam` or `WorldQuery` for a wrapper struct that uses the
`Default` trait:

```rust
// Before:

#[derive(WorldQuery)
struct MyQuery {
   #[world_query(ignore)]
    str: String,
}

// After:

#[derive(WorldQuery)
struct MyQuery {
    str: DefaultQuery<String>,
}

pub struct DefaultQuery<T: Default>(pub T);

unsafe impl<T: Default> WorldQuery for DefaultQuery<T> {
    type Item<'w> = Self;
    ...
    unsafe fn fetch<'w>(...) -> Self::Item<'w> {
        Self(T::default())
    }
}
```
2023-03-30 23:02:25 +00:00