Skip to content
Open
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
14 changes: 14 additions & 0 deletions _release-content/migration-guides/type_id_map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: Explicit TypeId map aliases
pull_requests: [25053]
---

`TypeIdHashMap` and `TypeIdIndexMap` have been added for code that maps
[`TypeId`](https://doc.rust-lang.org/std/any/struct.TypeId.html) values. Use `TypeIdHashMap` when
iteration order is unimportant and average O(1) removal is desired. Use `TypeIdIndexMap` when
insertion-order iteration is required.

`TypeIdMap` remains an alias for the ordered `TypeIdIndexMap`, but is deprecated so users can
choose the appropriate behavior explicitly. `TypeIdMapEntry` is likewise deprecated in favor of
`TypeIdHashMapEntry` or `TypeIdIndexMapEntry`. Use `TypeIdHashMapExt` for the generic convenience
methods on `TypeIdHashMap`; the existing `TypeIdMapExt` continues to work with ordered maps.
12 changes: 6 additions & 6 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use bevy_platform::{collections::HashMap, hash::NoOpHash};
use bevy_reflect::{prelude::ReflectDefault, Reflect, TypePath};
use bevy_time::Time;
use bevy_transform::TransformSystems;
use bevy_utils::{PreHashMap, PreHashMapExt, TypeIdMap};
use bevy_utils::{PreHashMap, PreHashMapExt, TypeIdHashMap};
use serde::{Deserialize, Serialize};
use thread_local::ThreadLocal;
use tracing::{trace, warn};
Expand Down Expand Up @@ -778,7 +778,7 @@ pub struct AnimationEvaluationState {
struct AnimationCurveEvaluators {
component_property_curve_evaluators:
PreHashMap<(TypeId, usize), Box<dyn AnimationCurveEvaluator>>,
type_id_curve_evaluators: TypeIdMap<Box<dyn AnimationCurveEvaluator>>,
type_id_curve_evaluators: TypeIdHashMap<Box<dyn AnimationCurveEvaluator>>,
}

impl AnimationCurveEvaluators {
Expand All @@ -804,10 +804,10 @@ impl AnimationCurveEvaluators {
.component_property_curve_evaluators
.get_or_insert_with(component_property, func),
EvaluatorId::Type(type_id) => match self.type_id_curve_evaluators.entry(type_id) {
bevy_utils::TypeIdMapEntry::Occupied(occupied_entry) => {
bevy_utils::TypeIdHashMapEntry::Occupied(occupied_entry) => {
&mut **occupied_entry.into_mut()
}
bevy_utils::TypeIdMapEntry::Vacant(vacant_entry) => {
bevy_utils::TypeIdHashMapEntry::Vacant(vacant_entry) => {
&mut **vacant_entry.insert(func())
}
},
Expand All @@ -818,7 +818,7 @@ impl AnimationCurveEvaluators {
#[derive(Default)]
struct CurrentEvaluators {
component_properties: PreHashMap<(TypeId, usize), ()>,
type_ids: TypeIdMap<()>,
type_ids: TypeIdHashMap<()>,
}

impl CurrentEvaluators {
Expand All @@ -837,7 +837,7 @@ impl CurrentEvaluators {
(visit)(EvaluatorId::ComponentField(&key))?;
}

for (key, _) in self.type_ids.drain(..) {
for (key, _) in self.type_ids.drain() {
(visit)(EvaluatorId::Type(key))?;
}

Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_app/src/plugin_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
use bevy_utils::{TypeIdMap, TypeIdMapEntry as Entry};
use bevy_utils::{TypeIdHashMap, TypeIdHashMapEntry as Entry};
use core::any::TypeId;
use log::{debug, warn};

Expand Down Expand Up @@ -281,7 +281,7 @@ impl PluginGroup for PluginGroupBuilder {
/// can be disabled, enabled or reordered.
pub struct PluginGroupBuilder {
group_name: String,
plugins: TypeIdMap<PluginEntry>,
plugins: TypeIdHashMap<PluginEntry>,
order: Vec<TypeId>,
}

Expand Down Expand Up @@ -417,7 +417,7 @@ impl PluginGroupBuilder {
for plugin_id in order {
self.upsert_plugin_entry_state(
plugin_id,
plugins.shift_remove(&plugin_id).unwrap(),
plugins.remove(&plugin_id).unwrap(),
self.order.len(),
);

Expand Down Expand Up @@ -566,7 +566,7 @@ impl PluginGroupBuilder {
#[track_caller]
pub fn finish(mut self, app: &mut App) {
for ty in &self.order {
if let Some(entry) = self.plugins.shift_remove(ty)
if let Some(entry) = self.plugins.remove(ty)
&& entry.enabled
{
debug!("added plugin: {}", entry.plugin.name());
Expand Down
20 changes: 10 additions & 10 deletions crates/bevy_asset/src/server/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use alloc::{
use bevy_ecs::world::World;
use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet};
use bevy_tasks::Task;
use bevy_utils::{TypeIdMap, TypeIdMapEntry};
use bevy_utils::{TypeIdHashMap, TypeIdHashMapEntry};
use core::{
any::{type_name, TypeId},
task::Waker,
Expand Down Expand Up @@ -79,7 +79,7 @@ pub(crate) struct AssetServerStats {

#[derive(Default)]
pub(crate) struct AssetInfos {
path_to_index: HashMap<AssetPath<'static>, TypeIdMap<AssetIndex>>,
path_to_index: HashMap<AssetPath<'static>, TypeIdHashMap<AssetIndex>>,
infos: HashMap<ErasedAssetIndex, AssetInfo>,
/// If set to `true`, this informs [`AssetInfos`] to track data relevant to watching for changes (such as `load_dependents`)
/// This should only be set at startup.
Expand All @@ -90,10 +90,10 @@ pub(crate) struct AssetInfos {
/// Tracks living labeled assets for a given source asset.
/// This should only be set when watching for changes to avoid unnecessary work.
pub(crate) living_labeled_assets: HashMap<AssetPath<'static>, HashSet<Box<str>>>,
pub(crate) handle_providers: TypeIdMap<AssetHandleProvider>,
pub(crate) dependency_loaded_event_sender: TypeIdMap<fn(&mut World, AssetIndex)>,
pub(crate) handle_providers: TypeIdHashMap<AssetHandleProvider>,
pub(crate) dependency_loaded_event_sender: TypeIdHashMap<fn(&mut World, AssetIndex)>,
pub(crate) dependency_failed_event_sender:
TypeIdMap<fn(&mut World, AssetIndex, AssetPath<'static>, AssetLoadError)>,
TypeIdHashMap<fn(&mut World, AssetIndex, AssetPath<'static>, AssetLoadError)>,
pub(crate) pending_tasks: HashMap<ErasedAssetIndex, Task<()>>,
/// The stats that have collected during usage of the asset server.
pub(crate) stats: AssetServerStats,
Expand Down Expand Up @@ -133,7 +133,7 @@ impl AssetInfos {

fn create_handle_internal(
infos: &mut HashMap<ErasedAssetIndex, AssetInfo>,
handle_providers: &TypeIdMap<AssetHandleProvider>,
handle_providers: &TypeIdHashMap<AssetHandleProvider>,
living_labeled_assets: &mut HashMap<AssetPath<'static>, HashSet<Box<str>>>,
watching_for_changes: bool,
type_id: TypeId,
Expand Down Expand Up @@ -222,7 +222,7 @@ impl AssetInfos {
.ok_or(GetOrCreateHandleInternalError::HandleMissingButTypeIdNotSpecified)?;

match handles.entry(type_id) {
TypeIdMapEntry::Occupied(entry) => {
TypeIdHashMapEntry::Occupied(entry) => {
let index = *entry.get();
// if there is a path_to_id entry, info always exists
let info = self
Expand Down Expand Up @@ -264,7 +264,7 @@ impl AssetInfos {
}
}
// The entry does not exist, so this is a "fresh" asset load. We must create a new handle
TypeIdMapEntry::Vacant(entry) => {
TypeIdHashMapEntry::Vacant(entry) => {
let should_load = match loading_mode {
HandleLoadingMode::NotLoading => false,
HandleLoadingMode::Request | HandleLoadingMode::Force => true,
Expand Down Expand Up @@ -709,7 +709,7 @@ impl AssetInfos {

fn process_handle_drop_internal(
infos: &mut HashMap<ErasedAssetIndex, AssetInfo>,
path_to_id: &mut HashMap<AssetPath<'static>, TypeIdMap<AssetIndex>>,
path_to_id: &mut HashMap<AssetPath<'static>, TypeIdHashMap<AssetIndex>>,
loader_dependents: &mut HashMap<AssetPath<'static>, HashSet<AssetPath<'static>>>,
living_labeled_assets: &mut HashMap<AssetPath<'static>, HashSet<Box<str>>>,
pending_tasks: &mut HashMap<ErasedAssetIndex, Task<()>>,
Expand Down Expand Up @@ -746,7 +746,7 @@ impl AssetInfos {
}

if let Some(map) = path_to_id.get_mut(path) {
map.shift_remove(&type_id);
map.remove(&type_id);

if map.is_empty() {
path_to_id.remove(path);
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_asset/src/server/loaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ use alloc::{boxed::Box, sync::Arc, vec::Vec};
use async_broadcast::RecvError;
use bevy_platform::collections::HashMap;
use bevy_tasks::IoTaskPool;
use bevy_utils::TypeIdMap;
use bevy_utils::TypeIdHashMap;
use core::any::TypeId;
use thiserror::Error;
use tracing::warn;

#[derive(Default)]
pub(crate) struct AssetLoaders {
loaders: Vec<MaybeAssetLoader>,
type_id_to_loaders: TypeIdMap<Vec<usize>>,
type_id_to_loaders: TypeIdHashMap<Vec<usize>>,
extension_to_loaders: HashMap<Box<str>, Vec<usize>>,
type_path_to_loader: HashMap<&'static str, usize>,
type_path_to_preregistered_loader: HashMap<&'static str, usize>,
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_camera/src/visibility/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use bevy_asset::{AssetEventSystems, Assets};
use bevy_ecs::{prelude::*, VariantDefaults};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_transform::{components::GlobalTransform, TransformSystems};
use bevy_utils::{Parallel, TypeIdMap};
use bevy_utils::{Parallel, TypeIdHashMap};
use smallvec::SmallVec;

use crate::{
Expand Down Expand Up @@ -343,7 +343,7 @@ pub struct DynamicSkinnedMeshBounds;
#[reflect(Component, Default, Debug, Clone)]
pub struct VisibleEntities {
#[reflect(ignore, clone)]
pub entities: TypeIdMap<Vec<Entity>>,
pub entities: TypeIdHashMap<Vec<Entity>>,
}

impl Default for VisibleEntities {
Expand All @@ -355,7 +355,7 @@ impl Default for VisibleEntities {
// We could handle this case in the `DirtySpecializations` methods
// instead, but that would complicate what are already some very
// complicated method signatures. So it's simpler to just do this.
let mut entities = TypeIdMap::default();
let mut entities = TypeIdHashMap::default();
entities.insert(TypeId::of::<Mesh3d>(), vec![]);
VisibleEntities { entities }
}
Expand Down Expand Up @@ -746,7 +746,7 @@ fn reset_view_visibility(mut reset_query: Query<&mut ViewVisibility, Without<NoC
/// To ensure that an entity is checked for visibility, make sure that it has a
/// [`VisibilityClass`] component and that that component is nonempty.
pub fn check_visibility_cpu_culling(
mut thread_queues: Local<Parallel<TypeIdMap<Vec<Entity>>>>,
mut thread_queues: Local<Parallel<TypeIdHashMap<Vec<Entity>>>>,
mut view_query: Query<(
Entity,
&mut VisibleEntities,
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ecs/src/bundle/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy_platform::{
hash::FixedHasher,
};
use bevy_ptr::{MovingPtr, OwningPtr};
use bevy_utils::TypeIdMap;
use bevy_utils::TypeIdHashMap;
use core::{any::TypeId, ptr::NonNull};
use indexmap::{IndexMap, IndexSet};

Expand Down Expand Up @@ -393,9 +393,9 @@ pub(crate) enum ArchetypeMoveType {
pub struct Bundles {
bundle_infos: Vec<BundleInfo>,
/// Cache static [`BundleId`]
bundle_ids: TypeIdMap<BundleId>,
bundle_ids: TypeIdHashMap<BundleId>,
/// Cache bundles, which contains both explicit and required components of [`Bundle`]
contributed_bundle_ids: TypeIdMap<BundleId>,
contributed_bundle_ids: TypeIdHashMap<BundleId>,
/// Cache dynamic [`BundleId`] with multiple components
dynamic_bundle_ids: HashMap<Box<[ComponentId]>, BundleId>,
dynamic_bundle_storages: HashMap<BundleId, Vec<StorageType>>,
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/component/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bevy_platform::{hash::FixedHasher, sync::PoisonError};
use bevy_ptr::OwningPtr;
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect;
use bevy_utils::{prelude::DebugName, TypeIdMap};
use bevy_utils::{prelude::DebugName, TypeIdHashMap};
use core::{
alloc::Layout,
any::{Any, TypeId},
Expand Down Expand Up @@ -360,7 +360,7 @@ impl ComponentDescriptor {
#[derive(Debug, Default)]
pub struct Components {
pub(super) components: Vec<Option<ComponentInfo>>,
pub(super) indices: TypeIdMap<ComponentId>,
pub(super) indices: TypeIdHashMap<ComponentId>,
// This is kept internal and local to verify that no deadlocks can occur.
pub(super) queued: bevy_platform::sync::RwLock<QueuedComponents>,
}
Expand Down
15 changes: 5 additions & 10 deletions crates/bevy_ecs/src/component/register.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloc::vec::Vec;
use bevy_platform::sync::PoisonError;
use bevy_utils::TypeIdMap;
use bevy_utils::TypeIdHashMap;
use core::any::Any;
use core::{any::TypeId, fmt::Debug, ops::Deref};

Expand Down Expand Up @@ -132,12 +132,7 @@ impl<'w> ComponentsRegistrator<'w> {
.unwrap_or_else(PoisonError::into_inner);
queued.components.keys().next().copied().map(|type_id| {
// SAFETY: the id just came from a valid iterator.
unsafe {
queued
.components
.shift_remove(&type_id)
.debug_checked_unwrap()
}
unsafe { queued.components.remove(&type_id).debug_checked_unwrap() }
})
} {
registrator.register(self);
Expand Down Expand Up @@ -193,7 +188,7 @@ impl<'w> ComponentsRegistrator<'w> {
.get_mut()
.unwrap_or_else(PoisonError::into_inner)
.components
.shift_remove(&type_id)
.remove(&type_id)
{
// If we are trying to register something that has already been queued, we respect the queue.
// Just like if we are trying to register something that already is, we respect the first registration.
Expand Down Expand Up @@ -329,7 +324,7 @@ impl<'w> ComponentsRegistrator<'w> {
.get_mut()
.unwrap_or_else(PoisonError::into_inner)
.components
.shift_remove(&type_id)
.remove(&type_id)
{
// If we are trying to register something that has already been queued, we respect the queue.
// Just like if we are trying to register something that already is, we respect the first registration.
Expand Down Expand Up @@ -391,7 +386,7 @@ impl QueuedRegistration {
/// Allows queuing components to be registered.
#[derive(Default)]
pub struct QueuedComponents {
pub(super) components: TypeIdMap<QueuedRegistration>,
pub(super) components: TypeIdHashMap<QueuedRegistration>,
pub(super) dynamic_registrations: Vec<QueuedRegistration>,
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/schedule/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::{
fmt::Debug,
};

use bevy_utils::TypeIdMap;
use bevy_utils::TypeIdHashMap;

use crate::schedule::InternedSystemSet;

Expand All @@ -28,7 +28,7 @@ pub(crate) enum DependencyKind {
pub(crate) struct Dependency {
pub(crate) kind: DependencyKind,
pub(crate) set: InternedSystemSet,
pub(crate) options: TypeIdMap<Box<dyn Any>>,
pub(crate) options: TypeIdHashMap<Box<dyn Any>>,
}

impl Dependency {
Expand Down
16 changes: 13 additions & 3 deletions crates/bevy_ecs/src/schedule/pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::{
};

use bevy_platform::{collections::HashSet, hash::FixedHasher};
use bevy_utils::TypeIdMap;
use bevy_utils::TypeIdHashMap;
use indexmap::IndexSet;

use super::{DiGraph, NodeId, ScheduleBuildError, ScheduleGraph};
Expand Down Expand Up @@ -127,7 +127,12 @@ pub(super) trait ScheduleBuildPassObj: Send + Sync + Debug {
dependency_flattening: &DiGraph<NodeId>,
dependencies_to_add: &mut Vec<(NodeId, NodeId)>,
);
fn add_dependency(&mut self, from: NodeId, to: NodeId, all_options: &TypeIdMap<Box<dyn Any>>);
fn add_dependency(
&mut self,
from: NodeId,
to: NodeId,
all_options: &TypeIdHashMap<Box<dyn Any>>,
);
}

impl<T: ScheduleBuildPass> ScheduleBuildPassObj for T {
Expand All @@ -149,7 +154,12 @@ impl<T: ScheduleBuildPass> ScheduleBuildPassObj for T {
let iter = self.collapse_set(set, systems, dependency_flattening);
dependencies_to_add.extend(iter);
}
fn add_dependency(&mut self, from: NodeId, to: NodeId, all_options: &TypeIdMap<Box<dyn Any>>) {
fn add_dependency(
&mut self,
from: NodeId,
to: NodeId,
all_options: &TypeIdHashMap<Box<dyn Any>>,
) {
let option = all_options
.get(&TypeId::of::<T::EdgeOptions>())
.and_then(|x| x.downcast_ref::<T::EdgeOptions>());
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/schedule/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use bevy_platform::{
collections::{HashMap, HashSet},
hash::FixedHasher,
};
use bevy_utils::{default, TypeIdMap};
use bevy_utils::{default, TypeIdHashMap};
use core::{
any::{Any, TypeId},
fmt::{Debug, Write},
Expand Down Expand Up @@ -285,7 +285,7 @@ pub enum Chain {
Unchained,
/// Systems are chained. `before -> after` ordering constraints
/// will be added between the successive elements.
Chained(TypeIdMap<Box<dyn Any>>),
Chained(TypeIdHashMap<Box<dyn Any>>),
}

impl Chain {
Expand Down
Loading