Skip to content
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
6 changes: 3 additions & 3 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,10 +748,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_platform::collections::hash_map::Entry::Occupied(occupied_entry) => {
bevy_utils::TypeIdMapEntry::Occupied(occupied_entry) => {
&mut **occupied_entry.into_mut()
}
bevy_platform::collections::hash_map::Entry::Vacant(vacant_entry) => {
bevy_utils::TypeIdMapEntry::Vacant(vacant_entry) => {
&mut **vacant_entry.insert(func())
}
},
Expand Down Expand Up @@ -781,7 +781,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
7 changes: 3 additions & 4 deletions crates/bevy_app/src/plugin_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
use bevy_platform::collections::hash_map::Entry;
use bevy_utils::TypeIdMap;
use bevy_utils::{TypeIdMap, TypeIdMapEntry as Entry};
use core::any::TypeId;
use log::{debug, warn};

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

Expand Down Expand Up @@ -517,7 +516,7 @@ impl PluginGroupBuilder {
#[track_caller]
pub fn finish(mut self, app: &mut App) {
for ty in &self.order {
if let Some(entry) = self.plugins.remove(ty)
if let Some(entry) = self.plugins.shift_remove(ty)
&& entry.enabled
{
debug!("added plugin: {}", entry.plugin.name());
Expand Down
8 changes: 4 additions & 4 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;
use bevy_utils::{TypeIdMap, TypeIdMapEntry};
use core::{
any::{type_name, TypeId},
task::Waker,
Expand Down Expand Up @@ -222,7 +222,7 @@ impl AssetInfos {
.ok_or(GetOrCreateHandleInternalError::HandleMissingButTypeIdNotSpecified)?;

match handles.entry(type_id) {
Entry::Occupied(entry) => {
TypeIdMapEntry::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
Entry::Vacant(entry) => {
TypeIdMapEntry::Vacant(entry) => {
let should_load = match loading_mode {
HandleLoadingMode::NotLoading => false,
HandleLoadingMode::Request | HandleLoadingMode::Force => true,
Expand Down Expand Up @@ -746,7 +746,7 @@ impl AssetInfos {
}

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

if map.is_empty() {
path_to_id.remove(path);
Expand Down
11 changes: 8 additions & 3 deletions crates/bevy_ecs/src/component/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ 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.remove(&type_id).debug_checked_unwrap() }
unsafe {
queued
.components
.shift_remove(&type_id)
.debug_checked_unwrap()
}
})
} {
registrator.register(self);
Expand Down Expand Up @@ -189,7 +194,7 @@ impl<'w> ComponentsRegistrator<'w> {
.get_mut()
.unwrap_or_else(PoisonError::into_inner)
.components
.remove(&type_id)
.shift_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 @@ -338,7 +343,7 @@ impl<'w> ComponentsRegistrator<'w> {
.get_mut()
.unwrap_or_else(PoisonError::into_inner)
.components
.remove(&type_id)
.shift_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
26 changes: 11 additions & 15 deletions crates/bevy_reflect/src/type_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,22 +292,18 @@ impl TypeRegistry {
type_id: TypeId,
get_registration: impl FnOnce() -> TypeRegistration,
) -> bool {
use bevy_platform::collections::hash_map::Entry;

match self.registrations.entry(type_id) {
Entry::Occupied(_) => false,
Entry::Vacant(entry) => {
let registration = get_registration();
Self::update_registration_indices(
&registration,
&mut self.short_path_to_id,
&mut self.type_path_to_id,
&mut self.ambiguous_names,
);
entry.insert(registration);
true
}
if self.registrations.contains_key(&type_id) {
return false;
}
let registration = get_registration();
Self::update_registration_indices(
&registration,
&mut self.short_path_to_id,
&mut self.type_path_to_id,
&mut self.ambiguous_names,
);
self.registrations.insert(type_id, registration);
true
}

/// Internal method to register additional lookups for a given [`TypeRegistration`].
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_reflect/src/utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl<T: TypedProperty> GenericTypeCell<T> {

write_lock
.entry(type_id)
.insert({
.insert_entry({
// We leak here in order to obtain a `&'static` reference.
// Otherwise, we won't be able to return a reference due to the `RwLock`.
// This should be okay, though, since we expect it to remain statically
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/src/batching/gpu_preprocessing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ where
BatchedInstanceBuffers {
current_input_buffer: InstanceInputUniformBuffer::new(),
previous_input_buffer: PreviousInstanceInputUniformBuffer::new(),
phase_instance_buffers: HashMap::default(),
phase_instance_buffers: TypeIdMap::default(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ bevy_platform = { path = "../bevy_platform", version = "0.19.0-dev", default-fea
disqualified = { version = "1.0", default-features = false }
thread_local = { version = "1.0", optional = true }
async-channel = { version = "2.3.0", optional = true }
indexmap = { version = "2", default-features = false }

[dev-dependencies]
static_assertions = "1.1.0"
Expand Down
20 changes: 12 additions & 8 deletions crates/bevy_utils/src/map.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use core::{any::TypeId, hash::Hash};

use bevy_platform::{
collections::{hash_map::Entry, HashMap},
collections::HashMap,
hash::{Hashed, NoOpHash, PassHash},
};
use indexmap::map::IndexMap;

/// The [`Entry`][indexmap::map::Entry] type for [`TypeIdMap`].
pub use indexmap::map::Entry as TypeIdMapEntry;

/// A [`HashMap`] pre-configured to use [`Hashed`] keys and [`PassHash`] passthrough hashing.
/// Iteration order only depends on the order of insertions and deletions.
Expand Down Expand Up @@ -34,14 +38,14 @@ impl<K: Hash + Eq + PartialEq + Clone, V> PreHashMapExt<K, V> for PreHashMap<K,
}
}

/// A specialized hashmap type with Key of [`TypeId`]
/// A specialized map type with Key of [`TypeId`]
/// Iteration order only depends on the order of insertions and deletions.
pub type TypeIdMap<V> = HashMap<TypeId, V, NoOpHash>;
pub type TypeIdMap<V> = IndexMap<TypeId, V, NoOpHash>;

/// Extension trait to make use of [`TypeIdMap`] more ergonomic.
///
/// Each function on this trait is a trivial wrapper for a function
/// on [`HashMap`], replacing a `TypeId` key with a
/// on [`IndexMap`], replacing a `TypeId` key with a
/// generic parameter `T`.
///
/// # Examples
Expand Down Expand Up @@ -80,7 +84,7 @@ pub trait TypeIdMapExt<V> {
fn remove_type<T: ?Sized + 'static>(&mut self) -> Option<V>;

/// Gets the type `T`'s entry in the map for in-place manipulation.
fn entry_type<T: ?Sized + 'static>(&mut self) -> Entry<'_, TypeId, V, NoOpHash>;
fn entry_type<T: ?Sized + 'static>(&mut self) -> TypeIdMapEntry<'_, TypeId, V>;
}

impl<V> TypeIdMapExt<V> for TypeIdMap<V> {
Expand All @@ -101,11 +105,11 @@ impl<V> TypeIdMapExt<V> for TypeIdMap<V> {

#[inline]
fn remove_type<T: ?Sized + 'static>(&mut self) -> Option<V> {
self.remove(&TypeId::of::<T>())
self.shift_remove(&TypeId::of::<T>())
}

#[inline]
fn entry_type<T: ?Sized + 'static>(&mut self) -> Entry<'_, TypeId, V, NoOpHash> {
fn entry_type<T: ?Sized + 'static>(&mut self) -> TypeIdMapEntry<'_, TypeId, V> {
self.entry(TypeId::of::<T>())
}
}
Expand Down Expand Up @@ -152,4 +156,4 @@ mod tests {
);
}
}
}
}