mirror of
https://github.com/bevyengine/bevy
synced 2025-01-23 02:15:15 +00:00
abceebebba
# 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> |
||
---|---|---|
.. | ||
bevy_a11y | ||
bevy_animation | ||
bevy_app | ||
bevy_asset | ||
bevy_audio | ||
bevy_color | ||
bevy_core | ||
bevy_core_pipeline | ||
bevy_derive | ||
bevy_dev_tools | ||
bevy_diagnostic | ||
bevy_dylib | ||
bevy_dynamic_plugin | ||
bevy_ecs | ||
bevy_encase_derive | ||
bevy_gilrs | ||
bevy_gizmos | ||
bevy_gltf | ||
bevy_hierarchy | ||
bevy_input | ||
bevy_internal | ||
bevy_log | ||
bevy_macro_utils | ||
bevy_math | ||
bevy_mikktspace | ||
bevy_pbr | ||
bevy_picking | ||
bevy_ptr | ||
bevy_reflect | ||
bevy_render | ||
bevy_scene | ||
bevy_sprite | ||
bevy_state | ||
bevy_tasks | ||
bevy_text | ||
bevy_time | ||
bevy_transform | ||
bevy_ui | ||
bevy_utils | ||
bevy_window | ||
bevy_winit |