-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# 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>
- Loading branch information
1 parent
d38d8a1
commit 3bfc427
Showing
4 changed files
with
126 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/// 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. | ||
} |