bevy/crates/bevy_ecs/src
Felix Rath abceebebba
feat: Add World::get_reflect() and World::get_reflect_mut() (#14416)
# Objective

Sometimes one wants to retrieve a `&dyn Reflect` for an entity's
component, which so far required multiple, non-obvious steps and
`unsafe`-code.
The docs for
[`MutUntyped`](https://docs.rs/bevy/latest/bevy/ecs/change_detection/struct.MutUntyped.html#method.map_unchanged)
contain an example of the unsafe part.

## Solution

This PR adds the two methods:

```rust
// immutable variant
World::get_reflect(&self, entity: Entity, type_id: TypeId) -> Result<&dyn Reflect, GetComponentReflectError>

// mutable variant
World::get_reflect_mut(&mut self, entity: Entity, type_id: TypeId) -> Result<Mut<'_, dyn Reflect>, GetComponentReflectError>
```

which take care of the necessary steps, check required invariants etc.,
and contain the unsafety so the caller doesn't have to deal with it.

## Testing

- Did you test these changes? If so, how?
- Added tests and a doc test, also (successfully) ran `cargo run -p ci`.
- Are there any parts that need more testing?
- Could add tests for each individual error variant, but it's not
required imo.
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- Run `cargo test --doc --package bevy_ecs --all-features --
world::World::get_reflect --show-output` for the doctest
- Run `cargo test --package bevy_ecs --lib --all-features --
world::tests::reflect_tests --show-output` for the unittests
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  - Don't think it's relevant, but tested on 64bit linux (only).

---

## Showcase

Copy of the doctest example which gives a good overview of what this
enables:

```rust
use bevy_ecs::prelude::*;
use bevy_reflect::Reflect;
use std::any::TypeId;

// define a `Component` and derive `Reflect` for it
#[derive(Component, Reflect)]
struct MyComponent;

// create a `World` for this example
let mut world = World::new();

// Note: This is usually handled by `App::register_type()`, but this example can not use `App`.
world.init_resource::<AppTypeRegistry>();
world.get_resource_mut::<AppTypeRegistry>().unwrap().write().register::<MyComponent>();

// spawn an entity with a `MyComponent`
let entity = world.spawn(MyComponent).id();

// retrieve a reflected reference to the entity's `MyComponent`
let comp_reflected: &dyn Reflect = world.get_reflect(entity, TypeId::of::<MyComponent>()).unwrap();

// make sure we got the expected type
assert!(comp_reflected.is::<MyComponent>());
```

## Migration Guide

No breaking changes, but users can use the new methods if they did it
manually before.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-23 16:57:54 +00:00
..
entity Fix intra-doc links and make CI test them (#14076) 2024-07-11 13:08:31 +00:00
event Minimal Bubbling Observers (#13991) 2024-07-15 13:39:41 +00:00
identifier feat: Reflection implementations on Identifier (#13648) 2024-06-03 16:33:14 +00:00
observer Recalibrated observe benchmark (#14381) 2024-07-18 18:25:33 +00:00
query implement DoubleEndedIterator for QueryManyIter (#14128) 2024-07-22 18:21:42 +00:00
reflect Fixed #14248 and other URL issues (#14276) 2024-07-11 12:01:49 +00:00
schedule Simplify run conditions (#14441) 2024-07-22 19:21:47 +00:00
storage Apply Clippy lints regarding lazy evaluation and closures (#14015) 2024-07-01 15:54:40 +00:00
system Make names of closure systems changable (#14369) 2024-07-18 18:07:47 +00:00
world feat: Add World::get_reflect() and World::get_reflect_mut() (#14416) 2024-07-23 16:57:54 +00:00
archetype.rs Component Lifecycle Hook & Observer Trigger for replaced values (#14212) 2024-07-15 15:24:15 +00:00
batching.rs Parallel event reader (#12554) 2024-04-22 16:37:42 +00:00
bundle.rs Update trigger_observers to operate over slices of data (#14354) 2024-07-17 13:01:52 +00:00
change_detection.rs Simplify run conditions (#14441) 2024-07-22 19:21:47 +00:00
component.rs Component Lifecycle Hook & Observer Trigger for replaced values (#14212) 2024-07-15 15:24:15 +00:00
intern.rs Moves intern and label modules into bevy_ecs (#12772) 2024-04-08 15:34:11 +00:00
label.rs Add mappings to EntityMapper (#13727) 2024-06-08 12:52:23 +00:00
lib.rs Component Lifecycle Hook & Observer Trigger for replaced values (#14212) 2024-07-15 15:24:15 +00:00
removal_detection.rs Created an EventMutator for when you want to mutate an event before reading (#13818) 2024-07-08 14:53:06 +00:00
traversal.rs Minimal Bubbling Observers (#13991) 2024-07-15 13:39:41 +00:00