bevy/crates
Carter Anderson a033f1b206
Replace VisitEntities with MapEntities (#18432)
# Objective

There are currently too many disparate ways to handle entity mapping,
especially after #17687. We now have MapEntities, VisitEntities,
VisitEntitiesMut, Component::visit_entities,
Component::visit_entities_mut.

Our only known use case at the moment for these is entity mapping. This
means we have significant consolidation potential.

Additionally, VisitEntitiesMut cannot be implemented for map-style
collections like HashSets, as you cant "just" mutate a `&mut Entity`.
Our current approach to Component mapping requires VisitEntitiesMut,
meaning this category of entity collection isn't mappable. `MapEntities`
is more generally applicable. Additionally, the _existence_ of the
blanket From impl on VisitEntitiesMut blocks us from implementing
MapEntities for HashSets (or any types we don't own), because the owner
could always add a conflicting impl in the future.

## Solution

Use `MapEntities` everywhere and remove all "visit entities" usages.

* Add `Component::map_entities`
* Remove `Component::visit_entities`, `Component::visit_entities_mut`,
`VisitEntities`, and `VisitEntitiesMut`
* Support deriving `Component::map_entities` in `#[derive(Coomponent)]`
* Add `#[derive(MapEntities)]`, and share logic with the
`Component::map_entities` derive.
* Add `ComponentCloneCtx::queue_deferred`, which is command-like logic
that runs immediately after normal clones. Reframe `FromWorld` fallback
logic in the "reflect clone" impl to use it. This cuts out a lot of
unnecessary work and I think justifies the existence of a pseudo-command
interface (given how niche, yet performance sensitive this is).

Note that we no longer auto-impl entity mapping for ` IntoIterator<Item
= &'a Entity>` types, as this would block our ability to implement cases
like `HashMap`. This means the onus is on us (or type authors) to add
explicit support for types that should be mappable.

Also note that the Component-related changes do not require a migration
guide as there hasn't been a release with them yet.

## Migration Guide

If you were previously implementing `VisitEntities` or
`VisitEntitiesMut` (likely via a derive), instead use `MapEntities`.
Those were almost certainly used in the context of Bevy Scenes or
reflection via `ReflectMapEntities`. If you have a case that uses
`VisitEntities` or `VisitEntitiesMut` directly, where `MapEntities` is
not a viable replacement, please let us know!

```rust
// before
#[derive(VisitEntities, VisitEntitiesMut)]
struct Inventory {
  items: Vec<Entity>,
  #[visit_entities(ignore)]
  label: String,
}

// after
#[derive(MapEntities)]
struct Inventory {
  #[entities]
  items: Vec<Entity>,
  label: String,
}
```
2025-03-21 00:18:10 +00:00
..
bevy_a11y bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_animation bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_anti_aliasing Add bevy_anti_aliasing (#18323) 2025-03-19 18:40:32 +00:00
bevy_app Unify and simplify command and system error handling (#18351) 2025-03-18 19:27:50 +00:00
bevy_asset bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_audio bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_color bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_core_pipeline Add bevy_anti_aliasing (#18323) 2025-03-19 18:40:32 +00:00
bevy_derive Link iOS example with rustc, and avoid C trampoline (#14780) 2025-03-17 21:14:07 +00:00
bevy_dev_tools Generic system config (#17962) 2025-03-12 00:12:30 +00:00
bevy_diagnostic Add process cpu/memory usage to SystemInformationDiagnosticsPlugin (#18279) 2025-03-16 21:14:46 +00:00
bevy_dylib enable std when building bevy_dylib (#18405) 2025-03-19 00:49:26 +00:00
bevy_ecs Replace VisitEntities with MapEntities (#18432) 2025-03-21 00:18:10 +00:00
bevy_encase_derive Internalize BevyManifest logic. Switch to RwLock (#18263) 2025-03-12 00:46:01 +00:00
bevy_gilrs Replace some !Send resources with thread_local! (#17730) 2025-03-04 07:48:02 +00:00
bevy_gizmos Extract sprites into a Vec (#17619) 2025-03-18 00:48:33 +00:00
bevy_gltf Gltf handle missing bindposes (#18419) 2025-03-19 21:45:05 +00:00
bevy_image remove circular dependency between bevy_sprite and bevy_image (#18379) 2025-03-18 01:38:49 +00:00
bevy_input bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_input_focus bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_internal Add bevy_anti_aliasing (#18323) 2025-03-19 18:40:32 +00:00
bevy_log Add print_stdout and print_stderr lints (#17446) (#18233) 2025-03-11 19:35:48 +00:00
bevy_macro_utils Switch to ImDocument in BevyManifest (#18272) 2025-03-12 20:15:39 +00:00
bevy_math bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_mesh bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_mikktspace Add print_stdout and print_stderr lints (#17446) (#18233) 2025-03-11 19:35:48 +00:00
bevy_pbr Add bevy_anti_aliasing (#18323) 2025-03-19 18:40:32 +00:00
bevy_picking Unify picking backends (#17348) 2025-03-18 19:24:43 +00:00
bevy_platform_support Remove example causing circular dependency in bevy_platform_support (#18390) 2025-03-18 08:58:52 +00:00
bevy_ptr moved Debug from derive to impl_ptr in bevy_ptr (#18042) 2025-02-28 02:54:46 +00:00
bevy_reflect Fixed Reflect derive macro on empty enums (#18277) (#18298) 2025-03-17 18:13:55 +00:00
bevy_remote FilteredResource returns a Result instead of a simple Option (#18265) 2025-03-17 18:54:13 +00:00
bevy_render Force serial command encoding on Linux/amdvlk (#18368) 2025-03-18 03:16:38 +00:00
bevy_scene Replace VisitEntities with MapEntities (#18432) 2025-03-21 00:18:10 +00:00
bevy_sprite Fix unecessary specialization checks for apps with many materials (#18410) 2025-03-19 06:22:39 +00:00
bevy_state bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_tasks Add print_stdout and print_stderr lints (#17446) (#18233) 2025-03-11 19:35:48 +00:00
bevy_text Extract sprites into a Vec (#17619) 2025-03-18 00:48:33 +00:00
bevy_time bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bevy_transform Revert "Transform Propagation Optimization: Static Subtree Marking (#18094)" (#18363) 2025-03-17 20:01:29 +00:00
bevy_ui Unified picking cleanup (#18401) 2025-03-18 20:28:03 +00:00
bevy_utils Automatically enable portable-atomic when required (#17570) 2025-02-24 20:52:46 +00:00
bevy_window Replace VisitEntities with MapEntities (#18432) 2025-03-21 00:18:10 +00:00
bevy_winit bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00