Path: blob/main/crates/bevy_ecs/src/component/required.rs
6600 views
use alloc::{format, vec::Vec};1use bevy_platform::{hash::FixedHasher, sync::Arc};2use bevy_ptr::OwningPtr;3use core::fmt::Debug;4use indexmap::{IndexMap, IndexSet};5use thiserror::Error;67use crate::{8bundle::BundleInfo,9change_detection::MaybeLocation,10component::{Component, ComponentId, Components, ComponentsRegistrator, Tick},11entity::Entity,12query::DebugCheckedUnwrap as _,13storage::{SparseSets, Table, TableRow},14};1516/// Metadata associated with a required component. See [`Component`] for details.17#[derive(Clone)]18pub struct RequiredComponent {19/// The constructor used for the required component.20pub constructor: RequiredComponentConstructor,21}2223/// A Required Component constructor. See [`Component`] for details.24#[derive(Clone)]25pub struct RequiredComponentConstructor(26// Note: this function makes `unsafe` assumptions, so it cannot be public.27Arc<dyn Fn(&mut Table, &mut SparseSets, Tick, TableRow, Entity, MaybeLocation)>,28);2930impl RequiredComponentConstructor {31/// Creates a new instance of `RequiredComponentConstructor` for the given type32///33/// # Safety34///35/// - `component_id` must be a valid component for type `C`.36pub unsafe fn new<C: Component>(component_id: ComponentId, constructor: fn() -> C) -> Self {37RequiredComponentConstructor({38// `portable-atomic-util` `Arc` is not able to coerce an unsized39// type like `std::sync::Arc` can. Creating a `Box` first does the40// coercion.41//42// This would be resolved by https://github.com/rust-lang/rust/issues/1234304344#[cfg(not(target_has_atomic = "ptr"))]45use alloc::boxed::Box;4647type Constructor = dyn for<'a, 'b> Fn(48&'a mut Table,49&'b mut SparseSets,50Tick,51TableRow,52Entity,53MaybeLocation,54);5556#[cfg(not(target_has_atomic = "ptr"))]57type Intermediate<T> = Box<T>;5859#[cfg(target_has_atomic = "ptr")]60type Intermediate<T> = Arc<T>;6162let boxed: Intermediate<Constructor> = Intermediate::new(63move |table, sparse_sets, change_tick, table_row, entity, caller| {64OwningPtr::make(constructor(), |ptr| {65// SAFETY: This will only be called in the context of `BundleInfo::write_components`, which will66// pass in a valid table_row and entity requiring a C constructor67// C::STORAGE_TYPE is the storage type associated with `component_id` / `C`68// `ptr` points to valid `C` data, which matches the type associated with `component_id`69unsafe {70BundleInfo::initialize_required_component(71table,72sparse_sets,73change_tick,74table_row,75entity,76component_id,77C::STORAGE_TYPE,78ptr,79caller,80);81}82});83},84);8586Arc::from(boxed)87})88}8990/// # Safety91/// This is intended to only be called in the context of [`BundleInfo::write_components`] to initialized required components.92/// Calling it _anywhere else_ should be considered unsafe.93///94/// `table_row` and `entity` must correspond to a valid entity that currently needs a component initialized via the constructor stored95/// on this [`RequiredComponentConstructor`]. The stored constructor must correspond to a component on `entity` that needs initialization.96/// `table` and `sparse_sets` must correspond to storages on a world where `entity` needs this required component initialized.97///98/// Again, don't call this anywhere but [`BundleInfo::write_components`].99pub(crate) unsafe fn initialize(100&self,101table: &mut Table,102sparse_sets: &mut SparseSets,103change_tick: Tick,104table_row: TableRow,105entity: Entity,106caller: MaybeLocation,107) {108(self.0)(table, sparse_sets, change_tick, table_row, entity, caller);109}110}111112/// The collection of metadata for components that are required for a given component.113///114/// For more information, see the "Required Components" section of [`Component`].115#[derive(Default, Clone)]116pub struct RequiredComponents {117/// The components that are directly required (i.e. excluding inherited ones), in the order of their precedence.118///119/// # Safety120/// The [`RequiredComponent`] instance associated to each ID must be valid for its component.121pub(crate) direct: IndexMap<ComponentId, RequiredComponent, FixedHasher>,122/// All the components that are required (i.e. including inherited ones), in depth-first order. Most importantly,123/// components in this list always appear after all the components that they require.124///125/// Note that the direct components are not necessarily at the end of this list, for example if A and C are directly126/// requires, and A requires B requires C, then `all` will hold [C, B, A].127///128/// # Safety129/// The [`RequiredComponent`] instance associated to each ID must be valid for its component.130pub(crate) all: IndexMap<ComponentId, RequiredComponent, FixedHasher>,131}132133impl Debug for RequiredComponents {134fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {135f.debug_struct("RequiredComponents")136.field("direct", &self.direct.keys())137.field("all", &self.all.keys())138.finish()139}140}141142impl RequiredComponents {143/// Registers the [`Component`] `C` as an explicitly required component.144///145/// If the component was not already registered as an explicit required component then it is added146/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.147///148/// # Safety149///150/// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.151unsafe fn register<C: Component>(152&mut self,153components: &mut ComponentsRegistrator<'_>,154constructor: fn() -> C,155) {156let id = components.register_component::<C>();157// SAFETY:158// - `id` was just registered in `components`;159// - the caller guarantees all other components were registered in `components`.160unsafe { self.register_by_id::<C>(id, components, constructor) };161}162163/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.164///165/// If the component was not already registered as an explicit required component then it is added166/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.167///168/// # Safety169///170/// - `component_id` must be a valid component in `components` for the type `C`;171/// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.172unsafe fn register_by_id<C: Component>(173&mut self,174component_id: ComponentId,175components: &Components,176constructor: fn() -> C,177) {178// SAFETY: the caller guarantees that `component_id` is valid for the type `C`.179let constructor =180|| unsafe { RequiredComponentConstructor::new(component_id, constructor) };181182// SAFETY:183// - the caller guarantees that `component_id` is valid in `components`184// - the caller guarantees all other components were registered in `components`;185// - constructor is guaranteed to create a valid constructor for the component with id `component_id`.186unsafe { self.register_dynamic_with(component_id, components, constructor) };187}188189/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.190///191/// If the component was not already registered as an explicit required component then it is added192/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.193///194/// # Safety195///196/// - `component_id` must be a valid component in `components`;197/// - all other components in `self` must have been registered in `components`;198/// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the199/// component with ID `component_id`.200unsafe fn register_dynamic_with(201&mut self,202component_id: ComponentId,203components: &Components,204constructor: impl FnOnce() -> RequiredComponentConstructor,205) {206// If already registered as a direct required component then bail.207let entry = match self.direct.entry(component_id) {208indexmap::map::Entry::Vacant(entry) => entry,209indexmap::map::Entry::Occupied(_) =>210panic!("Error while registering required component {component_id:?}: already directly required"),211};212213// Insert into `direct`.214let constructor = constructor();215let required_component = RequiredComponent { constructor };216entry.insert(required_component.clone());217218// Register inherited required components.219// SAFETY:220// - the caller guarantees all components that were in `self` have been registered in `components`;221// - `component_id` has just been added, but is also guaranteed by the called to be valid in `components`.222unsafe {223Self::register_inherited_required_components_unchecked(224&mut self.all,225component_id,226required_component,227components,228);229}230}231232/// Rebuild the `all` list233///234/// # Safety235///236/// - all components in `self` must have been registered in `components`.237unsafe fn rebuild_inherited_required_components(&mut self, components: &Components) {238// Clear `all`, we are re-initializing it.239self.all.clear();240241// Register all inherited components as if we just registered all components in `direct` one-by-one.242for (&required_id, required_component) in &self.direct {243// SAFETY:244// - the caller guarantees that all components in this instance have been registered in `components`,245// meaning both `all` and `required_id` have been registered in `components`;246// - `required_component` was associated to `required_id`, so it must hold a constructor valid for it.247unsafe {248Self::register_inherited_required_components_unchecked(249&mut self.all,250required_id,251required_component.clone(),252components,253);254}255}256}257258/// Registers all the inherited required components from `required_id`.259///260/// # Safety261///262/// - all components in `all` must have been registered in `components`;263/// - `required_id` must have been registered in `components`;264/// - `required_component` must hold a valid constructor for the component with id `required_id`.265unsafe fn register_inherited_required_components_unchecked(266all: &mut IndexMap<ComponentId, RequiredComponent, FixedHasher>,267required_id: ComponentId,268required_component: RequiredComponent,269components: &Components,270) {271// SAFETY: the caller guarantees that `required_id` is valid in `components`.272let info = unsafe { components.get_info(required_id).debug_checked_unwrap() };273274// Now we need to "recursively" register the275// Small optimization: if the current required component was already required recursively276// by an earlier direct required component then all its inherited components have all already277// been inserted, so let's not try to reinsert them.278if !all.contains_key(&required_id) {279for (&inherited_id, inherited_required) in &info.required_components().all {280// This is an inherited required component: insert it only if not already present.281// By the invariants of `RequiredComponents`, `info.required_components().all` holds the required282// components in a depth-first order, and this makes us store the components in `self.all` also283// in depth-first order, as long as we don't overwrite existing ones.284//285// SAFETY:286// `inherited_required` was associated to `inherited_id`, so it must have been valid for its component.287all.entry(inherited_id)288.or_insert_with(|| inherited_required.clone());289}290}291292// For direct required components:293// - insert them after inherited components to follow the depth-first order;294// - insert them unconditionally in order to make their constructor the one that's used.295// Note that `insert` does not change the order of components, meaning `component_id` will still appear296// before any other component that requires it.297//298// SAFETY: the caller guaranees that `required_component` is valid for the component with ID `required_id`.299all.insert(required_id, required_component);300}301302/// Iterates the ids of all required components. This includes recursive required components.303pub fn iter_ids(&self) -> impl Iterator<Item = ComponentId> + '_ {304self.all.keys().copied()305}306}307308impl Components {309/// Registers the components in `required_components` as required by `requiree`.310///311/// # Safety312///313/// - `requiree` must have been registered in `self`314/// - all components in `required_components` must have been registered in `self`;315/// - this is called with `requiree` before being called on any component requiring `requiree`.316pub(crate) unsafe fn register_required_by(317&mut self,318requiree: ComponentId,319required_components: &RequiredComponents,320) {321for &required in required_components.all.keys() {322// SAFETY: the caller guarantees that all components in `required_components` have been registered in `self`.323let required_by = unsafe { self.get_required_by_mut(required).debug_checked_unwrap() };324// This preserves the invariant of `required_by` because:325// - components requiring `required` and required by `requiree` are already initialized at this point326// and hence registered in `required_by` before `requiree`;327// - components requiring `requiree` cannot exist yet, as this is called on `requiree` before them.328required_by.insert(requiree);329}330}331332/// Registers the given component `R` and [required components] inherited from it as required by `T`.333///334/// When `T` is added to an entity, `R` will also be added if it was not already provided.335/// The given `constructor` will be used for the creation of `R`.336///337/// [required components]: Component#required-components338///339/// # Safety340///341/// - the given component IDs `required` and `requiree` must be valid in `self`;342/// - the given component ID `required` must be valid for the component type `R`.343///344///345/// # Errors346///347/// Returns a [`RequiredComponentsError`] if either of these are true:348/// - the `required` component is already a *directly* required component for the `requiree`; indirect349/// requirements through other components are allowed. In those cases, the more specific350/// registration will be used.351/// - the `requiree` component is already a (possibly indirect) required component for the `required` component.352pub(crate) unsafe fn register_required_components<R: Component>(353&mut self,354requiree: ComponentId,355required: ComponentId,356constructor: fn() -> R,357) -> Result<(), RequiredComponentsError> {358// First step: validate inputs and return errors.359360// SAFETY: The caller ensures that the `required` is valid.361let required_required_components = unsafe {362self.get_required_components(required)363.debug_checked_unwrap()364};365366// Cannot create cyclic requirements.367if required_required_components.all.contains_key(&requiree) {368return Err(RequiredComponentsError::CyclicRequirement(369requiree, required,370));371}372373// SAFETY: The caller ensures that the `requiree` is valid.374let required_components = unsafe {375self.get_required_components_mut(requiree)376.debug_checked_unwrap()377};378379// Cannot directly require the same component twice.380if required_components.direct.contains_key(&required) {381return Err(RequiredComponentsError::DuplicateRegistration(382requiree, required,383));384}385386// Second step: register the single requirement requiree->required387388// Store the old count of (all) required components. This will help determine which ones are new.389let old_required_count = required_components.all.len();390391// SAFETY: the caller guarantees that `requiree` is valid in `self`.392self.required_components_scope(requiree, |this, required_components| {393// SAFETY: the caller guarantees that `required` is valid for type `R` in `self`394unsafe { required_components.register_by_id(required, this, constructor) };395});396397// Third step: update the required components and required_by of all the indirect requirements/requirees.398399// Borrow again otherwise it conflicts with the `self.required_components_scope` call.400// SAFETY: The caller ensures that the `requiree` is valid.401let required_components = unsafe {402self.get_required_components_mut(requiree)403.debug_checked_unwrap()404};405406// Optimization: get all the new required components, i.e. those that were appended.407// Other components that might be inherited when requiring `required` can be safely ignored because408// any component requiring `requiree` will already transitively require them.409// Note: the only small exception is for `required` itself, for which we cannot ignore the value of the410// constructor. But for simplicity we will rebuild any `RequiredComponents`411let new_required_components = required_components.all[old_required_count..]412.keys()413.copied()414.collect::<Vec<_>>();415416// Get all the new requiree components, i.e. `requiree` and all the components that `requiree` is required by.417// SAFETY: The caller ensures that the `requiree` is valid.418let requiree_required_by = unsafe { self.get_required_by(requiree).debug_checked_unwrap() };419let new_requiree_components = [requiree]420.into_iter()421.chain(requiree_required_by.iter().copied())422.collect::<IndexSet<_, FixedHasher>>();423424// We now need to update the required and required_by components of all the components425// directly or indirectly involved.426// Important: we need to be careful about the order we do these operations in.427// Since computing the required components of some component depends on the required components of428// other components, and while we do this operations not all required components are up-to-date, we need429// to ensure we update components in such a way that we update a component after the components it depends on.430// Luckily, `new_requiree_components` comes from `ComponentInfo::required_by`, which guarantees an order431// with that property.432433// Update the inherited required components of all requiree components (directly or indirectly).434// Skip the first one (requiree) because we already updates it.435for &indirect_requiree in &new_requiree_components[1..] {436// SAFETY: `indirect_requiree` comes from `self` so it must be valid.437self.required_components_scope(indirect_requiree, |this, required_components| {438// Rebuild the inherited required components.439// SAFETY: `required_components` comes from `self`, so all its components must have be valid in `self`.440unsafe { required_components.rebuild_inherited_required_components(this) };441});442}443444// Update the `required_by` of all the components that were newly required (directly or indirectly).445for &indirect_required in &new_required_components {446// SAFETY: `indirect_required` comes from `self`, so it must be valid.447let required_by = unsafe {448self.get_required_by_mut(indirect_required)449.debug_checked_unwrap()450};451452// Remove and re-add all the components in `new_requiree_components`453// This preserves the invariant of `required_by` because `new_requiree_components`454// satisfies its invariant, due to being `requiree` followed by its `required_by` components,455// and because any component not in `new_requiree_components` cannot require a component in it,456// since if that was the case it would appear in the `required_by` for `requiree`.457required_by.retain(|id| !new_requiree_components.contains(id));458required_by.extend(&new_requiree_components);459}460461Ok(())462}463464/// Temporarily take out the [`RequiredComponents`] of the component with id `component_id`465/// and runs the given closure with mutable access to `self` and the given [`RequiredComponents`].466///467/// SAFETY:468///469/// `component_id` is valid in `self.components`470unsafe fn required_components_scope<R>(471&mut self,472component_id: ComponentId,473f: impl FnOnce(&mut Self, &mut RequiredComponents) -> R,474) -> R {475struct DropGuard<'a> {476components: &'a mut Components,477component_id: ComponentId,478required_components: RequiredComponents,479}480481impl Drop for DropGuard<'_> {482fn drop(&mut self) {483// SAFETY: The caller ensures that the `component_id` is valid.484let required_components = unsafe {485self.components486.get_required_components_mut(self.component_id)487.debug_checked_unwrap()488};489490debug_assert!(required_components.direct.is_empty());491debug_assert!(required_components.all.is_empty());492493*required_components = core::mem::take(&mut self.required_components);494}495}496497let mut guard = DropGuard {498component_id,499// SAFETY: The caller ensures that the `component_id` is valid.500required_components: core::mem::take(unsafe {501self.get_required_components_mut(component_id)502.debug_checked_unwrap()503}),504components: self,505};506507f(guard.components, &mut guard.required_components)508}509}510511/// An error returned when the registration of a required component fails.512#[derive(Error, Debug)]513#[non_exhaustive]514pub enum RequiredComponentsError {515/// The component is already a directly required component for the requiree.516#[error("Component {0:?} already directly requires component {1:?}")]517DuplicateRegistration(ComponentId, ComponentId),518/// Adding the given requirement would create a cycle.519#[error("Cyclic requirement found: the requiree component {0:?} is required by the required component {1:?}")]520CyclicRequirement(ComponentId, ComponentId),521/// An archetype with the component that requires other components already exists522#[error("An archetype with the component {0:?} that requires other components already exists")]523ArchetypeExists(ComponentId),524}525526pub(super) fn enforce_no_required_components_recursion(527components: &Components,528recursion_check_stack: &[ComponentId],529required: ComponentId,530) {531if let Some(direct_recursion) = recursion_check_stack532.iter()533.position(|&id| id == required)534.map(|index| index == recursion_check_stack.len() - 1)535{536panic!(537"Recursive required components detected: {}\nhelp: {}",538recursion_check_stack539.iter()540.map(|id| format!("{}", components.get_name(*id).unwrap().shortname()))541.collect::<Vec<_>>()542.join(" → "),543if direct_recursion {544format!(545"Remove require({}).",546components.get_name(required).unwrap().shortname()547)548} else {549"If this is intentional, consider merging the components.".into()550}551);552}553}554555/// This is a safe handle around `ComponentsRegistrator` and `RequiredComponents` to register required components.556pub struct RequiredComponentsRegistrator<'a, 'w> {557components: &'a mut ComponentsRegistrator<'w>,558required_components: &'a mut RequiredComponents,559}560561impl<'a, 'w> RequiredComponentsRegistrator<'a, 'w> {562/// # Safety563///564/// All components in `required_components` must have been registered in `components`565pub(super) unsafe fn new(566components: &'a mut ComponentsRegistrator<'w>,567required_components: &'a mut RequiredComponents,568) -> Self {569Self {570components,571required_components,572}573}574575/// Registers the [`Component`] `C` as an explicitly required component.576///577/// If the component was not already registered as an explicit required component then it is added578/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.579pub fn register_required<C: Component>(&mut self, constructor: fn() -> C) {580// SAFETY: we internally guarantee that all components in `required_components`581// are registered in `components`582unsafe {583self.required_components584.register(self.components, constructor);585}586}587588/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.589///590/// If the component was not already registered as an explicit required component then it is added591/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.592///593/// # Safety594///595/// `component_id` must be a valid [`ComponentId`] for `C` in the [`Components`] instance of `self`.596pub unsafe fn register_required_by_id<C: Component>(597&mut self,598component_id: ComponentId,599constructor: fn() -> C,600) {601// SAFETY:602// - the caller guarantees `component_id` is a valid component in `components` for `C`;603// - we internally guarantee all other components in `required_components` are registered in `components`.604unsafe {605self.required_components.register_by_id::<C>(606component_id,607self.components,608constructor,609);610}611}612613/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.614///615/// If the component was not already registered as an explicit required component then it is added616/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.617///618/// # Safety619///620/// - `component_id` must be valid in the [`Components`] instance of `self`;621/// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the622/// component with ID `component_id`.623pub unsafe fn register_required_dynamic_with(624&mut self,625component_id: ComponentId,626constructor: impl FnOnce() -> RequiredComponentConstructor,627) {628// SAFETY:629// - the caller guarantees `component_id` is valid in `components`;630// - the caller guarantees `constructor` returns a valid constructor for `component_id`;631// - we internally guarantee all other components in `required_components` are registered in `components`.632unsafe {633self.required_components.register_dynamic_with(634component_id,635self.components,636constructor,637);638}639}640}641642#[cfg(test)]643mod tests {644use alloc::string::{String, ToString};645646use crate::{647bundle::Bundle,648component::{Component, RequiredComponentsError},649prelude::Resource,650world::World,651};652653#[test]654fn required_components() {655#[derive(Component)]656#[require(Y)]657struct X;658659#[derive(Component)]660#[require(Z = new_z())]661struct Y {662value: String,663}664665#[derive(Component)]666struct Z(u32);667668impl Default for Y {669fn default() -> Self {670Self {671value: "hello".to_string(),672}673}674}675676fn new_z() -> Z {677Z(7)678}679680let mut world = World::new();681let id = world.spawn(X).id();682assert_eq!(683"hello",684world.entity(id).get::<Y>().unwrap().value,685"Y should have the default value"686);687assert_eq!(6887,689world.entity(id).get::<Z>().unwrap().0,690"Z should have the value provided by the constructor defined in Y"691);692693let id = world694.spawn((695X,696Y {697value: "foo".to_string(),698},699))700.id();701assert_eq!(702"foo",703world.entity(id).get::<Y>().unwrap().value,704"Y should have the manually provided value"705);706assert_eq!(7077,708world.entity(id).get::<Z>().unwrap().0,709"Z should have the value provided by the constructor defined in Y"710);711712let id = world.spawn((X, Z(8))).id();713assert_eq!(714"hello",715world.entity(id).get::<Y>().unwrap().value,716"Y should have the default value"717);718assert_eq!(7198,720world.entity(id).get::<Z>().unwrap().0,721"Z should have the manually provided value"722);723}724725#[test]726fn generic_required_components() {727#[derive(Component)]728#[require(Y<usize>)]729struct X;730731#[derive(Component, Default)]732struct Y<T> {733value: T,734}735736let mut world = World::new();737let id = world.spawn(X).id();738assert_eq!(7390,740world.entity(id).get::<Y<usize>>().unwrap().value,741"Y should have the default value"742);743}744745#[test]746fn required_components_spawn_nonexistent_hooks() {747#[derive(Component)]748#[require(Y)]749struct X;750751#[derive(Component, Default)]752struct Y;753754#[derive(Resource)]755struct A(usize);756757#[derive(Resource)]758struct I(usize);759760let mut world = World::new();761world.insert_resource(A(0));762world.insert_resource(I(0));763world764.register_component_hooks::<Y>()765.on_add(|mut world, _| world.resource_mut::<A>().0 += 1)766.on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);767768// Spawn entity and ensure Y was added769assert!(world.spawn(X).contains::<Y>());770771assert_eq!(world.resource::<A>().0, 1);772assert_eq!(world.resource::<I>().0, 1);773}774775#[test]776fn required_components_insert_existing_hooks() {777#[derive(Component)]778#[require(Y)]779struct X;780781#[derive(Component, Default)]782struct Y;783784#[derive(Resource)]785struct A(usize);786787#[derive(Resource)]788struct I(usize);789790let mut world = World::new();791world.insert_resource(A(0));792world.insert_resource(I(0));793world794.register_component_hooks::<Y>()795.on_add(|mut world, _| world.resource_mut::<A>().0 += 1)796.on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);797798// Spawn entity and ensure Y was added799assert!(world.spawn_empty().insert(X).contains::<Y>());800801assert_eq!(world.resource::<A>().0, 1);802assert_eq!(world.resource::<I>().0, 1);803}804805#[test]806fn required_components_take_leaves_required() {807#[derive(Component)]808#[require(Y)]809struct X;810811#[derive(Component, Default)]812struct Y;813814let mut world = World::new();815let e = world.spawn(X).id();816let _ = world.entity_mut(e).take::<X>().unwrap();817assert!(world.entity_mut(e).contains::<Y>());818}819820#[test]821fn required_components_retain_keeps_required() {822#[derive(Component)]823#[require(Y)]824struct X;825826#[derive(Component, Default)]827struct Y;828829#[derive(Component, Default)]830struct Z;831832let mut world = World::new();833let e = world.spawn((X, Z)).id();834world.entity_mut(e).retain::<X>();835assert!(world.entity_mut(e).contains::<X>());836assert!(world.entity_mut(e).contains::<Y>());837assert!(!world.entity_mut(e).contains::<Z>());838}839840#[test]841fn required_components_spawn_then_insert_no_overwrite() {842#[derive(Component)]843#[require(Y)]844struct X;845846#[derive(Component, Default)]847struct Y(usize);848849let mut world = World::new();850let id = world.spawn((X, Y(10))).id();851world.entity_mut(id).insert(X);852853assert_eq!(85410,855world.entity(id).get::<Y>().unwrap().0,856"Y should still have the manually provided value"857);858}859860#[test]861fn dynamic_required_components() {862#[derive(Component)]863#[require(Y)]864struct X;865866#[derive(Component, Default)]867struct Y;868869let mut world = World::new();870let x_id = world.register_component::<X>();871872let mut e = world.spawn_empty();873874// SAFETY: x_id is a valid component id875bevy_ptr::OwningPtr::make(X, |ptr| unsafe {876e.insert_by_id(x_id, ptr);877});878879assert!(e.contains::<Y>());880}881882#[test]883fn remove_component_and_its_runtime_required_components() {884#[derive(Component)]885struct X;886887#[derive(Component, Default)]888struct Y;889890#[derive(Component, Default)]891struct Z;892893#[derive(Component)]894struct V;895896let mut world = World::new();897world.register_required_components::<X, Y>();898world.register_required_components::<Y, Z>();899900let e = world.spawn((X, V)).id();901assert!(world.entity(e).contains::<X>());902assert!(world.entity(e).contains::<Y>());903assert!(world.entity(e).contains::<Z>());904assert!(world.entity(e).contains::<V>());905906//check that `remove` works as expected907world.entity_mut(e).remove::<X>();908assert!(!world.entity(e).contains::<X>());909assert!(world.entity(e).contains::<Y>());910assert!(world.entity(e).contains::<Z>());911assert!(world.entity(e).contains::<V>());912913world.entity_mut(e).insert(X);914assert!(world.entity(e).contains::<X>());915assert!(world.entity(e).contains::<Y>());916assert!(world.entity(e).contains::<Z>());917assert!(world.entity(e).contains::<V>());918919//remove `X` again and ensure that `Y` and `Z` was removed too920world.entity_mut(e).remove_with_requires::<X>();921assert!(!world.entity(e).contains::<X>());922assert!(!world.entity(e).contains::<Y>());923assert!(!world.entity(e).contains::<Z>());924assert!(world.entity(e).contains::<V>());925}926927#[test]928fn remove_component_and_its_required_components() {929#[derive(Component)]930#[require(Y)]931struct X;932933#[derive(Component, Default)]934#[require(Z)]935struct Y;936937#[derive(Component, Default)]938struct Z;939940#[derive(Component)]941struct V;942943let mut world = World::new();944945let e = world.spawn((X, V)).id();946assert!(world.entity(e).contains::<X>());947assert!(world.entity(e).contains::<Y>());948assert!(world.entity(e).contains::<Z>());949assert!(world.entity(e).contains::<V>());950951//check that `remove` works as expected952world.entity_mut(e).remove::<X>();953assert!(!world.entity(e).contains::<X>());954assert!(world.entity(e).contains::<Y>());955assert!(world.entity(e).contains::<Z>());956assert!(world.entity(e).contains::<V>());957958world.entity_mut(e).insert(X);959assert!(world.entity(e).contains::<X>());960assert!(world.entity(e).contains::<Y>());961assert!(world.entity(e).contains::<Z>());962assert!(world.entity(e).contains::<V>());963964//remove `X` again and ensure that `Y` and `Z` was removed too965world.entity_mut(e).remove_with_requires::<X>();966assert!(!world.entity(e).contains::<X>());967assert!(!world.entity(e).contains::<Y>());968assert!(!world.entity(e).contains::<Z>());969assert!(world.entity(e).contains::<V>());970}971972#[test]973fn remove_bundle_and_his_required_components() {974#[derive(Component, Default)]975#[require(Y)]976struct X;977978#[derive(Component, Default)]979struct Y;980981#[derive(Component, Default)]982#[require(W)]983struct Z;984985#[derive(Component, Default)]986struct W;987988#[derive(Component)]989struct V;990991#[derive(Bundle, Default)]992struct TestBundle {993x: X,994z: Z,995}996997let mut world = World::new();998let e = world.spawn((TestBundle::default(), V)).id();9991000assert!(world.entity(e).contains::<X>());1001assert!(world.entity(e).contains::<Y>());1002assert!(world.entity(e).contains::<Z>());1003assert!(world.entity(e).contains::<W>());1004assert!(world.entity(e).contains::<V>());10051006world.entity_mut(e).remove_with_requires::<TestBundle>();1007assert!(!world.entity(e).contains::<X>());1008assert!(!world.entity(e).contains::<Y>());1009assert!(!world.entity(e).contains::<Z>());1010assert!(!world.entity(e).contains::<W>());1011assert!(world.entity(e).contains::<V>());1012}10131014#[test]1015fn runtime_required_components() {1016// Same as `required_components` test but with runtime registration10171018#[derive(Component)]1019struct X;10201021#[derive(Component)]1022struct Y {1023value: String,1024}10251026#[derive(Component)]1027struct Z(u32);10281029impl Default for Y {1030fn default() -> Self {1031Self {1032value: "hello".to_string(),1033}1034}1035}10361037let mut world = World::new();10381039world.register_required_components::<X, Y>();1040world.register_required_components_with::<Y, Z>(|| Z(7));10411042let id = world.spawn(X).id();10431044assert_eq!(1045"hello",1046world.entity(id).get::<Y>().unwrap().value,1047"Y should have the default value"1048);1049assert_eq!(10507,1051world.entity(id).get::<Z>().unwrap().0,1052"Z should have the value provided by the constructor defined in Y"1053);10541055let id = world1056.spawn((1057X,1058Y {1059value: "foo".to_string(),1060},1061))1062.id();1063assert_eq!(1064"foo",1065world.entity(id).get::<Y>().unwrap().value,1066"Y should have the manually provided value"1067);1068assert_eq!(10697,1070world.entity(id).get::<Z>().unwrap().0,1071"Z should have the value provided by the constructor defined in Y"1072);10731074let id = world.spawn((X, Z(8))).id();1075assert_eq!(1076"hello",1077world.entity(id).get::<Y>().unwrap().value,1078"Y should have the default value"1079);1080assert_eq!(10818,1082world.entity(id).get::<Z>().unwrap().0,1083"Z should have the manually provided value"1084);1085}10861087#[test]1088fn runtime_required_components_override_1() {1089#[derive(Component)]1090struct X;10911092#[derive(Component, Default)]1093struct Y;10941095#[derive(Component)]1096struct Z(u32);10971098let mut world = World::new();10991100// - X requires Y with default constructor1101// - Y requires Z with custom constructor1102// - X requires Z with custom constructor (more specific than X -> Y -> Z)1103world.register_required_components::<X, Y>();1104world.register_required_components_with::<Y, Z>(|| Z(5));1105world.register_required_components_with::<X, Z>(|| Z(7));11061107let id = world.spawn(X).id();11081109assert_eq!(11107,1111world.entity(id).get::<Z>().unwrap().0,1112"Z should have the value provided by the constructor defined in X"1113);1114}11151116#[test]1117fn runtime_required_components_override_2() {1118// Same as `runtime_required_components_override_1` test but with different registration order11191120#[derive(Component)]1121struct X;11221123#[derive(Component, Default)]1124struct Y;11251126#[derive(Component)]1127struct Z(u32);11281129let mut world = World::new();11301131// - X requires Y with default constructor1132// - X requires Z with custom constructor (more specific than X -> Y -> Z)1133// - Y requires Z with custom constructor1134world.register_required_components::<X, Y>();1135world.register_required_components_with::<X, Z>(|| Z(7));1136world.register_required_components_with::<Y, Z>(|| Z(5));11371138let id = world.spawn(X).id();11391140assert_eq!(11417,1142world.entity(id).get::<Z>().unwrap().0,1143"Z should have the value provided by the constructor defined in X"1144);1145}11461147#[test]1148fn runtime_required_components_propagate_up() {1149// `A` requires `B` directly.1150#[derive(Component)]1151#[require(B)]1152struct A;11531154#[derive(Component, Default)]1155struct B;11561157#[derive(Component, Default)]1158struct C;11591160let mut world = World::new();11611162// `B` requires `C` with a runtime registration.1163// `A` should also require `C` because it requires `B`.1164world.register_required_components::<B, C>();11651166let id = world.spawn(A).id();11671168assert!(world.entity(id).get::<C>().is_some());1169}11701171#[test]1172fn runtime_required_components_propagate_up_even_more() {1173#[derive(Component)]1174struct A;11751176#[derive(Component, Default)]1177struct B;11781179#[derive(Component, Default)]1180struct C;11811182#[derive(Component, Default)]1183struct D;11841185let mut world = World::new();11861187world.register_required_components::<A, B>();1188world.register_required_components::<B, C>();1189world.register_required_components::<C, D>();11901191let id = world.spawn(A).id();11921193assert!(world.entity(id).get::<D>().is_some());1194}11951196#[test]1197fn runtime_required_components_deep_require_does_not_override_shallow_require() {1198#[derive(Component)]1199struct A;1200#[derive(Component, Default)]1201struct B;1202#[derive(Component, Default)]1203struct C;1204#[derive(Component)]1205struct Counter(i32);1206#[derive(Component, Default)]1207struct D;12081209let mut world = World::new();12101211world.register_required_components::<A, B>();1212world.register_required_components::<B, C>();1213world.register_required_components::<C, D>();1214world.register_required_components_with::<D, Counter>(|| Counter(2));1215// This should replace the require constructor in A since it is1216// shallower.1217world.register_required_components_with::<C, Counter>(|| Counter(1));12181219let id = world.spawn(A).id();12201221// The "shallower" of the two components is used.1222assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);1223}12241225#[test]1226fn runtime_required_components_deep_require_does_not_override_shallow_require_deep_subtree_after_shallow(1227) {1228#[derive(Component)]1229struct A;1230#[derive(Component, Default)]1231struct B;1232#[derive(Component, Default)]1233struct C;1234#[derive(Component, Default)]1235struct D;1236#[derive(Component, Default)]1237struct E;1238#[derive(Component)]1239struct Counter(i32);1240#[derive(Component, Default)]1241struct F;12421243let mut world = World::new();12441245world.register_required_components::<A, B>();1246world.register_required_components::<B, C>();1247world.register_required_components::<C, D>();1248world.register_required_components::<D, E>();1249world.register_required_components_with::<E, Counter>(|| Counter(1));1250world.register_required_components_with::<F, Counter>(|| Counter(2));1251world.register_required_components::<E, F>();12521253let id = world.spawn(A).id();12541255// The "shallower" of the two components is used.1256assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);1257}12581259#[test]1260fn runtime_required_components_existing_archetype() {1261#[derive(Component)]1262struct X;12631264#[derive(Component, Default)]1265struct Y;12661267let mut world = World::new();12681269// Registering required components after the archetype has already been created should panic.1270// This may change in the future.1271world.spawn(X);1272assert!(matches!(1273world.try_register_required_components::<X, Y>(),1274Err(RequiredComponentsError::ArchetypeExists(_))1275));1276}12771278#[test]1279fn runtime_required_components_fail_with_duplicate() {1280#[derive(Component)]1281#[require(Y)]1282struct X;12831284#[derive(Component, Default)]1285struct Y;12861287let mut world = World::new();12881289// This should fail: Tried to register Y as a requirement for X, but the requirement already exists.1290assert!(matches!(1291world.try_register_required_components::<X, Y>(),1292Err(RequiredComponentsError::DuplicateRegistration(_, _))1293));1294}12951296#[test]1297fn required_components_bundle_priority() {1298#[derive(Component, PartialEq, Eq, Clone, Copy, Debug)]1299struct MyRequired(bool);13001301#[derive(Component, Default)]1302#[require(MyRequired(false))]1303struct MiddleMan;13041305#[derive(Component, Default)]1306#[require(MiddleMan)]1307struct ConflictingRequire;13081309#[derive(Component, Default)]1310#[require(MyRequired(true))]1311struct MyComponent;13121313let mut world = World::new();1314let order_a = world1315.spawn((ConflictingRequire, MyComponent))1316.get::<MyRequired>()1317.cloned();1318let order_b = world1319.spawn((MyComponent, ConflictingRequire))1320.get::<MyRequired>()1321.cloned();13221323assert_eq!(order_a, Some(MyRequired(false)));1324assert_eq!(order_b, Some(MyRequired(true)));1325}13261327#[test]1328#[should_panic]1329fn required_components_recursion_errors() {1330#[derive(Component, Default)]1331#[require(B)]1332struct A;13331334#[derive(Component, Default)]1335#[require(C)]1336struct B;13371338#[derive(Component, Default)]1339#[require(B)]1340struct C;13411342World::new().register_component::<A>();1343}13441345#[test]1346#[should_panic]1347fn required_components_self_errors() {1348#[derive(Component, Default)]1349#[require(A)]1350struct A;13511352World::new().register_component::<A>();1353}13541355#[test]1356fn regression_19333() {1357#[derive(Component)]1358struct X(usize);13591360#[derive(Default, Component)]1361#[require(X(0))]1362struct Base;13631364#[derive(Default, Component)]1365#[require(X(1), Base)]1366struct A;13671368#[derive(Default, Component)]1369#[require(A, Base)]1370struct B;13711372#[derive(Default, Component)]1373#[require(B, Base)]1374struct C;13751376let mut w = World::new();13771378assert_eq!(w.spawn(B).get::<X>().unwrap().0, 1);1379assert_eq!(w.spawn(C).get::<X>().unwrap().0, 1);1380}13811382#[test]1383fn required_components_depth_first_2v1() {1384#[derive(Component)]1385struct X(usize);13861387#[derive(Component)]1388#[require(Left, Right)]1389struct Root;13901391#[derive(Component, Default)]1392#[require(LeftLeft)]1393struct Left;13941395#[derive(Component, Default)]1396#[require(X(0))] // This is at depth 2 but is more on the left of the tree1397struct LeftLeft;13981399#[derive(Component, Default)]1400#[require(X(1))] //. This is at depth 1 but is more on the right of the tree1401struct Right;14021403let mut world = World::new();14041405// LeftLeft should have priority over Right1406assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);1407}14081409#[test]1410fn required_components_depth_first_3v1() {1411#[derive(Component)]1412struct X(usize);14131414#[derive(Component)]1415#[require(Left, Right)]1416struct Root;14171418#[derive(Component, Default)]1419#[require(LeftLeft)]1420struct Left;14211422#[derive(Component, Default)]1423#[require(LeftLeftLeft)]1424struct LeftLeft;14251426#[derive(Component, Default)]1427#[require(X(0))] // This is at depth 3 but is more on the left of the tree1428struct LeftLeftLeft;14291430#[derive(Component, Default)]1431#[require(X(1))] //. This is at depth 1 but is more on the right of the tree1432struct Right;14331434let mut world = World::new();14351436// LeftLeftLeft should have priority over Right1437assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);1438}14391440#[test]1441fn runtime_required_components_depth_first_2v1() {1442#[derive(Component)]1443struct X(usize);14441445#[derive(Component)]1446struct Root;14471448#[derive(Component, Default)]1449struct Left;14501451#[derive(Component, Default)]1452struct LeftLeft;14531454#[derive(Component, Default)]1455struct Right;14561457// Register bottom up: registering higher level components should pick up lower level ones.1458let mut world = World::new();1459world.register_required_components_with::<LeftLeft, X>(|| X(0));1460world.register_required_components_with::<Right, X>(|| X(1));1461world.register_required_components::<Left, LeftLeft>();1462world.register_required_components::<Root, Left>();1463world.register_required_components::<Root, Right>();1464assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);14651466// Register top down: registering lower components should propagate to higher ones1467let mut world = World::new();1468world.register_required_components::<Root, Left>(); // Note: still register Left before Right1469world.register_required_components::<Root, Right>();1470world.register_required_components::<Left, LeftLeft>();1471world.register_required_components_with::<Right, X>(|| X(1));1472world.register_required_components_with::<LeftLeft, X>(|| X(0));1473assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);14741475// Register top down again, but this time LeftLeft before Right1476let mut world = World::new();1477world.register_required_components::<Root, Left>();1478world.register_required_components::<Root, Right>();1479world.register_required_components::<Left, LeftLeft>();1480world.register_required_components_with::<LeftLeft, X>(|| X(0));1481world.register_required_components_with::<Right, X>(|| X(1));1482assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);1483}14841485#[test]1486fn runtime_required_components_propagate_metadata_alternate() {1487#[derive(Component, Default)]1488#[require(L1)]1489struct L0;14901491#[derive(Component, Default)]1492struct L1;14931494#[derive(Component, Default)]1495#[require(L3)]1496struct L2;14971498#[derive(Component, Default)]1499struct L3;15001501#[derive(Component, Default)]1502#[require(L5)]1503struct L4;15041505#[derive(Component, Default)]1506struct L5;15071508// Try to piece the 3 requirements together1509let mut world = World::new();1510world.register_required_components::<L1, L2>();1511world.register_required_components::<L3, L4>();1512let e = world.spawn(L0).id();1513assert!(world1514.query::<(&L0, &L1, &L2, &L3, &L4, &L5)>()1515.get(&world, e)1516.is_ok());15171518// Repeat but in the opposite order1519let mut world = World::new();1520world.register_required_components::<L3, L4>();1521world.register_required_components::<L1, L2>();1522let e = world.spawn(L0).id();1523assert!(world1524.query::<(&L0, &L1, &L2, &L3, &L4, &L5)>()1525.get(&world, e)1526.is_ok());1527}15281529#[test]1530fn runtime_required_components_propagate_metadata_chain() {1531#[derive(Component, Default)]1532#[require(L1)]1533struct L0;15341535#[derive(Component, Default)]1536struct L1;15371538#[derive(Component, Default)]1539struct L2;15401541#[derive(Component, Default)]1542#[require(L4)]1543struct L3;15441545#[derive(Component, Default)]1546struct L4;15471548// Try to piece the 3 requirements together1549let mut world = World::new();1550world.register_required_components::<L1, L2>();1551world.register_required_components::<L2, L3>();1552let e = world.spawn(L0).id();1553assert!(world1554.query::<(&L0, &L1, &L2, &L3, &L4)>()1555.get(&world, e)1556.is_ok());15571558// Repeat but in the opposite order1559let mut world = World::new();1560world.register_required_components::<L2, L3>();1561world.register_required_components::<L1, L2>();1562let e = world.spawn(L0).id();1563assert!(world1564.query::<(&L0, &L1, &L2, &L3, &L4)>()1565.get(&world, e)1566.is_ok());1567}15681569#[test]1570fn runtime_required_components_cyclic() {1571#[derive(Component, Default)]1572#[require(B)]1573struct A;15741575#[derive(Component, Default)]1576struct B;15771578#[derive(Component, Default)]1579struct C;15801581let mut world = World::new();15821583assert!(world.try_register_required_components::<B, C>().is_ok());1584assert!(matches!(1585world.try_register_required_components::<C, A>(),1586Err(RequiredComponentsError::CyclicRequirement(_, _))1587));1588}1589}159015911592