diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index d27e2a4d281b8b..5c16732fb7f932 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -1,4 +1,5 @@ use bevy_utils::HashMap; +use bevy_utils::StableHashMap; use crate::{ bundle::BundleId, @@ -132,13 +133,11 @@ pub struct Archetype { RelationKindId, ( Option, - HashMap, + StableHashMap, ), >, } -// FIXME(Relationships) hashmap iters are nondet and causing tests to fail - pub struct KindTargetsIter<'a> { no_target: Option<()>, targets: std::collections::hash_map::Keys<'a, Entity, ArchetypeComponentInfo>, @@ -177,7 +176,8 @@ impl Archetype { for ((kind_id, target), archetype_component_id) in table_components.iter().zip(table_archetype_components) { - let components = components.get_or_insert_with(*kind_id, || (None, HashMap::default())); + let components = + components.get_or_insert_with(*kind_id, || (None, StableHashMap::default())); let arch_comp_info = ArchetypeComponentInfo { storage_type: StorageType::Table, @@ -196,7 +196,8 @@ impl Archetype { .iter() .zip(sparse_set_archetype_components) { - let components = components.get_or_insert_with(*kind_id, || (None, HashMap::default())); + let components = + components.get_or_insert_with(*kind_id, || (None, StableHashMap::default())); let arch_comp_info = ArchetypeComponentInfo { storage_type: StorageType::SparseSet, archetype_component_id, diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index f912f5cb17b0e9..0e3b7ed339c239 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -7,7 +7,7 @@ use crate::{ world::{Mut, World}, }; use bevy_ecs_macros::all_tuples; -use bevy_utils::HashMap; +use bevy_utils::{HashMap, StableHashMap}; use smallvec::SmallVec; use std::{ any::TypeId, @@ -671,7 +671,7 @@ pub enum Either { pub enum RelationAccess<'w, 's, T: Component> { Table { current_idx: usize, - columns: &'w (Option, HashMap), + columns: &'w (Option, StableHashMap), iter: Either, std::slice::Iter<'s, Entity>>, p: PhantomData<&'w T>, }, diff --git a/crates/bevy_ecs/src/storage/table.rs b/crates/bevy_ecs/src/storage/table.rs index 19d86d14643591..db5f0a75c6f808 100644 --- a/crates/bevy_ecs/src/storage/table.rs +++ b/crates/bevy_ecs/src/storage/table.rs @@ -4,7 +4,7 @@ use crate::{ entity::Entity, storage::{BlobVec, SparseSet}, }; -use bevy_utils::{AHasher, HashMap}; +use bevy_utils::{AHasher, HashMap, StableHashMap}; use std::{ cell::UnsafeCell, hash::{Hash, Hasher}, @@ -159,7 +159,6 @@ impl Column { } } -// FIXME(Relationships) hashmap iters are nondet and causing tests to fail pub struct ColIter<'a> { no_target_col: Option<&'a Column>, target_cols: std::collections::hash_map::Iter<'a, Entity, Column>, @@ -177,7 +176,7 @@ impl<'a> Iterator for ColIter<'a> { } pub struct Table { - pub(crate) columns: SparseSet, HashMap)>, + pub(crate) columns: SparseSet, StableHashMap)>, entities: Vec, archetypes: Vec, grow_amount: usize, @@ -239,7 +238,7 @@ impl Table { pub fn add_column(&mut self, component_kind: &RelationshipKindInfo, target: Option) { let column = self .columns - .get_or_insert_with(component_kind.id(), || (None, HashMap::default())); + .get_or_insert_with(component_kind.id(), || (None, StableHashMap::default())); match target { Some(target) => { diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index d1a405910ba4db..ef1ea95dea133b 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -6,7 +6,7 @@ mod world_cell; #[cfg(test)] mod tests; -use bevy_utils::HashMap; +use bevy_utils::{HashMap, StableHashMap}; pub use entity_ref::*; pub use pointer::*; pub use spawn_batch::*; @@ -867,7 +867,7 @@ impl World { ), storage_type: StorageType::Table, }), - HashMap::default(), + StableHashMap::default(), ), ); *archetype_component_count += 1; diff --git a/crates/bevy_ecs/src/world/tests.rs b/crates/bevy_ecs/src/world/tests.rs index ff3c0995e2b376..34b55c656191be 100644 --- a/crates/bevy_ecs/src/world/tests.rs +++ b/crates/bevy_ecs/src/world/tests.rs @@ -231,28 +231,27 @@ fn table_relation_access() { ); assert!(matches!(accessor.next(), None)); // - let (child, accessor) = iter.next().unwrap(); + let (child, mut accessor) = iter.next().unwrap(); assert!(child == child2); - let foo = accessor.collect::>(); assert_eq!( - foo[0], + accessor.next().unwrap(), ( - Some(parent2), + Some(random_parent), &ChildOf { - despawn_recursive: false + despawn_recursive: true } ) ); assert_eq!( - foo[1], + accessor.next().unwrap(), ( - Some(random_parent), + Some(parent2), &ChildOf { - despawn_recursive: true + despawn_recursive: false } ) ); - assert!(foo.len() == 2); + assert!(matches!(accessor.next(), None)); assert!(matches!(iter.next(), None)); } @@ -354,18 +353,18 @@ fn sparse_relation_access() { assert_eq!( accessor.next().unwrap(), ( - Some(parent1), + Some(random_parent), &ChildOf { - despawn_recursive: true + despawn_recursive: false } ) ); assert_eq!( accessor.next().unwrap(), ( - Some(random_parent), + Some(parent1), &ChildOf { - despawn_recursive: false + despawn_recursive: true } ) );