bevy_reflect: Re-reflect hashbrown
types (#18944)
# Objective Fixes #18943 ## Solution Reintroduces support for `hashbrown`'s `HashMap` and `HashSet` types. These were inadvertently removed when `bevy_platform` newtyped the `hashbrown` types. Since we removed our `hashbrown` dependency, I gated these impls behind a `hashbrown` feature. Not entirely sure if this is necessary since we enabled it for `bevy_reflect` through `bevy_platform` anyways. (Complex features still confuse me a bit so let me know if I can just remove it!) I also went ahead and preemptively implemented `TypePath` for `PassHash` while I was here. ## Testing You can test that it works by adding the following to a Bevy example based on this PR (you'll also need to include `hashbrown` of course): ```rust #[derive(Reflect)] struct Foo(hashbrown::HashMap<String, String>); ``` Then check it compiles with: ``` cargo check --example hello_world --no-default-features --features=bevy_reflect/hashbrown ```
This commit is contained in:
parent
b4ee898154
commit
227e1bbf34
@ -33,6 +33,9 @@ debug_stack = ["std"]
|
|||||||
## Adds reflection support to `glam` types.
|
## Adds reflection support to `glam` types.
|
||||||
glam = ["dep:glam"]
|
glam = ["dep:glam"]
|
||||||
|
|
||||||
|
## Adds reflection support to `hashbrown` types.
|
||||||
|
hashbrown = ["dep:hashbrown"]
|
||||||
|
|
||||||
## Adds reflection support to `petgraph` types.
|
## Adds reflection support to `petgraph` types.
|
||||||
petgraph = ["dep:petgraph", "std"]
|
petgraph = ["dep:petgraph", "std"]
|
||||||
|
|
||||||
@ -87,6 +90,7 @@ bevy_platform = { path = "../bevy_platform", version = "0.16.0", default-feature
|
|||||||
|
|
||||||
# used by bevy-utils, but it also needs reflect impls
|
# used by bevy-utils, but it also needs reflect impls
|
||||||
foldhash = { version = "0.1.3", default-features = false }
|
foldhash = { version = "0.1.3", default-features = false }
|
||||||
|
hashbrown = { version = "0.15.1", optional = true, default-features = false }
|
||||||
|
|
||||||
# other
|
# other
|
||||||
erased-serde = { version = "0.4", default-features = false, features = [
|
erased-serde = { version = "0.4", default-features = false, features = [
|
||||||
|
@ -1001,6 +1001,19 @@ crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashMap
|
|||||||
>
|
>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "hashbrown")]
|
||||||
|
impl_reflect_for_hashmap!(hashbrown::hash_map::HashMap<K, V, S>);
|
||||||
|
#[cfg(feature = "hashbrown")]
|
||||||
|
impl_type_path!(::hashbrown::hash_map::HashMap<K, V, S>);
|
||||||
|
#[cfg(all(feature = "functions", feature = "hashbrown"))]
|
||||||
|
crate::func::macros::impl_function_traits!(::hashbrown::hash_map::HashMap<K, V, S>;
|
||||||
|
<
|
||||||
|
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
|
||||||
|
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
|
||||||
|
S: TypePath + BuildHasher + Default + Send + Sync
|
||||||
|
>
|
||||||
|
);
|
||||||
|
|
||||||
macro_rules! impl_reflect_for_hashset {
|
macro_rules! impl_reflect_for_hashset {
|
||||||
($ty:path) => {
|
($ty:path) => {
|
||||||
impl<V, S> Set for $ty
|
impl<V, S> Set for $ty
|
||||||
@ -1208,6 +1221,7 @@ macro_rules! impl_reflect_for_hashset {
|
|||||||
|
|
||||||
impl_type_path!(::bevy_platform::hash::NoOpHash);
|
impl_type_path!(::bevy_platform::hash::NoOpHash);
|
||||||
impl_type_path!(::bevy_platform::hash::FixedHasher);
|
impl_type_path!(::bevy_platform::hash::FixedHasher);
|
||||||
|
impl_type_path!(::bevy_platform::hash::PassHash);
|
||||||
impl_reflect_opaque!(::core::net::SocketAddr(
|
impl_reflect_opaque!(::core::net::SocketAddr(
|
||||||
Clone,
|
Clone,
|
||||||
Debug,
|
Debug,
|
||||||
@ -1239,6 +1253,18 @@ crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashSet
|
|||||||
>
|
>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "hashbrown")]
|
||||||
|
impl_reflect_for_hashset!(::hashbrown::hash_set::HashSet<V,S>);
|
||||||
|
#[cfg(feature = "hashbrown")]
|
||||||
|
impl_type_path!(::hashbrown::hash_set::HashSet<V, S>);
|
||||||
|
#[cfg(all(feature = "functions", feature = "hashbrown"))]
|
||||||
|
crate::func::macros::impl_function_traits!(::hashbrown::hash_set::HashSet<V, S>;
|
||||||
|
<
|
||||||
|
V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration,
|
||||||
|
S: TypePath + BuildHasher + Default + Send + Sync
|
||||||
|
>
|
||||||
|
);
|
||||||
|
|
||||||
impl<K, V> Map for ::alloc::collections::BTreeMap<K, V>
|
impl<K, V> Map for ::alloc::collections::BTreeMap<K, V>
|
||||||
where
|
where
|
||||||
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
|
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
|
||||||
@ -2848,4 +2874,15 @@ mod tests {
|
|||||||
let output = <&'static str as FromReflect>::from_reflect(&expected).unwrap();
|
let output = <&'static str as FromReflect>::from_reflect(&expected).unwrap();
|
||||||
assert_eq!(expected, output);
|
assert_eq!(expected, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_reflect_hashmaps() {
|
||||||
|
assert_impl_all!(std::collections::HashMap<u32, f32>: Reflect);
|
||||||
|
assert_impl_all!(bevy_platform::collections::HashMap<u32, f32>: Reflect);
|
||||||
|
|
||||||
|
// We specify `foldhash::fast::RandomState` directly here since without the `default-hasher`
|
||||||
|
// feature, hashbrown uses an empty enum to force users to specify their own
|
||||||
|
#[cfg(feature = "hashbrown")]
|
||||||
|
assert_impl_all!(hashbrown::HashMap<u32, f32, foldhash::fast::RandomState>: Reflect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user