From 3528800d2eae9373705db213489bae5c285ec922 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Fri, 18 Jul 2025 11:36:15 +0200 Subject: [PATCH] fix: don't expose &mut Components through ComponentsRegistrator --- crates/bevy_ecs/src/component/register.rs | 51 ++++++++++++++--------- crates/bevy_ecs/src/component/required.rs | 15 +++---- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/crates/bevy_ecs/src/component/register.rs b/crates/bevy_ecs/src/component/register.rs index cb3ca7f544..fa22ebe8f6 100644 --- a/crates/bevy_ecs/src/component/register.rs +++ b/crates/bevy_ecs/src/component/register.rs @@ -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::()); + self.components + .register_component_inner(id, ComponentDescriptor::new::()); } let type_id = TypeId::of::(); - 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); } }) } diff --git a/crates/bevy_ecs/src/component/required.rs b/crates/bevy_ecs/src/component/required.rs index d46b6b61ce..5b32342334 100644 --- a/crates/bevy_ecs/src/component/required.rs +++ b/crates/bevy_ecs/src/component/required.rs @@ -253,13 +253,14 @@ impl<'w> ComponentsRegistrator<'w> { // SAFETY: We just created the components. unsafe { - self.register_required_components_manual_unchecked::( - requiree, - required, - required_components, - constructor, - inheritance_depth, - ); + self.components + .register_required_components_manual_unchecked::( + requiree, + required, + required_components, + constructor, + inheritance_depth, + ); } } }