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_utils::TypeIdMap;
use core::any::Any;
use core::ops::DerefMut;
use core::{any::TypeId, fmt::Debug, ops::Deref};
use crate::query::DebugCheckedUnwrap as _;
use crate::{
component::{
Component, ComponentDescriptor, ComponentId, Components, RequiredComponents, StorageType,
},
query::DebugCheckedUnwrap as _,
resource::Resource,
};
@ -62,8 +61,8 @@ impl ComponentIds {
/// A [`Components`] wrapper that enables additional features, like registration.
pub struct ComponentsRegistrator<'w> {
components: &'w mut Components,
ids: &'w mut ComponentIds,
pub(super) components: &'w mut Components,
pub(super) ids: &'w mut ComponentIds,
}
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> {
/// Constructs a new [`ComponentsRegistrator`].
///
@ -223,10 +216,11 @@ impl<'w> ComponentsRegistrator<'w> {
) {
// SAFETY: ensured by caller.
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 prev = self.indices.insert(type_id, id);
let prev = self.components.indices.insert(type_id, id);
debug_assert!(prev.is_none());
let mut required_components = RequiredComponents::default();
@ -272,7 +266,7 @@ impl<'w> ComponentsRegistrator<'w> {
let id = self.ids.next_mut();
// SAFETY: The id is fresh.
unsafe {
self.register_component_inner(id, descriptor);
self.components.register_component_inner(id, descriptor);
}
id
}
@ -339,7 +333,8 @@ impl<'w> ComponentsRegistrator<'w> {
let id = self.ids.next_mut();
// SAFETY: The resource is not currently registered, the id is fresh, and the [`ComponentDescriptor`] matches the [`TypeId`]
unsafe {
self.register_resource_unchecked(type_id, id, descriptor());
self.components
.register_resource_unchecked(type_id, id, descriptor());
}
id
}
@ -363,10 +358,20 @@ impl<'w> ComponentsRegistrator<'w> {
let id = self.ids.next_mut();
// SAFETY: The id is fresh.
unsafe {
self.register_component_inner(id, descriptor);
self.components.register_component_inner(id, descriptor);
}
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.
@ -587,7 +592,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
self.register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| {
// SAFETY: Id uniqueness handled by caller.
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.
#[expect(unused_unsafe, reason = "More precise to specify.")]
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.
#[expect(unused_unsafe, reason = "More precise to specify.")]
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| {
// SAFETY: Id uniqueness handled by caller.
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.
unsafe {
self.register_required_components_manual_unchecked::<R>(
requiree,
required,
required_components,
constructor,
inheritance_depth,
);
self.components
.register_required_components_manual_unchecked::<R>(
requiree,
required,
required_components,
constructor,
inheritance_depth,
);
}
}
}