Fix CI issues

This commit is contained in:
Giacomo Stevanato 2025-07-13 16:22:30 +02:00
parent 87bd81b8ab
commit 18c4ca405e
No known key found for this signature in database
3 changed files with 41 additions and 29 deletions

View File

@ -1,5 +1,8 @@
use alloc::{boxed::Box, vec, vec::Vec}; use alloc::{boxed::Box, vec, vec::Vec};
use bevy_platform::collections::{HashMap, HashSet}; use bevy_platform::{
collections::{HashMap, HashSet},
hash::FixedHasher,
};
use bevy_ptr::OwningPtr; use bevy_ptr::OwningPtr;
use bevy_utils::TypeIdMap; use bevy_utils::TypeIdMap;
use core::{any::TypeId, ptr::NonNull}; use core::{any::TypeId, ptr::NonNull};
@ -89,7 +92,10 @@ impl BundleInfo {
mut component_ids: Vec<ComponentId>, mut component_ids: Vec<ComponentId>,
id: BundleId, id: BundleId,
) -> BundleInfo { ) -> BundleInfo {
let explicit_component_ids = component_ids.iter().copied().collect::<IndexSet<_>>(); let explicit_component_ids = component_ids
.iter()
.copied()
.collect::<IndexSet<_, FixedHasher>>();
// check for duplicates // check for duplicates
if explicit_component_ids.len() != component_ids.len() { if explicit_component_ids.len() != component_ids.len() {
@ -113,7 +119,7 @@ impl BundleInfo {
panic!("Bundle {bundle_type_name} has duplicate components: {names:?}"); panic!("Bundle {bundle_type_name} has duplicate components: {names:?}");
} }
let mut depth_first_components = IndexMap::new(); let mut depth_first_components = IndexMap::<_, _, FixedHasher>::default();
for &component_id in &component_ids { for &component_id in &component_ids {
// SAFETY: caller has verified that all ids are valid // SAFETY: caller has verified that all ids are valid
let info = unsafe { components.get_info_unchecked(component_id) }; let info = unsafe { components.get_info_unchecked(component_id) };
@ -155,7 +161,7 @@ impl BundleInfo {
self.id self.id
} }
/// Returns the length of the explicit components part of the [contributed_components](Self::contributed_components) list. /// Returns the length of the explicit components part of the [`contributed_components`](Self::contributed_components) list.
pub(super) fn explicit_components_len(&self) -> usize { pub(super) fn explicit_components_len(&self) -> usize {
self.contributed_components.len() - self.required_component_constructors.len() self.contributed_components.len() - self.required_component_constructors.len()
} }

View File

@ -1,5 +1,5 @@
use alloc::{borrow::Cow, vec::Vec}; use alloc::{borrow::Cow, vec::Vec};
use bevy_platform::sync::PoisonError; use bevy_platform::{hash::FixedHasher, sync::PoisonError};
use bevy_ptr::OwningPtr; use bevy_ptr::OwningPtr;
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
@ -34,7 +34,7 @@ pub struct ComponentInfo {
/// The set of components that require this components. /// The set of components that require this components.
/// Invariant: this is stored in a depth-first order, that is components are stored after the components /// Invariant: this is stored in a depth-first order, that is components are stored after the components
/// that they depend on. /// that they depend on.
pub(super) required_by: IndexSet<ComponentId>, pub(super) required_by: IndexSet<ComponentId, FixedHasher>,
} }
impl ComponentInfo { impl ComponentInfo {
@ -527,7 +527,10 @@ impl Components {
} }
#[inline] #[inline]
pub(crate) fn get_required_by(&self, id: ComponentId) -> Option<&IndexSet<ComponentId>> { pub(crate) fn get_required_by(
&self,
id: ComponentId,
) -> Option<&IndexSet<ComponentId, FixedHasher>> {
self.components self.components
.get(id.0) .get(id.0)
.and_then(|info| info.as_ref().map(|info| &info.required_by)) .and_then(|info| info.as_ref().map(|info| &info.required_by))
@ -537,7 +540,7 @@ impl Components {
pub(crate) fn get_required_by_mut( pub(crate) fn get_required_by_mut(
&mut self, &mut self,
id: ComponentId, id: ComponentId,
) -> Option<&mut IndexSet<ComponentId>> { ) -> Option<&mut IndexSet<ComponentId, FixedHasher>> {
self.components self.components
.get_mut(id.0) .get_mut(id.0)
.and_then(|info| info.as_mut().map(|info| &mut info.required_by)) .and_then(|info| info.as_mut().map(|info| &mut info.required_by))

View File

@ -1,5 +1,5 @@
use alloc::{format, vec::Vec}; use alloc::{format, vec::Vec};
use bevy_platform::sync::Arc; use bevy_platform::{hash::FixedHasher, sync::Arc};
use bevy_ptr::OwningPtr; use bevy_ptr::OwningPtr;
use core::fmt::Debug; use core::fmt::Debug;
use indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
@ -119,7 +119,7 @@ pub struct RequiredComponents {
/// ///
/// # Safety /// # Safety
/// The [`RequiredComponent`] instance associated to each ID must be valid for its component. /// The [`RequiredComponent`] instance associated to each ID must be valid for its component.
pub(crate) direct: IndexMap<ComponentId, RequiredComponent>, pub(crate) direct: IndexMap<ComponentId, RequiredComponent, FixedHasher>,
/// All the components that are required (i.e. including inherited ones), in depth-first order. Most importantly, /// All the components that are required (i.e. including inherited ones), in depth-first order. Most importantly,
/// components in this list always appear after all the components that they require. /// components in this list always appear after all the components that they require.
/// ///
@ -128,7 +128,7 @@ pub struct RequiredComponents {
/// ///
/// # Safety /// # Safety
/// The [`RequiredComponent`] instance associated to each ID must be valid for its component. /// The [`RequiredComponent`] instance associated to each ID must be valid for its component.
pub(crate) all: IndexMap<ComponentId, RequiredComponent>, pub(crate) all: IndexMap<ComponentId, RequiredComponent, FixedHasher>,
} }
impl Debug for RequiredComponents { impl Debug for RequiredComponents {
@ -149,7 +149,7 @@ impl RequiredComponents {
/// ///
/// # Safety /// # Safety
/// ///
/// - all other components in this [`RequiredComponents`] instance must have been registrated in `components`. /// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.
pub unsafe fn register<C: Component>( pub unsafe fn register<C: Component>(
&mut self, &mut self,
components: &mut ComponentsRegistrator<'_>, components: &mut ComponentsRegistrator<'_>,
@ -171,7 +171,7 @@ impl RequiredComponents {
/// # Safety /// # Safety
/// ///
/// - `component_id` must be a valid component in `components` for the type `C`; /// - `component_id` must be a valid component in `components` for the type `C`;
/// - all other components in this [`RequiredComponents`] instance must have been registrated in `components`. /// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.
pub unsafe fn register_by_id<C: Component>( pub unsafe fn register_by_id<C: Component>(
&mut self, &mut self,
component_id: ComponentId, component_id: ComponentId,
@ -198,7 +198,7 @@ impl RequiredComponents {
/// # Safety /// # Safety
/// ///
/// - `component_id` must be a valid component in `components`; /// - `component_id` must be a valid component in `components`;
/// - all other components in this [`RequiredComponents`] instance must have been registrated in `components`; /// - all other components in `self` must have been registered in `components`;
/// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the /// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the
/// component with ID `component_id`. /// component with ID `component_id`.
pub unsafe fn register_dynamic_with( pub unsafe fn register_dynamic_with(
@ -219,14 +219,17 @@ impl RequiredComponents {
entry.insert(required_component.clone()); entry.insert(required_component.clone());
// Register inherited required components. // Register inherited required components.
// SAFETY:
// - the caller guarantees all components that were in `self` have been registered in `components`;
// - `component_id` has just been added, but is also guaranteed by the called to be valid in `components`.
unsafe { unsafe {
Self::register_inherited_required_components_unchecked( Self::register_inherited_required_components_unchecked(
&mut self.all, &mut self.all,
component_id, component_id,
required_component, required_component,
components, components,
) );
}; }
true true
} }
@ -235,7 +238,7 @@ impl RequiredComponents {
/// ///
/// # Safety /// # Safety
/// ///
/// - all components in this [`RequiredComponents`] instance must have been registrated in `components`. /// - all components in `self` must have been registered in `components`.
unsafe fn rebuild_inherited_required_components(&mut self, components: &Components) { unsafe fn rebuild_inherited_required_components(&mut self, components: &Components) {
// Clear `all`, we are re-initializing it. // Clear `all`, we are re-initializing it.
self.all.clear(); self.all.clear();
@ -252,7 +255,7 @@ impl RequiredComponents {
required_id, required_id,
required_component.clone(), required_component.clone(),
components, components,
) );
} }
} }
} }
@ -265,7 +268,7 @@ impl RequiredComponents {
/// - `required_id` must have been registered in `components`; /// - `required_id` must have been registered in `components`;
/// - `required_component` must hold a valid constructor for the component with id `required_id`. /// - `required_component` must hold a valid constructor for the component with id `required_id`.
unsafe fn register_inherited_required_components_unchecked( unsafe fn register_inherited_required_components_unchecked(
all: &mut IndexMap<ComponentId, RequiredComponent>, all: &mut IndexMap<ComponentId, RequiredComponent, FixedHasher>,
required_id: ComponentId, required_id: ComponentId,
required_component: RequiredComponent, required_component: RequiredComponent,
components: &Components, components: &Components,
@ -281,7 +284,7 @@ impl RequiredComponents {
for (&inherited_id, inherited_required) in &info.required_components().all { for (&inherited_id, inherited_required) in &info.required_components().all {
// This is an inherited required component: insert it only if not already present. // This is an inherited required component: insert it only if not already present.
// By the invariants of `RequiredComponents`, `info.required_components().all` holds the required // By the invariants of `RequiredComponents`, `info.required_components().all` holds the required
// components in a depth-first order, and this makes us store teh components in `self.all` also // components in a depth-first order, and this makes us store the components in `self.all` also
// in depth-first order, as long as we don't overwrite existing ones. // in depth-first order, as long as we don't overwrite existing ones.
// //
// SAFETY: // SAFETY:
@ -407,7 +410,7 @@ impl Components {
let new_required_components = required_components.all[old_required_count..] let new_required_components = required_components.all[old_required_count..]
.keys() .keys()
.copied() .copied()
.collect::<IndexSet<_>>(); .collect::<IndexSet<_, FixedHasher>>();
// Get all the new requiree components, i.e. `requiree` and all the components that `requiree` is required by. // Get all the new requiree components, i.e. `requiree` and all the components that `requiree` is required by.
// SAFETY: The caller ensures that the `requiree` is valid. // SAFETY: The caller ensures that the `requiree` is valid.
@ -426,7 +429,7 @@ impl Components {
for &indirect_requiree in &new_requiree_components { for &indirect_requiree in &new_requiree_components {
// Extract the required components to avoid conflicting borrows. Remember to put this back before continuing! // Extract the required components to avoid conflicting borrows. Remember to put this back before continuing!
// SAFETY: `indirect_requiree` comes from `self`, so it must be valid. // SAFETY: `indirect_requiree` comes from `self`, so it must be valid.
let mut required_components = std::mem::take(unsafe { let mut required_components = core::mem::take(unsafe {
self.get_required_components_mut(indirect_requiree) self.get_required_components_mut(indirect_requiree)
.debug_checked_unwrap() .debug_checked_unwrap()
}); });
@ -474,7 +477,7 @@ impl Components {
) { ) {
// Extract the required components to avoid conflicting borrows. Remember to put this back before returning! // Extract the required components to avoid conflicting borrows. Remember to put this back before returning!
// SAFETY: The caller ensures that the `requiree` is valid. // SAFETY: The caller ensures that the `requiree` is valid.
let mut required_components = std::mem::take(unsafe { let mut required_components = core::mem::take(unsafe {
self.get_required_components_mut(requiree) self.get_required_components_mut(requiree)
.debug_checked_unwrap() .debug_checked_unwrap()
}); });
@ -537,7 +540,7 @@ pub(super) fn enforce_no_required_components_recursion(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::string::{String, ToString}; use alloc::string::{String, ToString};
use crate::{ use crate::{
bundle::Bundle, bundle::Bundle,
@ -1251,14 +1254,14 @@ mod tests {
#[test] #[test]
fn regression_19333() { fn regression_19333() {
#[derive(Component)] #[derive(Component)]
struct X(bool); struct X(usize);
#[derive(Default, Component)] #[derive(Default, Component)]
#[require(X(false))] #[require(X(0))]
struct Base; struct Base;
#[derive(Default, Component)] #[derive(Default, Component)]
#[require(X(true), Base)] #[require(X(1), Base)]
struct A; struct A;
#[derive(Default, Component)] #[derive(Default, Component)]
@ -1271,7 +1274,7 @@ mod tests {
let mut w = World::new(); let mut w = World::new();
assert_eq!(w.spawn(B).get::<X>().unwrap().0, true); assert_eq!(w.spawn(B).get::<X>().unwrap().0, 1);
assert_eq!(w.spawn(C).get::<X>().unwrap().0, true); assert_eq!(w.spawn(C).get::<X>().unwrap().0, 1);
} }
} }