fix: don't expose &mut Components through ComponentsRegistrator

This commit is contained in:
Giacomo Stevanato 2025-07-18 11:36:15 +02:00
parent 877d278785
commit 3528800d2e
No known key found for this signature in database
2 changed files with 40 additions and 26 deletions

View File

@ -2,14 +2,13 @@ use alloc::{boxed::Box, vec::Vec};
use bevy_platform::sync::PoisonError; use bevy_platform::sync::PoisonError;
use bevy_utils::TypeIdMap; use bevy_utils::TypeIdMap;
use core::any::Any; use core::any::Any;
use core::ops::DerefMut;
use core::{any::TypeId, fmt::Debug, ops::Deref}; use core::{any::TypeId, fmt::Debug, ops::Deref};
use crate::query::DebugCheckedUnwrap as _;
use crate::{ use crate::{
component::{ component::{
Component, ComponentDescriptor, ComponentId, Components, RequiredComponents, StorageType, Component, ComponentDescriptor, ComponentId, Components, RequiredComponents, StorageType,
}, },
query::DebugCheckedUnwrap as _,
resource::Resource, resource::Resource,
}; };
@ -62,8 +61,8 @@ impl ComponentIds {
/// A [`Components`] wrapper that enables additional features, like registration. /// A [`Components`] wrapper that enables additional features, like registration.
pub struct ComponentsRegistrator<'w> { pub struct ComponentsRegistrator<'w> {
components: &'w mut Components, pub(super) components: &'w mut Components,
ids: &'w mut ComponentIds, pub(super) ids: &'w mut ComponentIds,
} }
impl Deref for ComponentsRegistrator<'_> { impl Deref for ComponentsRegistrator<'_> {
@ -74,12 +73,6 @@ impl Deref for ComponentsRegistrator<'_> {
} }
} }
impl DerefMut for ComponentsRegistrator<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.components
}
}
impl<'w> ComponentsRegistrator<'w> { impl<'w> ComponentsRegistrator<'w> {
/// Constructs a new [`ComponentsRegistrator`]. /// Constructs a new [`ComponentsRegistrator`].
/// ///
@ -223,10 +216,11 @@ impl<'w> ComponentsRegistrator<'w> {
) { ) {
// SAFETY: ensured by caller. // SAFETY: ensured by caller.
unsafe { unsafe {
self.register_component_inner(id, ComponentDescriptor::new::<T>()); self.components
.register_component_inner(id, ComponentDescriptor::new::<T>());
} }
let type_id = TypeId::of::<T>(); let type_id = TypeId::of::<T>();
let prev = self.indices.insert(type_id, id); let prev = self.components.indices.insert(type_id, id);
debug_assert!(prev.is_none()); debug_assert!(prev.is_none());
let mut required_components = RequiredComponents::default(); let mut required_components = RequiredComponents::default();
@ -272,7 +266,7 @@ impl<'w> ComponentsRegistrator<'w> {
let id = self.ids.next_mut(); let id = self.ids.next_mut();
// SAFETY: The id is fresh. // SAFETY: The id is fresh.
unsafe { unsafe {
self.register_component_inner(id, descriptor); self.components.register_component_inner(id, descriptor);
} }
id id
} }
@ -339,7 +333,8 @@ impl<'w> ComponentsRegistrator<'w> {
let id = self.ids.next_mut(); let id = self.ids.next_mut();
// SAFETY: The resource is not currently registered, the id is fresh, and the [`ComponentDescriptor`] matches the [`TypeId`] // SAFETY: The resource is not currently registered, the id is fresh, and the [`ComponentDescriptor`] matches the [`TypeId`]
unsafe { unsafe {
self.register_resource_unchecked(type_id, id, descriptor()); self.components
.register_resource_unchecked(type_id, id, descriptor());
} }
id id
} }
@ -363,10 +358,20 @@ impl<'w> ComponentsRegistrator<'w> {
let id = self.ids.next_mut(); let id = self.ids.next_mut();
// SAFETY: The id is fresh. // SAFETY: The id is fresh.
unsafe { unsafe {
self.register_component_inner(id, descriptor); self.components.register_component_inner(id, descriptor);
} }
id id
} }
/// Equivalent of `Components::any_queued_mut`
pub fn any_queued_mut(&mut self) -> bool {
self.components.any_queued_mut()
}
/// Equivalent of `Components::any_queued_mut`
pub fn num_queued_mut(&mut self) -> usize {
self.components.num_queued_mut()
}
} }
/// A queued component registration. /// A queued component registration.
@ -587,7 +592,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
self.register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| { self.register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| {
// SAFETY: Id uniqueness handled by caller. // SAFETY: Id uniqueness handled by caller.
unsafe { unsafe {
registrator.register_component_inner(id, descriptor); registrator
.components
.register_component_inner(id, descriptor);
} }
}) })
} }
@ -616,7 +623,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
// SAFETY: Id uniqueness handled by caller, and the type_id matches descriptor. // SAFETY: Id uniqueness handled by caller, and the type_id matches descriptor.
#[expect(unused_unsafe, reason = "More precise to specify.")] #[expect(unused_unsafe, reason = "More precise to specify.")]
unsafe { unsafe {
registrator.register_resource_unchecked(type_id, id, descriptor); registrator
.components
.register_resource_unchecked(type_id, id, descriptor);
} }
}, },
) )
@ -648,7 +657,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
// SAFETY: Id uniqueness handled by caller, and the type_id matches descriptor. // SAFETY: Id uniqueness handled by caller, and the type_id matches descriptor.
#[expect(unused_unsafe, reason = "More precise to specify.")] #[expect(unused_unsafe, reason = "More precise to specify.")]
unsafe { unsafe {
registrator.register_resource_unchecked(type_id, id, descriptor); registrator
.components
.register_resource_unchecked(type_id, id, descriptor);
} }
}, },
) )
@ -672,7 +683,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
self.register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| { self.register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| {
// SAFETY: Id uniqueness handled by caller. // SAFETY: Id uniqueness handled by caller.
unsafe { unsafe {
registrator.register_component_inner(id, descriptor); registrator
.components
.register_component_inner(id, descriptor);
} }
}) })
} }

View File

@ -253,13 +253,14 @@ impl<'w> ComponentsRegistrator<'w> {
// SAFETY: We just created the components. // SAFETY: We just created the components.
unsafe { unsafe {
self.register_required_components_manual_unchecked::<R>( self.components
requiree, .register_required_components_manual_unchecked::<R>(
required, requiree,
required_components, required,
constructor, required_components,
inheritance_depth, constructor,
); inheritance_depth,
);
} }
} }
} }