diff --git a/crates/bevy_reflect/Cargo.toml b/crates/bevy_reflect/Cargo.toml index d2297ab716..f37865f9a3 100644 --- a/crates/bevy_reflect/Cargo.toml +++ b/crates/bevy_reflect/Cargo.toml @@ -33,6 +33,9 @@ debug_stack = ["std"] ## Adds reflection support to `glam` types. glam = ["dep:glam"] +## Adds reflection support to `hashbrown` types. +hashbrown = ["dep:hashbrown"] + ## Adds reflection support to `petgraph` types. 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 foldhash = { version = "0.1.3", default-features = false } +hashbrown = { version = "0.15.1", optional = true, default-features = false } # other erased-serde = { version = "0.4", default-features = false, features = [ diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 350527f910..6a752d1877 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -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); +#[cfg(feature = "hashbrown")] +impl_type_path!(::hashbrown::hash_map::HashMap); +#[cfg(all(feature = "functions", feature = "hashbrown"))] +crate::func::macros::impl_function_traits!(::hashbrown::hash_map::HashMap; + < + K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > +); + macro_rules! impl_reflect_for_hashset { ($ty:path) => { impl 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::FixedHasher); +impl_type_path!(::bevy_platform::hash::PassHash); impl_reflect_opaque!(::core::net::SocketAddr( Clone, 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); +#[cfg(feature = "hashbrown")] +impl_type_path!(::hashbrown::hash_set::HashSet); +#[cfg(all(feature = "functions", feature = "hashbrown"))] +crate::func::macros::impl_function_traits!(::hashbrown::hash_set::HashSet; + < + V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > +); + impl Map for ::alloc::collections::BTreeMap where K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, @@ -2848,4 +2874,15 @@ mod tests { let output = <&'static str as FromReflect>::from_reflect(&expected).unwrap(); assert_eq!(expected, output); } + + #[test] + fn should_reflect_hashmaps() { + assert_impl_all!(std::collections::HashMap: Reflect); + assert_impl_all!(bevy_platform::collections::HashMap: 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: Reflect); + } }