Commit graph

7728 commits

Author SHA1 Message Date
Gino Valente
c3b91562d1 Add ArgCount 2024-12-08 15:21:23 -07:00
Gino Valente
f93aadd0dd Small optimization for ArgumentSignature from ArgList 2024-12-08 15:17:47 -07:00
Gino Valente
a6121d62f9 Improve function info representation
Replaced FunctionInfoType with FunctionInfo and added
SignatureInfo
2024-12-08 15:17:46 -07:00
Gino Valente
0a50c2a0cb Add and clean up internal representation 2024-12-08 15:14:14 -07:00
Gino Valente
45803de41b Changed benchmark names
Added the `simple_` qualifier
2024-12-08 15:13:30 -07:00
Gino Valente
0eb2398a26 Updated function_reflection example 2024-12-08 15:13:30 -07:00
Gino Valente
e5f2085ddf Added PrettyPrintFunctionInfo
Used to help reduce code duplication for overloaded functions
and to give users the option to pretty-print FunctionInfo
2024-12-08 15:13:29 -07:00
Gino Valente
c2a18d593f Added module-level docs for function overloading 2024-12-08 15:12:50 -07:00
Gino Valente
f4d8c2f16a Added a few more FunctionMap optimizations
Mainly usage of HashMap::insert_unique_unchecked
2024-12-08 15:12:50 -07:00
Gino Valente
841d1bc717 Reverted usage of NoOpHash
Turns out that NoOpHash works by only using the last u64 hash,
making collisions very likely when used with ArgumentSignature
2024-12-08 15:12:50 -07:00
Gino Valente
7d526ad2ba Improved docs for FunctionMap 2024-12-08 15:12:50 -07:00
Gino Valente
d662cb1e9e Added arg_count method 2024-12-08 15:12:49 -07:00
Gino Valente
f79672def3 Added is_overloaded method 2024-12-08 15:09:29 -07:00
Gino Valente
dbd3dc1e9b Switched to NoOpHash in FunctionMap
Since ArgumentSignature is just a wrapper around Box<[Type]>,
it should already contain a "high-quality hash"
2024-12-08 15:09:29 -07:00
Gino Valente
bd62310634 Added complex function to benchmark 2024-12-08 15:09:29 -07:00
Gino Valente
5923cfa0ec Optimized FunctionMap 2024-12-08 15:09:28 -07:00
Gino Valente
b3b6671d9c Added basic benchmarks for overloaded functions 2024-12-08 15:08:40 -07:00
Gino Valente
77ae7cf822 Added non-panicking method for adding overloads 2024-12-08 15:08:40 -07:00
Gino Valente
38b3cbf5c5 Simplified FunctionMap 2024-12-08 15:08:39 -07:00
Gino Valente
8ce37d975a Added reflection function overloading 2024-12-08 15:05:36 -07:00
Gino Valente
ba987ef60d Added Signature and ArgumentSignature types 2024-12-08 14:54:18 -07:00
Gino Valente
85482b393a Added Arg::is
Allows for manually defining basic generic function reflection
2024-12-08 14:54:18 -07:00
Gino Valente
14cc62c9c7 Added FunctionInfoType
This will be a foundational piece to enabling overloaded functions.
2024-12-08 14:54:17 -07:00
Emad Ali
1d3950a82a
Replace deperacted bundle mention in the comment (#16699)
Clean up left over comments after changes were made from bundles to
required components
2024-12-08 21:24:09 +00:00
homersimpsons
a6b5f80715
⬆️ Upgrade typos and its configuration (#16712)
# Objective

Fixes #16610, related to #16702

## Solution

Upgrade typos and its configuration

## Testing

- Did you test these changes? If so, how? No
- Are there any parts that need more testing? No
- How can other people (reviewers) test your changes? Is there anything
specific they need to know? No
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test? Not applicable
2024-12-08 17:25:10 +00:00
poopy
4aed2ca74c
Add World::try_resource_scope (#16707)
# Objective

Fixes #16706

## Solution 

- Added new method: `try_resource_scope` which returns `None` if the
requested resource doesn't exist.
- Changed the `resource_scope` test to use `try_resource_scope` as well
to test for the `None` case.

---

## Showcase

```rust
world.try_resource_scope::<MyResource, _>(|world, mut my_resource| {
    // do something with the resource if it exists
});
```
2024-12-08 15:40:09 +00:00
homersimpsons
0707c0717b
✏️ Fix typos across bevy (#16702)
# Objective

Fixes typos in bevy project, following suggestion in
https://github.com/bevyengine/bevy-website/pull/1912#pullrequestreview-2483499337

## Solution

I used https://github.com/crate-ci/typos to find them.

I included only the ones that feel undebatable too me, but I am not in
game engine so maybe some terms are expected.

I left out the following typos:
- `reparametrize` => `reparameterize`: There are a lot of occurences, I
believe this was expected
- `semicircles` => `hemicircles`: 2 occurences, may mean something
specific in geometry
- `invertation` => `inversion`: may mean something specific
- `unparented` => `parentless`: may mean something specific
- `metalness` => `metallicity`: may mean something specific

## Testing

- Did you test these changes? If so, how? I did not test the changes,
most changes are related to raw text. I expect the others to be tested
by the CI.
- Are there any parts that need more testing? I do not think
- How can other people (reviewers) test your changes? Is there anything
specific they need to know? To me there is nothing to test
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

---

## Migration Guide

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

(kept in case I include the `reparameterize` change here)

- If this PR is a breaking change (relative to the last release of
Bevy), describe how a user might need to migrate their code to support
these changes
- Simply adding new functionality is not a breaking change.
- Fixing behavior that was definitely a bug, rather than a questionable
design choice is not a breaking change.

## Questions

- [x] Should I include the above typos? No
(https://github.com/bevyengine/bevy/pull/16702#issuecomment-2525271152)
- [ ] Should I add `typos` to the CI? (I will check how to configure it
properly)

This project looks awesome, I really enjoy reading the progress made,
thanks to everyone involved.
2024-12-08 01:18:39 +00:00
Emad Ali
48fb4aa6d5
Update breakout to use Required Components (#16577)
# Objective

This PR update breakout to use the new 0.15 Required Component feature
instead of the Bundle.
Add more information in the comment about where to find more info about
Required Components.

## Solution

Replace `#[derive(Bundle)]` with a new Wall component and `#[require()]`
Macro to include the other components.

## Testing

Tested with `cargo test` as well tested the game manually with `cargo
run --example breakout` It looks to me that it works like it used to
before the changes. Tested on Arch Linux, Wayland

---------

Co-authored-by: Arnav Mummineni <45217840+RCoder01@users.noreply.github.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-12-07 00:21:26 +00:00
Patrick Walton
f5de3f08fb
Use multidraw for opaque meshes when GPU culling is in use. (#16427)
This commit adds support for *multidraw*, which is a feature that allows
multiple meshes to be drawn in a single drawcall. `wgpu` currently
implements multidraw on Vulkan, so this feature is only enabled there.
Multiple meshes can be drawn at once if they're in the same vertex and
index buffers and are otherwise placed in the same bin. (Thus, for
example, at present the materials and textures must be identical, but
see #16368.) Multidraw is a significant performance improvement during
the draw phase because it reduces the number of rebindings, as well as
the number of drawcalls.

This feature is currently only enabled when GPU culling is used: i.e.
when `GpuCulling` is present on a camera. Therefore, if you run for
example `scene_viewer`, you will not see any performance improvements,
because `scene_viewer` doesn't add the `GpuCulling` component to its
camera.

Additionally, the multidraw feature is only implemented for opaque 3D
meshes and not for shadows or 2D meshes. I plan to make GPU culling the
default and to extend the feature to shadows in the future. Also, in the
future I suspect that polyfilling multidraw on APIs that don't support
it will be fruitful, as even without driver-level support use of
multidraw allows us to avoid expensive `wgpu` rebindings.
2024-12-06 17:22:03 +00:00
Joona Aalto
4d6b02af89
Fix mehses -> meshes typo (#16688)
# Objective

The "mehses" typo introduced in a review comment
[here](https://github.com/bevyengine/bevy/pull/16657#discussion_r1870834999)
hurts my soul, it was merged right as I was about to comment about it :(

## Solution

Fix it :D

(also, why didn't the CI typo checker catch this?)
2024-12-06 17:09:10 +00:00
Zachary Harrold
a6adced9ed
Deny derive_more error feature and replace it with thiserror (#16684)
# Objective

- Remove `derive_more`'s error derivation and replace it with
`thiserror`

## Solution

- Added `derive_more`'s `error` feature to `deny.toml` to prevent it
sneaking back in.
- Reverted to `thiserror` error derivation

## Notes

Merge conflicts were too numerous to revert the individual changes, so
this reversion was done manually. Please scrutinise carefully during
review.
2024-12-06 17:03:55 +00:00
JaySpruce
d0afdc6b45
Move clone_entity commands to EntityCommands (#16672)
## Objective

I was resolving a conflict between #16132 and my PR #15929 and thought
the `clone_entity` commands made more sense in `EntityCommands`.

## Solution

Moved `Commands::clone_entity` to `EntityCommands::clone`, moved
`Commands::clone_entity_with` to `EntityCommands::clone_with`.

## Testing

Ran the two tests that used the old methods.

## Showcase

```
// Create a new entity and keep its EntityCommands.
let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));

// Create a clone of the first entity
let mut entity_clone = entity.clone();
```

The only potential downside is that the method name is now the same as
the one from the `Clone` trait. `EntityCommands` doesn't implement
`Clone` though, so there's no actual conflict.

Maybe I'm biased because this'll work better with my PR, but I think the
UX is nicer regardless.
2024-12-06 15:54:35 +00:00
Jakob Hellermann
10e3cc72ad
add missing type registration for Monitor (#16685)
# Objective


![image](https://github.com/user-attachments/assets/4b8d6a2c-86ed-4353-8133-0e0efdb3a697)
make `Monitor` reflectable by default

## Solution

- register type
2024-12-06 15:20:10 +00:00
Rob Parrett
5b1f0b1ef5
Fix error in volumetric fog shader (#16677)
# Objective

Volumetric fog was broken by #13746.

Looks like this particular shader just got missed. I don't see any other
instances of `unpack_offset_and_counts` in the codebase.

```
2024-12-06T03:18:42.297494Z ERROR bevy_render::render_resource::pipeline_cache: failed to process shader:
error: no definition in scope for identifier: 'bevy_pbr::clustered_forward::unpack_offset_and_counts'
    ┌─ crates/bevy_pbr/src/volumetric_fog/volumetric_fog.wgsl:312:29
    │
312 │     let offset_and_counts = bevy_pbr::clustered_forward::unpack_offset_and_counts(cluster_index);
    │                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown identifier
    │
    = no definition in scope for identifier: 'bevy_pbr::clustered_forward::unpack_offset_and_counts'
```

## Solution

Use `unpack_clusterable_object_index_ranges` to get the indices for
point/spot lights.

## Testing

`cargo run --example volumetric_fog`
`cargo run --example fog_volumes`
`cargo run --example scrolling_fog`
2024-12-06 08:49:18 +00:00
MichiRecRoom
24c3bd5f00
Skip all jobs on the Weekly beta compile test workflow when running on a fork (#16674)
# Objective
The weekly beta compile test workflow can be useful to people who have
forked the repository.

However, there are a few small issues with how this workflow is
currently set up:
* Scheduled workflows run on the base/default branch, with no way
(currently) to change this. On forks, the base/default branch is usually
kept in sync with the main Bevy repository, meaning that running this
workflow on forks would just be a waste of resources. (See
[here](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule)
- "Scheduled workflows will only run on the default branch.")
* Even if there was a way to change the branch that a scheduled workflow
runs on, forks default to not having an issue tracker.
* Even in the event that a fork's issue tracker is enabled, most users
probably don't want to receive automated issues in the event of a
compilation failure.

Because of these reasons, this workflow is irrelevant for 99% of forks.

## Solution
We now skip all jobs on the `Weekly beta compile test` workflow, if we
detect we're running this workflow on a fork.

## Testing
Testing? Who needs testing? (Seriously though, I made sure the syntax is
correct.)
2024-12-06 08:07:16 +00:00
Zachary Harrold
72f096c91e
Add no_std support to bevy_tasks (#15464)
# Objective

- Contributes to #15460

## Solution

- Added the following features:
  - `std` (default)
  - `async_executor` (default)
  - `edge_executor`
  - `critical-section`
  - `portable-atomic`
- Added [`edge-executor`](https://crates.io/crates/edge-executor) as a
`no_std` alternative to `async-executor`.
- Updated the `single_threaded_task_pool` to work in `no_std`
environments by gating its reliance on `thread_local`.

## Testing

- Added to `compile-check-no-std` CI command

## Notes

- In previous iterations of this PR, a custom `async-executor`
alternative was vendored in. This raised concerns around maintenance and
testing. In this iteration, an existing version of that same vendoring
is now used, but _only_ in `no_std` contexts. For existing `std`
contexts, the original `async-executor` is used.
- Due to the way statics work, certain `TaskPool` operations have added
restrictions around `Send`/`Sync` in `no_std`. This is because there
isn't a straightforward way to create a thread-local in `no_std`. If
these added constraints pose an issue we can revisit this at a later
date.
- If a user enables both the `async_executor` and `edge_executor`
features, we will default to using `async-executor`. Since enabling
`async_executor` requires `std`, we can safely assume we are in an `std`
context and use the original library.

---------

Co-authored-by: Mike <2180432+hymm@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-12-06 02:14:54 +00:00
Talin
bc572cd270
bevy_input_focus improvements (follow-up PR) (#16665)
This adds a few minor items which were left out of the previous PR:

- Added synchronization from bevy_input_focus to bevy_a11y.
- Initialize InputFocusVisible resource.
- Make `input_focus` available from `bevy` module.

I've tested this using VoiceOver on Mac OS. It works, but it needs
considerable polish.
2024-12-06 01:16:52 +00:00
Nuutti Kotivuori
912da04699
Run observers before hooks for on_replace and on_remove (#16499)
# Objective

- Fixes #16498 

## Solution

- Trivially swaps ordering of hooks and observers for all call sites
where they are triggered for `on_replace` or `on_remove`

## Testing

- Just CI

---

## Migration Guide

The order of hooks and observers for `on_replace` and `on_remove` has
been swapped. Observers are now run before hooks. This is a more natural
ordering where the removal ordering is inverted compared to the
insertion ordering.
2024-12-06 00:24:27 +00:00
Miles Silberling-Cook
0070514f54
Fallible systems (#16589)
# Objective

Error handling in bevy is hard. See for reference
https://github.com/bevyengine/bevy/issues/11562,
https://github.com/bevyengine/bevy/issues/10874 and
https://github.com/bevyengine/bevy/issues/12660. The goal of this PR is
to make it better, by allowing users to optionally return `Result` from
systems as outlined by Cart in
<https://github.com/bevyengine/bevy/issues/14275#issuecomment-2223708314>.

## Solution

This PR introduces a new `ScheuleSystem` type to represent systems that
can be added to schedules. Instances of this type contain either an
infallible `BoxedSystem<(), ()>` or a fallible `BoxedSystem<(),
Result>`. `ScheuleSystem` implements `System<In = (), Out = Result>` and
replaces all uses of `BoxedSystem` in schedules. The async executor now
receives a result after executing a system, which for infallible systems
is always `Ok(())`. Currently it ignores this result, but more useful
error handling could also be implemented.

Aliases for `Error` and `Result` have been added to the `bevy_ecs`
prelude, as well as const `OK` which new users may find more friendly
than `Ok(())`.

## Testing

- Currently there are not actual semantics changes that really require
new tests, but I added a basic one just to make sure we don't break
stuff in the future.
- The behavior of existing systems is totally unchanged, including
logging.
- All of the existing systems tests pass, and I have not noticed
anything strange while playing with the examples

## Showcase

The following minimal example prints "hello world" once, then completes.

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

fn main() {
    App::new().add_systems(Update, hello_world_system).run();
}

fn hello_world_system() -> Result {
    println!("hello world");
    Err("string")?;
    println!("goodbye world");
    OK
}
```

## Migration Guide

This change should be pretty much non-breaking, except for users who
have implemented their own custom executors. Those users should use
`ScheduleSystem` in place of `BoxedSystem<(), ()>` and import the
`System` trait where needed. They can choose to do whatever they wish
with the result.

## Current Work

+ [x] Fix tests & doc comments
+ [x] Write more tests
+ [x] Add examples
+ [X] Draft release notes

## Draft Release Notes

As of this release, systems can now return results.

First a bit of background: Bevy has hisotrically expected systems to
return the empty type `()`. While this makes sense in the context of the
ecs, it's at odds with how error handling is typically done in rust:
returning `Result::Error` to indicate failure, and using the
short-circuiting `?` operator to propagate that error up the call stack
to where it can be properly handled. Users of functional languages will
tell you this is called "monadic error handling".

Not being able to return `Results` from systems left bevy users with a
quandry. They could add custom error handling logic to every system, or
manually pipe every system into an error handler, or perhaps sidestep
the issue with some combination of fallible assignents, logging, macros,
and early returns. Often, users would just litter their systems with
unwraps and possible panics.

While any one of these approaches might be fine for a particular user,
each of them has their own drawbacks, and none makes good use of the
language. Serious issues could also arrise when two different crates
used by the same project made different choices about error handling.

Now, by returning results, systems can defer error handling to the
application itself. It looks like this:

```rust
// Previous, handling internally
app.add_systems(my_system)
fn my_system(window: Query<&Window>) {
   let Ok(window) = query.get_single() else {
       return;
   };
   // ... do something to the window here
}

// Previous, handling externally
app.add_systems(my_system.pipe(my_error_handler))
fn my_system(window: Query<&Window>) -> Result<(), impl Error> {
   let window = query.get_single()?;
   // ... do something to the window here
   Ok(())
}

// Previous, panicking
app.add_systems(my_system)
fn my_system(window: Query<&Window>) {
   let window = query.single();
   // ... do something to the window here
}

// Now 
app.add_systems(my_system)
fn my_system(window: Query<&Window>) -> Result {
    let window = query.get_single()?;
    // ... do something to the window here
    Ok(())
}
```

There are currently some limitations. Systems must either return `()` or
`Result<(), Box<dyn Error + Send + Sync + 'static>>`, with no
in-between. Results are also ignored by default, and though implementing
a custom handler is possible, it involves writing your own custom ecs
executor (which is *not* recomended).

Systems should return errors when they cannot perform their normal
behavior. In turn, errors returned to the executor while running the
schedule will (eventually) be treated as unexpected. Users and library
authors should prefer to return errors for anything that disrupts the
normal expected behavior of a system, and should only handle expected
cases internally.

We have big plans for improving error handling further:
+ Allowing users to change the error handling logic of the default
executors.
+ Adding source tracking and optional backtraces to errors.
+ Possibly adding tracing-levels (Error/Warn/Info/Debug/Trace) to
errors.
+ Generally making the default error logging more helpful and
inteligent.
+ Adding monadic system combininators for fallible systems.
+ Possibly removing all panicking variants from our api.

---------

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-12-05 22:29:06 +00:00
Robin Gloster
e763b71591
picking: disable raycast backface culling for Mesh2d (#16657)
# Objective

- This fixes raycast picking with lyon
- reverse winding of 2D meshes currently results in them being rendered
but not pickable as the raycast passes through the backface and would
only hit "from below"

## Solution

- Disables backface culling for Mesh2d

## Testing

- Tested picking with bevy_prototype_lyon
- Could probably use testing with Mesh3d (should not be affected) and
SimplifiedMesh (no experience with that, could have the same issue if
used for 2D?)

---------

Co-authored-by: Aevyrie <aevyrie@gmail.com>
2024-12-05 21:22:29 +00:00
Patrick Walton
d3241c4f8d
Fix the texture_binding_array, specialized_mesh_pipeline, and custom_shader_instancing examples after the bindless change. (#16641)
The bindless PR (#16368) broke some examples:

* `specialized_mesh_pipeline` and `custom_shader_instancing` failed
because they expect to be able to render a mesh with no material, by
overriding enough of the render pipeline to be able to do so. This PR
fixes the issue by restoring the old behavior in which we extract meshes
even if they have no material.

* `texture_binding_array` broke because it doesn't implement
`AsBindGroup::unprepared_bind_group`. This was tricky to fix because
there's a very good reason why `texture_binding_array` doesn't implement
that method: there's no sensible way to do so with `wgpu`'s current
bindless API, due to its multiple levels of borrowed references. To fix
the example, I split `MaterialBindGroup` into
`MaterialBindlessBindGroup` and `MaterialNonBindlessBindGroup`, and
allow direct custom implementations of `AsBindGroup::as_bind_group` for
the latter type of bind groups. To opt in to the new behavior, return
the `AsBindGroupError::CreateBindGroupDirectly` error from your
`AsBindGroup::unprepared_bind_group` implementation, and Bevy will call
your custom `AsBindGroup::as_bind_group` method as before.

## Migration Guide

* Bevy will now unconditionally call
`AsBindGroup::unprepared_bind_group` for your materials, so you must no
longer panic in that function. Instead, return the new
`AsBindGroupError::CreateBindGroupDirectly` error, and Bevy will fall
back to calling `AsBindGroup::as_bind_group` as before.
2024-12-05 21:22:14 +00:00
Zachary Harrold
73c6479f65
Add no_std support to bevy_color (#16633)
# Objective

- Contributes to #15460

## Solution

- Added the following new features: 
  - `std` (default)
  - `alloc`
  - `encase` (default)
  - `libm`

## Testing

- Added to `compile-check-no-std` CI command

## Notes

- `ColorCurve` requires `alloc` due to how the underlying `EvenCore`
type works.
- `Srgba::to_hex` requires `alloc` to return a `String`.
- This was otherwise a _very_ simple change
2024-12-05 21:21:45 +00:00
Michael Walter Van Der Velden
4be75305f2
Add optional transparency passthrough for sprite backend with bevy_picking (#16388)
# Objective

- Allow bevy_sprite_picking backend to pass through transparent sections
of the sprite.
- Fixes #14929

## Solution

- After sprite picking detects the cursor is within a sprites rect,
check the pixel at that location on the texture and check that it meets
an optional transparency cutoff. Change originally created for
mod_picking on bevy 0.14
(https://github.com/aevyrie/bevy_mod_picking/pull/373)

## Testing

- Ran Sprite Picking example to check it was working both with
transparency enabled and disabled
- ModPicking version is currently in use in my own isometric game where
this has been an extremely noticeable issue

## Showcase

![Sprite Picking
Text](https://github.com/user-attachments/assets/76568c0d-c359-422b-942d-17c84d3d3009)

## Migration Guide

Sprite picking now ignores transparent regions (with an alpha value less
than or equal to 0.1). To configure this, modify the
`SpriteBackendSettings` resource.

---------

Co-authored-by: andriyDev <andriydzikh@gmail.com>
2024-12-05 21:16:19 +00:00
Patrick Walton
8c2c07b1c8
Retain RenderMeshInstance and MeshInputUniform data from frame to frame. (#16385)
This commit moves the front end of the rendering pipeline to a retained
model when GPU preprocessing is in use (i.e. by default, except in
constrained environments). `RenderMeshInstance` and `MeshUniformData`
are stored from frame to frame and are updated only for the entities
that changed state. This was rather tricky and requires some careful
surgery to keep the data valid in the case of removals.

This patch is built on top of Bevy's change detection. Generally, this
worked, except that `ViewVisibility` isn't currently properly tracked.
Therefore, this commit adds proper change tracking for `ViewVisibility`.
Doing this required adding a new system that runs after all
`check_visibility` invocations, as no single `check_visibility`
invocation has enough global information to detect changes.

On the Bistro exterior scene, with all textures forced to opaque, this
patch improves steady-state `extract_meshes_for_gpu_building` from
93.8us to 34.5us and steady-state `collect_meshes_for_gpu_building` from
195.7us to 4.28us. Altogether this constitutes an improvement from 290us
to 38us, which is a 7.46x speedup.

![Screenshot 2024-11-13
143841](https://github.com/user-attachments/assets/40b1aacc-373d-4016-b7fd-b0284bc33de4)

![Screenshot 2024-11-13
143850](https://github.com/user-attachments/assets/53b401c3-7461-43b3-918b-cff89ea780d6)

This patch is only lightly tested and shouldn't land before 0.15 is
released anyway, so I'm releasing it as a draft.
2024-12-05 21:16:04 +00:00
Zachary Harrold
bf765e61b5
Add no_std support to bevy_reflect (#16256)
# Objective

- Contributes to #15460

## Solution

- Added `std` feature (enabled by default)

## Testing

- CI
- `cargo check -p bevy_reflect --no-default-features --target
"x86_64-unknown-none"`
- UEFI demo application runs with this branch of `bevy_reflect`,
allowing `derive(Reflect)`

## Notes

- The [`spin`](https://crates.io/crates/spin) crate has been included to
provide `RwLock` and `Once` (as an alternative to `OnceLock`) when the
`std` feature is not enabled. Another alternative may be more desirable,
please provide feedback if you have a strong opinion here!
- Certain items (`Box`, `String`, `ToString`) provided by `alloc` have
been added to `__macro_exports` as a way to avoid `alloc` vs `std`
namespacing. I'm personally quite annoyed that we can't rely on `alloc`
as a crate name in `std` environments within macros. I'd love an
alternative to my approach here, but I suspect it's the least-bad
option.
- I would've liked to have an `alloc` feature (for allocation-free
`bevy_reflect`), unfortunately, `erased_serde` unconditionally requires
access to `Box`. Maybe one day we could design around this, but for now
it just means `bevy_reflect` requires `alloc`.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-12-05 21:15:21 +00:00
Miles Silberling-Cook
09b0b5df91
Window picking (#16103)
# Objective

On the web, it's common to attach observers to windows. As @viridia has
discovered, this can be quite a nice paradigm in bevy as well when
applied to observers. The changes here are intended to make this
possible.
+ Adds a new default picking back-end as part to the core picking plugin
(which can be disabled) that causes pointers on windows to treat the
window entity as the final hit, behind everything else. This means
clicking empty space now dispatches normal picking events to the window,
and is especially nice for drag-and-drop functionality.
+ Adds a new traversal type, specific to picking events, that causes
them to bubble up to the window entity after they reach the root of the
hierarchy.

## Solution

The window picking back-end is extremely simple, but the bubbling
changes are much more complex, since they require doing a different
traversal depending on the picking event.

To achieve this, `Traversal` has been made generic over an associated
sized data type `D`. Observer bounds have been changed such that
`Event::Traversal<D>` is required for `Trigger<D>`. A blanket
implementation has been added for `()` and `Parent` that preserves the
existing functionality. A new `PointerTraversal` traversal has been
implemented, with a blanket implementation for `Traversal<Pointer<E>>`.

It is still possible to use `Parent` as the traversal for any event,
because of the blanket implementation. It is now possible for users to
add other custom traversals, which read event data during traversal.

## Testing

I tested these changes locally on some picking UI prototypes I have been
playing with. I also tested them on the picking examples.

---------

Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
2024-12-05 21:14:39 +00:00
MichiRecRoom
ec39f6b904
Do not attempt to send screenshots to Pixel Eagle without a token (#16655)
# Objective
Running Github Actions on forks helps users to reduce the amount of CI
errors they get before submitting a PR. However, due to how workflows
are set up on the Bevy repository, this can result in errors occurring
for jobs that may not be related to their PR - in this case, uploading
screenshots to Pixel Eagle.

## Solution
The Pixel Eagle workflow is skipped if we aren't running on the Bevy
repository.

If we are on the Bevy repository, or the user has set it to run
elsewhere, we check if the `PIXELEAGLE_TOKEN` secret is set. If it
isn't, we skip uploading screenshots to Pixel Eagle.

* Artifacts still continue to generate, in case the user needs them.
* In the event that the Pixel Eagle workflow runs, but the
`PIXELEAGLE_TOKEN` secret isn't set, we generate a step summary that
notifies the user of why it was skipped.
https://github.com/LikeLakers2/bevy/actions/runs/12173329006/attempts/1#summary-33953502068
for an example.

## Testing
Lots. And lots. Of trying to get Github Actions to work with me.
2024-12-05 21:00:01 +00:00
Nuutti Kotivuori
76d610d465
Flush commands after every mutation in WorldEntityMut (#16219)
# Objective

- Currently adding observers spawns an entity which implicitly flushes
the command queue, which can cause undefined behaviour if the
`WorldEntityMut` is used after this
- The reason `WorldEntityMut` attempted to (unsuccessfully) avoid
flushing commands until finished was that such commands may move or
despawn the entity being referenced, invalidating the cached location.
- With the introduction of hooks and observers, this isn't sensible
anymore as running the commands generated by hooks immediately is
required to maintain correct ordering of operations and to not expose
the world in an inconsistent state
- Objective is to make command flushing deterministic and fix the
related issues
- Fixes #16212
- Fixes #14621 
- Fixes #16034

## Solution

- Allow `WorldEntityMut` to exist even when it refers to a despawned
entity by allowing `EntityLocation` to be marked invalid
- Add checks to all methods to panic if trying to access a despawned
entity
- Flush command queue after every operation that might trigger hooks or
observers
- Update entity location always after flushing command queue

## Testing

- Added test cases for currently broken behaviour
- Added test cases that flushes happen in all operations
- Added test cases to ensure hooks and commands are run exactly in
correct order when nested

---

Todo:

- [x] Write migration guide
- [x] Add tests that using `EntityWorldMut` on a despawned entity panics
- [x] Add tests that commands are flushed after every operation that is
supposed to flush them
- [x] Add tests that hooks, observers and their spawned commands are run
in the correct order when nested

---

## Migration Guide

Previously `EntityWorldMut` triggered command queue flushes in
unpredictable places, which could interfere with hooks and observers.
Now the command queue is flushed always immediately after any call in
`EntityWorldMut` that spawns or despawns an entity, or adds, removes or
replaces a component. This means hooks and observers will run their
commands in the correct order.

As a side effect, there is a possibility that a hook or observer could
despawn the entity that is being referred to by `EntityWorldMut`. This
could already currently happen if an observer was added while keeping an
`EntityWorldMut` referece and would cause unsound behaviour. If the
entity has been despawned, calling any methods which require the entity
location will panic. This matches the behaviour that `Commands` will
panic if called on an already despawned entity. In the extremely rare
case where taking a new `EntityWorldMut` reference or otherwise
restructuring the code so that this case does not happen is not
possible, there's a new `is_despawned` method that can be used to check
if the referred entity has been despawned.
2024-12-05 20:30:12 +00:00
JMS55
83c729162f
Improve profiling instructions (#16299)
# Objective

- Make it easier to understand how to profile things.
- Talk about CPU vs GPU work for graphics.

## Solution

- Add a section on GPU profiling and CPU vs GPU work.
- Rearrange some sections so Tracy is the first backend mentioned.

## Issues
I did this as a very quick fix to clear some things up, but the overall
guide still flows poorly and has too much extraneous info distracting
from the use case of "I just want to figure out why my app is slow",
where the advice should be "use tracy, and if GPU bottlenecked, do
this". Someone should do a full rewrite at some point.

I chose to omit talking about RenderDiagnosticsPlugin, but it's
definitely worth a mention as a way to easily check GPU + GPU time for
graphics work, although it's not hooked up in a lot of the engine, iirc
only shadows and the main passes. Again someone else should write about
it in the future.

Similarly it might've been useful to have a section describing how to
use NSight/RGP/IGA/Xcode for GPU profiling, as they're far from
intuitive tools.
2024-12-05 18:41:58 +00:00
Christian Hughes
f87b9fe20c
Turn apply_deferred into a ZST System (#16642)
# Objective

- Required by #16622 due to differing implementations of `System` by
`FunctionSystem` and `ExclusiveFunctionSystem`.
- Optimize the memory usage of instances of `apply_deferred` in system
schedules.

## Solution

By changing `apply_deferred` from being an ordinary system that ends up
as an `ExclusiveFunctionSystem`, and instead into a ZST struct that
implements `System` manually, we save ~320 bytes per instance of
`apply_deferred` in any schedule.

## Testing

- All current tests pass.

---

## Migration Guide

- If you were previously calling the special `apply_deferred` system via
`apply_deferred(world)`, don't.
2024-12-05 18:14:05 +00:00