Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove remnant EntityHash and related types from bevy_utils #15039

Merged
merged 3 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions crates/bevy_ecs/src/observer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ mod trigger_event;
pub use runner::*;
pub use trigger_event::*;

use crate::entity::EntityHashMap;
use crate::observer::entity_observer::ObservedBy;
use crate::{archetype::ArchetypeFlags, system::IntoObserverSystem, world::*};
use crate::{component::ComponentId, prelude::*, world::DeferredWorld};
use bevy_ptr::Ptr;
use bevy_utils::{EntityHashMap, HashMap};
use bevy_utils::HashMap;
use std::{fmt::Debug, marker::PhantomData};

/// Type containing triggered [`Event`] information for a given run of an [`Observer`]. This contains the
Expand Down Expand Up @@ -152,15 +153,15 @@ pub struct ObserverTrigger {
}

// Map between an observer entity and its runner
type ObserverMap = EntityHashMap<Entity, ObserverRunner>;
type ObserverMap = EntityHashMap<ObserverRunner>;

/// Collection of [`ObserverRunner`] for [`Observer`] registered to a particular trigger targeted at a specific component.
#[derive(Default, Debug)]
pub struct CachedComponentObservers {
// Observers listening to triggers targeting this component
map: ObserverMap,
// Observers listening to triggers targeting this component on a specific entity
entity_map: EntityHashMap<Entity, ObserverMap>,
entity_map: EntityHashMap<ObserverMap>,
}

/// Collection of [`ObserverRunner`] for [`Observer`] registered to a particular trigger.
Expand All @@ -171,7 +172,7 @@ pub struct CachedObservers {
// Observers listening for this trigger fired at a specific component
component_observers: HashMap<ComponentId, CachedComponentObservers>,
// Observers listening for this trigger fired at a specific entity
entity_observers: EntityHashMap<Entity, ObserverMap>,
entity_observers: EntityHashMap<ObserverMap>,
}

/// Metadata for observers. Stores a cache mapping trigger ids to the registered observers.
Expand Down
1 change: 0 additions & 1 deletion crates/bevy_reflect/src/impls/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,6 @@ macro_rules! impl_reflect_for_hashset {
}

impl_type_path!(::bevy_utils::NoOpHash);
impl_type_path!(::bevy_utils::EntityHash);
impl_type_path!(::bevy_utils::FixedState);

impl_reflect_for_hashset!(::std::collections::HashSet<V,S>);
Expand Down
5 changes: 2 additions & 3 deletions crates/bevy_render/src/batching/gpu_preprocessing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
use bevy_app::{App, Plugin};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
entity::Entity,
entity::{Entity, EntityHashMap},
query::{Has, With},
schedule::IntoSystemConfigs as _,
system::{Query, Res, ResMut, Resource, StaticSystemParam},
world::{FromWorld, World},
};
use bevy_encase_derive::ShaderType;
use bevy_utils::EntityHashMap;
use bytemuck::{Pod, Zeroable};
use nonmax::NonMaxU32;
use smallvec::smallvec;
Expand Down Expand Up @@ -99,7 +98,7 @@ where
/// corresponds to each instance.
///
/// This is keyed off each view. Each view has a separate buffer.
pub work_item_buffers: EntityHashMap<Entity, PreprocessWorkItemBuffer>,
pub work_item_buffers: EntityHashMap<PreprocessWorkItemBuffer>,

/// The uniform data inputs for the current frame.
///
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_render/src/view/visibility/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use std::{
use bevy_app::{App, Plugin, PostUpdate};
use bevy_ecs::{
component::Component,
entity::Entity,
entity::{Entity, EntityHashMap},
query::{Changed, With},
schedule::IntoSystemConfigs as _,
system::{Query, Res, ResMut, Resource},
};
use bevy_math::{vec4, FloatOrd, Vec4};
use bevy_reflect::Reflect;
use bevy_transform::components::GlobalTransform;
use bevy_utils::{prelude::default, EntityHashMap, HashMap};
use bevy_utils::{prelude::default, HashMap};
use nonmax::NonMaxU16;
use wgpu::{BufferBindingType, BufferUsages};

Expand Down Expand Up @@ -191,7 +191,7 @@ impl VisibilityRange {
#[derive(Resource)]
pub struct RenderVisibilityRanges {
/// Information corresponding to each entity.
entities: EntityHashMap<Entity, RenderVisibilityEntityInfo>,
entities: EntityHashMap<RenderVisibilityEntityInfo>,

/// Maps a [`VisibilityRange`] to its index within the `buffer`.
///
Expand Down Expand Up @@ -309,13 +309,13 @@ impl RenderVisibilityRanges {
#[derive(Resource, Default)]
pub struct VisibleEntityRanges {
/// Stores which bit index each view corresponds to.
views: EntityHashMap<Entity, u8>,
views: EntityHashMap<u8>,

/// Stores a bitmask in which each view has a single bit.
///
/// A 0 bit for a view corresponds to "out of range"; a 1 bit corresponds to
/// "in range".
entities: EntityHashMap<Entity, u32>,
entities: EntityHashMap<u32>,
}

impl VisibleEntityRanges {
Expand Down
79 changes: 0 additions & 79 deletions crates/bevy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,85 +274,6 @@ impl<K: Hash + Eq + PartialEq + Clone, V> PreHashMapExt<K, V> for PreHashMap<K,
}
}

/// A [`BuildHasher`] that results in a [`EntityHasher`].
#[derive(Default, Clone)]
pub struct EntityHash;

impl BuildHasher for EntityHash {
type Hasher = EntityHasher;

fn build_hasher(&self) -> Self::Hasher {
EntityHasher::default()
}
}

/// A very fast hash that is only designed to work on generational indices
/// like `Entity`. It will panic if attempting to hash a type containing
/// non-u64 fields.
///
/// This is heavily optimized for typical cases, where you have mostly live
/// entities, and works particularly well for contiguous indices.
///
/// If you have an unusual case -- say all your indices are multiples of 256
/// or most of the entities are dead generations -- then you might want also to
/// try [`AHasher`] for a slower hash computation but fewer lookup conflicts.
#[derive(Debug, Default)]
pub struct EntityHasher {
hash: u64,
}

impl Hasher for EntityHasher {
#[inline]
fn finish(&self) -> u64 {
self.hash
}

fn write(&mut self, _bytes: &[u8]) {
panic!("can only hash u64 using EntityHasher");
}

#[inline]
fn write_u64(&mut self, bits: u64) {
// SwissTable (and thus `hashbrown`) cares about two things from the hash:
// - H1: low bits (masked by `2ⁿ-1`) to pick the slot in which to store the item
// - H2: high 7 bits are used to SIMD optimize hash collision probing
// For more see <https://abseil.io/about/design/swisstables#metadata-layout>

// This hash function assumes that the entity ids are still well-distributed,
// so for H1 leaves the entity id alone in the low bits so that id locality
// will also give memory locality for things spawned together.
// For H2, take advantage of the fact that while multiplication doesn't
// spread entropy to the low bits, it's incredibly good at spreading it
// upward, which is exactly where we need it the most.

// While this does include the generation in the output, it doesn't do so
// *usefully*. H1 won't care until you have over 3 billion entities in
// the table, and H2 won't care until something hits generation 33 million.
// Thus the comment suggesting that this is best for live entities,
// where there won't be generation conflicts where it would matter.

// The high 32 bits of this are ⅟φ for Fibonacci hashing. That works
// particularly well for hashing for the same reason as described in
// <https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/>
// It loses no information because it has a modular inverse.
// (Specifically, `0x144c_bc89_u32 * 0x9e37_79b9_u32 == 1`.)
//
// The low 32 bits make that part of the just product a pass-through.
const UPPER_PHI: u64 = 0x9e37_79b9_0000_0001;

// This is `(MAGIC * index + generation) << 32 + index`, in a single instruction.
self.hash = bits.wrapping_mul(UPPER_PHI);
}
}

/// A [`HashMap`] pre-configured to use [`EntityHash`] hashing.
/// Iteration order only depends on the order of insertions and deletions.
pub type EntityHashMap<K, V> = hashbrown::HashMap<K, V, EntityHash>;

/// A [`HashSet`] pre-configured to use [`EntityHash`] hashing.
/// Iteration order only depends on the order of insertions and deletions.
pub type EntityHashSet<T> = hashbrown::HashSet<T, EntityHash>;

/// A specialized hashmap type with Key of [`TypeId`]
/// Iteration order only depends on the order of insertions and deletions.
pub type TypeIdMap<V> = hashbrown::HashMap<TypeId, V, NoOpHash>;
Expand Down
4 changes: 2 additions & 2 deletions examples/2d/mesh2d_manual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use bevy::{
color::palettes::basic::YELLOW,
core_pipeline::core_2d::{Transparent2d, CORE_2D_DEPTH_FORMAT},
ecs::entity::EntityHashMap,
math::FloatOrd,
prelude::*,
render::{
Expand All @@ -33,7 +34,6 @@ use bevy::{
Mesh2dPipelineKey, Mesh2dTransforms, MeshFlags, RenderMesh2dInstance, SetMesh2dBindGroup,
SetMesh2dViewBindGroup, WithMesh2d,
},
utils::EntityHashMap,
};
use std::f32::consts::PI;

Expand Down Expand Up @@ -291,7 +291,7 @@ pub const COLORED_MESH2D_SHADER_HANDLE: Handle<Shader> =

/// Our custom pipeline needs its own instance storage
#[derive(Resource, Deref, DerefMut, Default)]
pub struct RenderColoredMesh2dInstances(EntityHashMap<Entity, RenderMesh2dInstance>);
pub struct RenderColoredMesh2dInstances(EntityHashMap<RenderMesh2dInstance>);

impl Plugin for ColoredMesh2dPlugin {
fn build(&self, app: &mut App) {
Expand Down