bevy/crates
Zachary Harrold 3f19997096
Added modify_component to EntityWorldMut, DeferredWorld, and World (#16668)
# Objective

- Make working with immutable components more ergonomic
- Assist #16662

## Solution

Added `modify_component` to `World` and `EntityWorldMut`. This method
"removes" a component from an entity, gives a mutable reference to it to
a provided closure, and then "re-inserts" the component back onto the
entity. This replacement triggers the `OnReplace` and `OnInsert` hooks,
but does _not_ cause an archetype move, as the removal is purely
simulated.

## Testing

- Added doc-tests and a unit test.

---

## Showcase

```rust
use bevy_ecs::prelude::*;

/// An immutable component.
#[derive(Component, PartialEq, Eq, Debug)]
#[component(immutable)]
struct Foo(bool);

let mut world = World::default();

let mut entity = world.spawn(Foo(false));

assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));

// Before the closure is executed, the `OnReplace` hooks/observers are triggered
entity.modify_component(|foo: &mut Foo| {
    foo.0 = true;
});
// After the closure is executed, `OnInsert` hooks/observers are triggered

assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));
```

## Notes

- If the component is not available on the entity, the closure and hooks
aren't executed, and `None` is returned. I chose this as an alternative
to returning an error or panicking, but I'm open to changing that based
on feedback.
- This relies on `unsafe`, in particular for accessing the `Archetype`
to trigger hooks. All the unsafe operations are contained within
`DeferredWorld::modify_component`, and I would appreciate that this
function is given special attention to ensure soundness.
- The `OnAdd` hook can never be triggered by this method, since the
component must already be inserted. I have chosen to not trigger
`OnRemove`, as I believe it makes sense that this method is purely a
replacement operation, not an actual removal/insertion.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Malek <50841145+MalekiRe@users.noreply.github.com>
2024-12-31 00:23:44 +00:00
..
bevy_a11y Replace bevy_a11y::Focus with InputFocus (#16863) 2024-12-18 00:16:19 +00:00
bevy_animation Simplify sort/max_by calls (#17048) 2024-12-30 22:59:36 +00:00
bevy_app Use -D warnings in all relevant CI (#17011) 2024-12-31 00:15:28 +00:00
bevy_asset Fix path checking for FileWatcher for virtual workspace projects (#16958) 2024-12-29 19:43:42 +00:00
bevy_audio Prefer Display over Debug (#16112) 2024-12-27 00:40:06 +00:00
bevy_color Fix msrvs (#17012) 2024-12-29 20:00:19 +00:00
bevy_core_pipeline Fix Docs // incorrect default value for ChromaticAberration intensity (#16994) 2024-12-29 19:32:44 +00:00
bevy_derive Add benchmarks and compile_fail tests back to workspace (#16858) 2024-12-21 22:30:29 +00:00
bevy_dev_tools Draw the UI debug overlay using the UI renderer (#16693) 2024-12-11 00:49:47 +00:00
bevy_diagnostic Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_dylib
bevy_ecs Added modify_component to EntityWorldMut, DeferredWorld, and World (#16668) 2024-12-31 00:23:44 +00:00
bevy_encase_derive Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_gilrs Deny derive_more error feature and replace it with thiserror (#16684) 2024-12-06 17:03:55 +00:00
bevy_gizmos Refactor non-core Curve methods into extension traits (#16930) 2024-12-29 19:26:49 +00:00
bevy_gltf Prefer Display over Debug (#16112) 2024-12-27 00:40:06 +00:00
bevy_hierarchy Refactor hierarchy-related commands to remove structs (#17029) 2024-12-30 20:58:03 +00:00
bevy_image Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_input Add no_std support to bevy_input (#16995) 2024-12-29 22:46:30 +00:00
bevy_input_focus Simplify sort/max_by calls (#17048) 2024-12-30 22:59:36 +00:00
bevy_internal Expose bevy_image as a feature (#16948) 2024-12-24 03:11:01 +00:00
bevy_log Basic filtering examples for users of the bevy_log. (#16455) 2024-12-29 22:56:40 +00:00
bevy_macro_utils Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_math Fix no_std CI Warnings and WASM Compatibility (#17049) 2024-12-30 23:01:27 +00:00
bevy_mesh Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_mikktspace Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_pbr Simplify sort/max_by calls (#17048) 2024-12-30 22:59:36 +00:00
bevy_picking Simplify sort/max_by calls (#17048) 2024-12-30 22:59:36 +00:00
bevy_ptr Fix MSRVs for standalone crates (#16333) 2024-11-17 09:38:13 +00:00
bevy_reflect Fix no_std CI Warnings and WASM Compatibility (#17049) 2024-12-30 23:01:27 +00:00
bevy_remote BRP registry JSON schema endpoint (#16882) 2024-12-26 22:14:08 +00:00
bevy_render Use -D warnings in all relevant CI (#17011) 2024-12-31 00:15:28 +00:00
bevy_scene Simplify sort/max_by calls (#17048) 2024-12-30 22:59:36 +00:00
bevy_sprite prepare_sprite_image_bind_groups refactor (#17045) 2024-12-30 22:54:04 +00:00
bevy_state Add no_std support to bevy_state (#17028) 2024-12-29 23:28:18 +00:00
bevy_tasks Use -D warnings in all relevant CI (#17011) 2024-12-31 00:15:28 +00:00
bevy_text get_glyph_atlas_info refactor (#17044) 2024-12-30 21:08:12 +00:00
bevy_time Use en-us locale for typos (#16037) 2024-10-20 18:55:17 +00:00
bevy_transform Add no_std support to bevy_transform (#17030) 2024-12-30 21:01:13 +00:00
bevy_ui Prefer Display over Debug (#16112) 2024-12-27 00:40:06 +00:00
bevy_utils Add portable-atomic support to bevy_utils for once! (#17027) 2024-12-29 22:50:08 +00:00
bevy_window Make RawHandleWrapper fields private to save users from themselves (#16968) 2024-12-29 19:54:57 +00:00
bevy_winit Simplify sort/max_by calls (#17048) 2024-12-30 22:59:36 +00:00