diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index 94749f0e8a4e7..87940c689a387 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -5,7 +5,7 @@ //! the derive helper attribute for `Reflect`, which looks like: //! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`. -use crate::fq_std::{FQAny, FQDefault, FQOption}; +use crate::fq_std::{FQAny, FQOption}; use crate::utility; use proc_macro2::{Ident, Span}; use quote::quote_spanned; @@ -225,7 +225,7 @@ impl ReflectTraits { &TraitImpl::Implemented(span) => Some(quote_spanned! {span=> fn reflect_hash(&self) -> #FQOption { use ::core::hash::{Hash, Hasher}; - let mut hasher: #bevy_reflect_path::ReflectHasher = #FQDefault::default(); + let mut hasher = #bevy_reflect_path::utility::reflect_hasher(); Hash::hash(&#FQAny::type_id(self), &mut hasher); Hash::hash(self, &mut hasher); #FQOption::Some(Hasher::finish(&hasher)) diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 07aa12efd0d0c..a7a6088fda177 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -1,6 +1,6 @@ use crate::{ - utility::NonGenericTypeInfoCell, DynamicInfo, Reflect, ReflectMut, ReflectOwned, ReflectRef, - TypeInfo, Typed, + utility::{reflect_hasher, NonGenericTypeInfoCell}, + DynamicInfo, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, Typed, }; use std::{ any::{Any, TypeId}, @@ -340,7 +340,7 @@ impl<'a> ExactSizeIterator for ArrayIter<'a> {} /// Returns the `u64` hash of the given [array](Array). #[inline] pub fn array_hash(array: &A) -> Option { - let mut hasher = crate::ReflectHasher::default(); + let mut hasher = reflect_hasher(); std::any::Any::type_id(array).hash(&mut hasher); array.len().hash(&mut hasher); for value in array.iter() { diff --git a/crates/bevy_reflect/src/enums/helpers.rs b/crates/bevy_reflect/src/enums/helpers.rs index d1ea359f8d6d8..09a3516c79d46 100644 --- a/crates/bevy_reflect/src/enums/helpers.rs +++ b/crates/bevy_reflect/src/enums/helpers.rs @@ -1,11 +1,11 @@ -use crate::{Enum, Reflect, ReflectRef, VariantType}; +use crate::{utility::reflect_hasher, Enum, Reflect, ReflectRef, VariantType}; use std::fmt::Debug; use std::hash::{Hash, Hasher}; /// Returns the `u64` hash of the given [enum](Enum). #[inline] pub fn enum_hash(value: &TEnum) -> Option { - let mut hasher = crate::ReflectHasher::default(); + let mut hasher = reflect_hasher(); std::any::Any::type_id(value).hash(&mut hasher); value.variant_name().hash(&mut hasher); value.variant_type().hash(&mut hasher); diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index efae9fdc8070c..a22a24958d80e 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -8,7 +8,7 @@ use crate::{ VariantInfo, VariantType, }; -use crate::utility::{GenericTypeInfoCell, NonGenericTypeInfoCell}; +use crate::utility::{reflect_hasher, GenericTypeInfoCell, NonGenericTypeInfoCell}; use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_value}; use bevy_utils::{Duration, Instant}; use bevy_utils::{HashMap, HashSet}; @@ -993,7 +993,7 @@ impl Reflect for Cow<'static, str> { } fn reflect_hash(&self) -> Option { - let mut hasher = crate::ReflectHasher::default(); + let mut hasher = reflect_hasher(); Hash::hash(&std::any::Any::type_id(self), &mut hasher); Hash::hash(self, &mut hasher); Some(hasher.finish()) @@ -1101,7 +1101,7 @@ impl Reflect for &'static Path { } fn reflect_hash(&self) -> Option { - let mut hasher = crate::ReflectHasher::default(); + let mut hasher = reflect_hasher(); Hash::hash(&std::any::Any::type_id(self), &mut hasher); Hash::hash(self, &mut hasher); Some(hasher.finish()) diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index c331d76b43e40..5cbc21cb329b4 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -2,7 +2,7 @@ use std::any::{Any, TypeId}; use std::fmt::{Debug, Formatter}; use std::hash::{Hash, Hasher}; -use crate::utility::NonGenericTypeInfoCell; +use crate::utility::{reflect_hasher, NonGenericTypeInfoCell}; use crate::{ DynamicInfo, FromReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, Typed, }; @@ -378,7 +378,7 @@ impl<'a> ExactSizeIterator for ListIter<'a> {} /// Returns the `u64` hash of the given [list](List). #[inline] pub fn list_hash(list: &L) -> Option { - let mut hasher = crate::ReflectHasher::default(); + let mut hasher = reflect_hasher(); std::any::Any::type_id(list).hash(&mut hasher); list.len().hash(&mut hasher); for value in list.iter() { diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 3857d8f3cd84b..90c57f7d5bbd6 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -9,7 +9,6 @@ use std::{ }; use crate::utility::NonGenericTypeInfoCell; -pub use bevy_utils::AHasher as ReflectHasher; /// An immutable enumeration of "kinds" of reflected type. /// diff --git a/crates/bevy_reflect/src/utility.rs b/crates/bevy_reflect/src/utility.rs index 8474bcb6e8595..3af535a1925ca 100644 --- a/crates/bevy_reflect/src/utility.rs +++ b/crates/bevy_reflect/src/utility.rs @@ -1,10 +1,13 @@ //! Helpers for working with Bevy reflection. use crate::TypeInfo; -use bevy_utils::HashMap; +use bevy_utils::{FixedState, HashMap}; use once_cell::race::OnceBox; use parking_lot::RwLock; -use std::any::{Any, TypeId}; +use std::{ + any::{Any, TypeId}, + hash::BuildHasher, +}; /// A container for [`TypeInfo`] over non-generic types, allowing instances to be stored statically. /// @@ -147,3 +150,15 @@ impl GenericTypeInfoCell { }) } } + +/// Deterministic fixed state hasher to be used by implementors of [`Reflect::reflect_hash`]. +/// +/// Hashes should be deterministic across processes so hashes can be used as +/// checksums for saved scenes, rollback snapshots etc. This function returns +/// such a hasher. +/// +/// [`Reflect::reflect_hash`]: crate::Reflect +#[inline] +pub fn reflect_hasher() -> bevy_utils::AHasher { + FixedState.build_hasher() +}