
# Objective - Fixes #13703 ## Solution - Added `mappings` to the `EntityMapper` trait, which returns an iterator over currently tracked `Entity` to `Entity` mappings. - Added `DynEntityMapper` as an [object safe](https://doc.rust-lang.org/reference/items/traits.html#object-safety) alternative to `EntityMapper`. - Added `assert_object_safe` as a helper for ensuring traits are object safe. ## Testing - Added new unit test `entity_mapper_iteration` which tests the `SceneEntityMapper` implementation of `EntityMapper::mappings`. - Added unit tests to ensure `DynEntityMapper`, `DynEq` and `DynHash` are object safe. - Passed CI on my Windows 10 development environment --- ## Changelog - Added `mappings` to `EntityMapper` trait. ## Migration Guide - If you are implementing `EntityMapper` yourself, you can use the below as a stub implementation: ```rust fn mappings(&self) -> impl Iterator<Item = (Entity, Entity)> { unimplemented!() } ``` - If you were using `EntityMapper` as a trait object (`dyn EntityMapper`), instead use `dyn DynEntityMapper` and its associated methods. ## Notes - The original issue proposed returning a `Vec` from `EntityMapper` instead of an `impl Iterator` to preserve its object safety. This is a simpler option, but also forces an allocation where it isn't strictly needed. I've opted for this split into `DynEntityMapper` and `EntityMapper` as it's been done several times across Bevy already, and provides maximum flexibility to users. - `assert_object_safe` is an empty function, since the assertion actually happens once you try to use a `dyn T` for some trait `T`. I have still added this function to clearly document what object safety is within Bevy, and to create a standard way to communicate that a given trait must be object safe. - Other traits should have tests added to ensure object safety, but I've left those off to avoid cluttering this PR further. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
31 lines
995 B
Rust
31 lines
995 B
Rust
/// Assert that a given `T` is [object safe](https://doc.rust-lang.org/reference/items/traits.html#object-safety).
|
|
/// Will fail to compile if that is not the case.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// # use bevy_utils::assert_object_safe;
|
|
/// // Concrete types are always object safe
|
|
/// struct MyStruct;
|
|
/// assert_object_safe::<MyStruct>();
|
|
///
|
|
/// // Trait objects are where that safety comes into question.
|
|
/// // This trait is object safe...
|
|
/// trait ObjectSafe { }
|
|
/// assert_object_safe::<dyn ObjectSafe>();
|
|
/// ```
|
|
///
|
|
/// ```compile_fail
|
|
/// # use bevy_utils::assert_object_safe;
|
|
/// // ...but this trait is not.
|
|
/// trait NotObjectSafe {
|
|
/// const VALUE: usize;
|
|
/// }
|
|
/// assert_object_safe::<dyn NotObjectSafe>();
|
|
/// // Error: the trait `NotObjectSafe` cannot be made into an object
|
|
/// ```
|
|
pub fn assert_object_safe<T: ?Sized>() {
|
|
// This space is left intentionally blank. The type parameter T is sufficient to induce a compiler
|
|
// error without a function body.
|
|
}
|