Path: blob/main/crates/bevy_ecs/src/component/required.rs
9402 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, Tick},10component::{Component, ComponentId, Components, ComponentsRegistrator},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>(37component_id: ComponentId,38constructor: impl Fn() -> C + 'static,39) -> Self {40RequiredComponentConstructor({41// `portable-atomic-util` `Arc` is not able to coerce an unsized42// type like `std::sync::Arc` can. Creating a `Box` first does the43// coercion.44//45// This would be resolved by https://github.com/rust-lang/rust/issues/1234304647#[cfg(not(target_has_atomic = "ptr"))]48use alloc::boxed::Box;4950type Constructor = dyn for<'a, 'b> Fn(51&'a mut Table,52&'b mut SparseSets,53Tick,54TableRow,55Entity,56MaybeLocation,57);5859#[cfg(not(target_has_atomic = "ptr"))]60type Intermediate<T> = Box<T>;6162#[cfg(target_has_atomic = "ptr")]63type Intermediate<T> = Arc<T>;6465let boxed: Intermediate<Constructor> = Intermediate::new(66move |table, sparse_sets, change_tick, table_row, entity, caller| {67OwningPtr::make(constructor(), |ptr| {68// SAFETY: This will only be called in the context of `BundleInfo::write_components`, which will69// pass in a valid table_row and entity requiring a C constructor70// C::STORAGE_TYPE is the storage type associated with `component_id` / `C`71// `ptr` points to valid `C` data, which matches the type associated with `component_id`72unsafe {73BundleInfo::initialize_required_component(74table,75sparse_sets,76change_tick,77table_row,78entity,79component_id,80C::STORAGE_TYPE,81ptr,82caller,83);84}85});86},87);8889Arc::from(boxed)90})91}9293/// # Safety94/// This is intended to only be called in the context of [`BundleInfo::write_components`] to initialized required components.95/// Calling it _anywhere else_ should be considered unsafe.96///97/// `table_row` and `entity` must correspond to a valid entity that currently needs a component initialized via the constructor stored98/// on this [`RequiredComponentConstructor`]. The stored constructor must correspond to a component on `entity` that needs initialization.99/// `table` and `sparse_sets` must correspond to storages on a world where `entity` needs this required component initialized.100///101/// Again, don't call this anywhere but [`BundleInfo::write_components`].102pub(crate) unsafe fn initialize(103&self,104table: &mut Table,105sparse_sets: &mut SparseSets,106change_tick: Tick,107table_row: TableRow,108entity: Entity,109caller: MaybeLocation,110) {111(self.0)(table, sparse_sets, change_tick, table_row, entity, caller);112}113}114115/// The collection of metadata for components that are required for a given component.116///117/// For more information, see the "Required Components" section of [`Component`].118#[derive(Default, Clone)]119pub struct RequiredComponents {120/// The components that are directly required (i.e. excluding inherited ones), in the order of their precedence.121///122/// # Safety123/// The [`RequiredComponent`] instance associated to each ID must be valid for its component.124pub(crate) direct: IndexMap<ComponentId, RequiredComponent, FixedHasher>,125/// All the components that are required (i.e. including inherited ones), in depth-first order. Most importantly,126/// components in this list always appear after all the components that they require.127///128/// Note that the direct components are not necessarily at the end of this list, for example if A and C are directly129/// requires, and A requires B requires C, then `all` will hold [C, B, A].130///131/// # Safety132/// The [`RequiredComponent`] instance associated to each ID must be valid for its component.133pub(crate) all: IndexMap<ComponentId, RequiredComponent, FixedHasher>,134}135136impl Debug for RequiredComponents {137fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {138f.debug_struct("RequiredComponents")139.field("direct", &self.direct.keys())140.field("all", &self.all.keys())141.finish()142}143}144145impl RequiredComponents {146/// Registers the [`Component`] `C` as an explicitly required component.147///148/// If the component was not already registered as an explicit required component then it is added149/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.150///151/// # Safety152///153/// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.154unsafe fn register<C: Component>(155&mut self,156components: &mut ComponentsRegistrator<'_>,157constructor: impl Fn() -> C + 'static,158) {159let id = components.register_component::<C>();160// SAFETY:161// - `id` was just registered in `components`;162// - the caller guarantees all other components were registered in `components`.163unsafe { self.register_by_id::<C>(id, components, constructor) };164}165166/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.167///168/// If the component was not already registered as an explicit required component then it is added169/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.170///171/// # Safety172///173/// - `component_id` must be a valid component in `components` for the type `C`;174/// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.175unsafe fn register_by_id<C: Component>(176&mut self,177component_id: ComponentId,178components: &Components,179constructor: impl Fn() -> C + 'static,180) {181// SAFETY: the caller guarantees that `component_id` is valid for the type `C`.182let constructor =183|| unsafe { RequiredComponentConstructor::new(component_id, constructor) };184185// SAFETY:186// - the caller guarantees that `component_id` is valid in `components`187// - the caller guarantees all other components were registered in `components`;188// - constructor is guaranteed to create a valid constructor for the component with id `component_id`.189unsafe { self.register_dynamic_with(component_id, components, constructor) };190}191192/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.193///194/// If the component was not already registered as an explicit required component then it is added195/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.196///197/// # Safety198///199/// - `component_id` must be a valid component in `components`;200/// - all other components in `self` must have been registered in `components`;201/// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the202/// component with ID `component_id`.203unsafe fn register_dynamic_with(204&mut self,205component_id: ComponentId,206components: &Components,207constructor: impl FnOnce() -> RequiredComponentConstructor,208) {209// If already registered as a direct required component then bail.210let entry = match self.direct.entry(component_id) {211indexmap::map::Entry::Vacant(entry) => entry,212indexmap::map::Entry::Occupied(_) =>213panic!("Error while registering required component {component_id:?}: already directly required"),214};215216// Insert into `direct`.217let constructor = constructor();218let required_component = RequiredComponent { constructor };219entry.insert(required_component.clone());220221// Register inherited required components.222// SAFETY:223// - the caller guarantees all components that were in `self` have been registered in `components`;224// - `component_id` has just been added, but is also guaranteed by the called to be valid in `components`.225unsafe {226Self::register_inherited_required_components_unchecked(227&mut self.all,228component_id,229required_component,230components,231);232}233}234235/// Rebuild the `all` list236///237/// # Safety238///239/// - all components in `self` must have been registered in `components`.240unsafe fn rebuild_inherited_required_components(&mut self, components: &Components) {241// Clear `all`, we are re-initializing it.242self.all.clear();243244// Register all inherited components as if we just registered all components in `direct` one-by-one.245for (&required_id, required_component) in &self.direct {246// SAFETY:247// - the caller guarantees that all components in this instance have been registered in `components`,248// meaning both `all` and `required_id` have been registered in `components`;249// - `required_component` was associated to `required_id`, so it must hold a constructor valid for it.250unsafe {251Self::register_inherited_required_components_unchecked(252&mut self.all,253required_id,254required_component.clone(),255components,256);257}258}259}260261/// Registers all the inherited required components from `required_id`.262///263/// # Safety264///265/// - all components in `all` must have been registered in `components`;266/// - `required_id` must have been registered in `components`;267/// - `required_component` must hold a valid constructor for the component with id `required_id`.268unsafe fn register_inherited_required_components_unchecked(269all: &mut IndexMap<ComponentId, RequiredComponent, FixedHasher>,270required_id: ComponentId,271required_component: RequiredComponent,272components: &Components,273) {274// SAFETY: the caller guarantees that `required_id` is valid in `components`.275let info = unsafe { components.get_info(required_id).debug_checked_unwrap() };276277// Now we need to "recursively" register the278// Small optimization: if the current required component was already required recursively279// by an earlier direct required component then all its inherited components have all already280// been inserted, so let's not try to reinsert them.281if !all.contains_key(&required_id) {282for (&inherited_id, inherited_required) in &info.required_components().all {283// This is an inherited required component: insert it only if not already present.284// By the invariants of `RequiredComponents`, `info.required_components().all` holds the required285// components in a depth-first order, and this makes us store the components in `self.all` also286// in depth-first order, as long as we don't overwrite existing ones.287//288// SAFETY:289// `inherited_required` was associated to `inherited_id`, so it must have been valid for its component.290all.entry(inherited_id)291.or_insert_with(|| inherited_required.clone());292}293}294295// For direct required components:296// - insert them after inherited components to follow the depth-first order;297// - insert them unconditionally in order to make their constructor the one that's used.298// Note that `insert` does not change the order of components, meaning `component_id` will still appear299// before any other component that requires it.300//301// SAFETY: the caller guarantees that `required_component` is valid for the component with ID `required_id`.302all.insert(required_id, required_component);303}304305/// Iterates the ids of all required components. This includes recursive required components.306pub fn iter_ids(&self) -> impl Iterator<Item = ComponentId> + '_ {307self.all.keys().copied()308}309}310311impl Components {312/// Registers the components in `required_components` as required by `requiree`.313///314/// # Safety315///316/// - `requiree` must have been registered in `self`317/// - all components in `required_components` must have been registered in `self`;318/// - this is called with `requiree` before being called on any component requiring `requiree`.319pub(crate) unsafe fn register_required_by(320&mut self,321requiree: ComponentId,322required_components: &RequiredComponents,323) {324for &required in required_components.all.keys() {325// SAFETY: the caller guarantees that all components in `required_components` have been registered in `self`.326let required_by = unsafe { self.get_required_by_mut(required).debug_checked_unwrap() };327// This preserves the invariant of `required_by` because:328// - components requiring `required` and required by `requiree` are already initialized at this point329// and hence registered in `required_by` before `requiree`;330// - components requiring `requiree` cannot exist yet, as this is called on `requiree` before them.331required_by.insert(requiree);332}333}334335/// Registers the given component `R` and [required components] inherited from it as required by `T`.336///337/// When `T` is added to an entity, `R` will also be added if it was not already provided.338/// The given `constructor` will be used for the creation of `R`.339///340/// [required components]: Component#required-components341///342/// # Safety343///344/// - the given component IDs `required` and `requiree` must be valid in `self`;345/// - the given component ID `required` must be valid for the component type `R`.346///347///348/// # Errors349///350/// Returns a [`RequiredComponentsError`] if either of these are true:351/// - the `required` component is already a *directly* required component for the `requiree`; indirect352/// requirements through other components are allowed. In those cases, the more specific353/// registration will be used.354/// - the `requiree` component is already a (possibly indirect) required component for the `required` component.355pub(crate) unsafe fn register_required_components<R: Component>(356&mut self,357requiree: ComponentId,358required: ComponentId,359constructor: fn() -> R,360) -> Result<(), RequiredComponentsError> {361// First step: validate inputs and return errors.362363// SAFETY: The caller ensures that the `required` is valid.364let required_required_components = unsafe {365self.get_required_components(required)366.debug_checked_unwrap()367};368369// Cannot create cyclic requirements.370if required_required_components.all.contains_key(&requiree) {371return Err(RequiredComponentsError::CyclicRequirement(372requiree, required,373));374}375376// SAFETY: The caller ensures that the `requiree` is valid.377let required_components = unsafe {378self.get_required_components_mut(requiree)379.debug_checked_unwrap()380};381382// Cannot directly require the same component twice.383if required_components.direct.contains_key(&required) {384return Err(RequiredComponentsError::DuplicateRegistration(385requiree, required,386));387}388389// Second step: register the single requirement requiree->required390391// Store the old count of (all) required components. This will help determine which ones are new.392let old_required_count = required_components.all.len();393394// SAFETY: the caller guarantees that `requiree` is valid in `self`.395unsafe {396self.required_components_scope(requiree, |this, required_components| {397// SAFETY: the caller guarantees that `required` is valid for type `R` in `self`398required_components.register_by_id(required, this, constructor);399});400}401// Third step: update the required components and required_by of all the indirect requirements/requirees.402403// Borrow again otherwise it conflicts with the `self.required_components_scope` call.404// SAFETY: The caller ensures that the `requiree` is valid.405let required_components = unsafe {406self.get_required_components_mut(requiree)407.debug_checked_unwrap()408};409410// Optimization: get all the new required components, i.e. those that were appended.411// Other components that might be inherited when requiring `required` can be safely ignored because412// any component requiring `requiree` will already transitively require them.413// Note: the only small exception is for `required` itself, for which we cannot ignore the value of the414// constructor. But for simplicity we will rebuild any `RequiredComponents`415let new_required_components = required_components.all[old_required_count..]416.keys()417.copied()418.collect::<Vec<_>>();419420// Get all the new requiree components, i.e. `requiree` and all the components that `requiree` is required by.421// SAFETY: The caller ensures that the `requiree` is valid.422let requiree_required_by = unsafe { self.get_required_by(requiree).debug_checked_unwrap() };423let new_requiree_components = [requiree]424.into_iter()425.chain(requiree_required_by.iter().copied())426.collect::<IndexSet<_, FixedHasher>>();427428// We now need to update the required and required_by components of all the components429// directly or indirectly involved.430// Important: we need to be careful about the order we do these operations in.431// Since computing the required components of some component depends on the required components of432// other components, and while we do this operations not all required components are up-to-date, we need433// to ensure we update components in such a way that we update a component after the components it depends on.434// Luckily, `new_requiree_components` comes from `ComponentInfo::required_by`, which guarantees an order435// with that property.436437// Update the inherited required components of all requiree components (directly or indirectly).438// Skip the first one (requiree) because we already updates it.439for &indirect_requiree in &new_requiree_components[1..] {440// SAFETY: `indirect_requiree` comes from `self` so it must be valid.441unsafe {442self.required_components_scope(indirect_requiree, |this, required_components| {443// Rebuild the inherited required components.444// SAFETY: `required_components` comes from `self`, so all its components must have be valid in `self`.445required_components.rebuild_inherited_required_components(this);446});447}448}449450// Update the `required_by` of all the components that were newly required (directly or indirectly).451for &indirect_required in &new_required_components {452// SAFETY: `indirect_required` comes from `self`, so it must be valid.453let required_by = unsafe {454self.get_required_by_mut(indirect_required)455.debug_checked_unwrap()456};457458// Remove and re-add all the components in `new_requiree_components`459// This preserves the invariant of `required_by` because `new_requiree_components`460// satisfies its invariant, due to being `requiree` followed by its `required_by` components,461// and because any component not in `new_requiree_components` cannot require a component in it,462// since if that was the case it would appear in the `required_by` for `requiree`.463required_by.retain(|id| !new_requiree_components.contains(id));464required_by.extend(&new_requiree_components);465}466467Ok(())468}469470/// Temporarily take out the [`RequiredComponents`] of the component with id `component_id`471/// and runs the given closure with mutable access to `self` and the given [`RequiredComponents`].472///473/// SAFETY:474///475/// `component_id` is valid in `self.components`476unsafe fn required_components_scope<R>(477&mut self,478component_id: ComponentId,479f: impl FnOnce(&mut Self, &mut RequiredComponents) -> R,480) -> R {481struct DropGuard<'a> {482components: &'a mut Components,483component_id: ComponentId,484required_components: RequiredComponents,485}486487impl Drop for DropGuard<'_> {488fn drop(&mut self) {489// SAFETY: The caller ensures that the `component_id` is valid.490let required_components = unsafe {491self.components492.get_required_components_mut(self.component_id)493.debug_checked_unwrap()494};495496debug_assert!(required_components.direct.is_empty());497debug_assert!(required_components.all.is_empty());498499*required_components = core::mem::take(&mut self.required_components);500}501}502503let mut guard = DropGuard {504component_id,505// SAFETY: The caller ensures that the `component_id` is valid.506required_components: core::mem::take(unsafe {507self.get_required_components_mut(component_id)508.debug_checked_unwrap()509}),510components: self,511};512513f(guard.components, &mut guard.required_components)514}515}516517/// An error returned when the registration of a required component fails.518#[derive(Error, Debug)]519#[non_exhaustive]520pub enum RequiredComponentsError {521/// The component is already a directly required component for the requiree.522#[error("Component {0:?} already directly requires component {1:?}")]523DuplicateRegistration(ComponentId, ComponentId),524/// Adding the given requirement would create a cycle.525#[error("Cyclic requirement found: the requiree component {0:?} is required by the required component {1:?}")]526CyclicRequirement(ComponentId, ComponentId),527/// An archetype with the component that requires other components already exists528#[error("An archetype with the component {0:?} that requires other components already exists")]529ArchetypeExists(ComponentId),530}531532pub(super) fn enforce_no_required_components_recursion(533components: &Components,534recursion_check_stack: &[ComponentId],535required: ComponentId,536) {537if let Some(direct_recursion) = recursion_check_stack538.iter()539.position(|&id| id == required)540.map(|index| index == recursion_check_stack.len() - 1)541{542panic!(543"Recursive required components detected: {}\nhelp: {}",544recursion_check_stack545.iter()546.map(|id| format!("{}", components.get_name(*id).unwrap().shortname()))547.collect::<Vec<_>>()548.join(" → "),549if direct_recursion {550format!(551"Remove require({}).",552components.get_name(required).unwrap().shortname()553)554} else {555"If this is intentional, consider merging the components.".into()556}557);558}559}560561/// This is a safe handle around `ComponentsRegistrator` and `RequiredComponents` to register required components.562pub struct RequiredComponentsRegistrator<'a, 'w> {563components: &'a mut ComponentsRegistrator<'w>,564required_components: &'a mut RequiredComponents,565}566567impl<'a, 'w> RequiredComponentsRegistrator<'a, 'w> {568/// # Safety569///570/// All components in `required_components` must have been registered in `components`571pub(super) unsafe fn new(572components: &'a mut ComponentsRegistrator<'w>,573required_components: &'a mut RequiredComponents,574) -> Self {575Self {576components,577required_components,578}579}580581/// Provides access to the current [`World`](crate::world::World)'s [`ComponentsRegistrator`]582pub fn components_registrator(&mut self) -> &mut ComponentsRegistrator<'w> {583self.components584}585586/// Registers the [`Component`] `C` as an explicitly required component.587///588/// If the component was not already registered as an explicit required component then it is added589/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.590pub fn register_required<C: Component>(&mut self, constructor: impl Fn() -> C + 'static) {591// SAFETY: we internally guarantee that all components in `required_components`592// are registered in `components`593unsafe {594self.required_components595.register(self.components, constructor);596}597}598599/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.600///601/// If the component was not already registered as an explicit required component then it is added602/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.603///604/// # Safety605///606/// `component_id` must be a valid [`ComponentId`] for `C` in the [`Components`] instance of `self`.607pub unsafe fn register_required_by_id<C: Component>(608&mut self,609component_id: ComponentId,610constructor: fn() -> C,611) {612// SAFETY:613// - the caller guarantees `component_id` is a valid component in `components` for `C`;614// - we internally guarantee all other components in `required_components` are registered in `components`.615unsafe {616self.required_components.register_by_id::<C>(617component_id,618self.components,619constructor,620);621}622}623624/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.625///626/// If the component was not already registered as an explicit required component then it is added627/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.628///629/// # Safety630///631/// - `component_id` must be valid in the [`Components`] instance of `self`;632/// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the633/// component with ID `component_id`.634pub unsafe fn register_required_dynamic_with(635&mut self,636component_id: ComponentId,637constructor: impl FnOnce() -> RequiredComponentConstructor,638) {639// SAFETY:640// - the caller guarantees `component_id` is valid in `components`;641// - the caller guarantees `constructor` returns a valid constructor for `component_id`;642// - we internally guarantee all other components in `required_components` are registered in `components`.643unsafe {644self.required_components.register_dynamic_with(645component_id,646self.components,647constructor,648);649}650}651}652653#[cfg(test)]654mod tests {655use alloc::string::{String, ToString};656657use crate::{658bundle::Bundle,659component::{Component, RequiredComponentsError},660prelude::Resource,661world::World,662};663664#[test]665fn required_components() {666#[derive(Component)]667#[require(Y)]668struct X;669670#[derive(Component)]671#[require(Z = new_z())]672struct Y {673value: String,674}675676#[derive(Component)]677struct Z(u32);678679impl Default for Y {680fn default() -> Self {681Self {682value: "hello".to_string(),683}684}685}686687fn new_z() -> Z {688Z(7)689}690691let mut world = World::new();692let id = world.spawn(X).id();693assert_eq!(694"hello",695world.entity(id).get::<Y>().unwrap().value,696"Y should have the default value"697);698assert_eq!(6997,700world.entity(id).get::<Z>().unwrap().0,701"Z should have the value provided by the constructor defined in Y"702);703704let id = world705.spawn((706X,707Y {708value: "foo".to_string(),709},710))711.id();712assert_eq!(713"foo",714world.entity(id).get::<Y>().unwrap().value,715"Y should have the manually provided value"716);717assert_eq!(7187,719world.entity(id).get::<Z>().unwrap().0,720"Z should have the value provided by the constructor defined in Y"721);722723let id = world.spawn((X, Z(8))).id();724assert_eq!(725"hello",726world.entity(id).get::<Y>().unwrap().value,727"Y should have the default value"728);729assert_eq!(7308,731world.entity(id).get::<Z>().unwrap().0,732"Z should have the manually provided value"733);734}735736#[test]737fn generic_required_components() {738#[derive(Component)]739#[require(Y<usize>)]740struct X;741742#[derive(Component, Default)]743struct Y<T> {744value: T,745}746747let mut world = World::new();748let id = world.spawn(X).id();749assert_eq!(7500,751world.entity(id).get::<Y<usize>>().unwrap().value,752"Y should have the default value"753);754}755756#[test]757fn required_components_spawn_nonexistent_hooks() {758#[derive(Component)]759#[require(Y)]760struct X;761762#[derive(Component, Default)]763struct Y;764765#[derive(Resource)]766struct A(usize);767768#[derive(Resource)]769struct I(usize);770771let mut world = World::new();772world.insert_resource(A(0));773world.insert_resource(I(0));774world775.register_component_hooks::<Y>()776.on_add(|mut world, _| world.resource_mut::<A>().0 += 1)777.on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);778779// Spawn entity and ensure Y was added780assert!(world.spawn(X).contains::<Y>());781782assert_eq!(world.resource::<A>().0, 1);783assert_eq!(world.resource::<I>().0, 1);784}785786#[test]787fn required_components_insert_existing_hooks() {788#[derive(Component)]789#[require(Y)]790struct X;791792#[derive(Component, Default)]793struct Y;794795#[derive(Resource)]796struct A(usize);797798#[derive(Resource)]799struct I(usize);800801let mut world = World::new();802world.insert_resource(A(0));803world.insert_resource(I(0));804world805.register_component_hooks::<Y>()806.on_add(|mut world, _| world.resource_mut::<A>().0 += 1)807.on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);808809// Spawn entity and ensure Y was added810assert!(world.spawn_empty().insert(X).contains::<Y>());811812assert_eq!(world.resource::<A>().0, 1);813assert_eq!(world.resource::<I>().0, 1);814}815816#[test]817fn required_components_take_leaves_required() {818#[derive(Component)]819#[require(Y)]820struct X;821822#[derive(Component, Default)]823struct Y;824825let mut world = World::new();826let e = world.spawn(X).id();827let _ = world.entity_mut(e).take::<X>().unwrap();828assert!(world.entity_mut(e).contains::<Y>());829}830831#[test]832fn required_components_retain_keeps_required() {833#[derive(Component)]834#[require(Y)]835struct X;836837#[derive(Component, Default)]838struct Y;839840#[derive(Component, Default)]841struct Z;842843let mut world = World::new();844let e = world.spawn((X, Z)).id();845world.entity_mut(e).retain::<X>();846assert!(world.entity_mut(e).contains::<X>());847assert!(world.entity_mut(e).contains::<Y>());848assert!(!world.entity_mut(e).contains::<Z>());849}850851#[test]852fn required_components_spawn_then_insert_no_overwrite() {853#[derive(Component)]854#[require(Y)]855struct X;856857#[derive(Component, Default)]858struct Y(usize);859860let mut world = World::new();861let id = world.spawn((X, Y(10))).id();862world.entity_mut(id).insert(X);863864assert_eq!(86510,866world.entity(id).get::<Y>().unwrap().0,867"Y should still have the manually provided value"868);869}870871#[test]872fn dynamic_required_components() {873#[derive(Component)]874#[require(Y)]875struct X;876877#[derive(Component, Default)]878struct Y;879880let mut world = World::new();881let x_id = world.register_component::<X>();882883let mut e = world.spawn_empty();884885// SAFETY: x_id is a valid component id886bevy_ptr::OwningPtr::make(X, |ptr| unsafe {887e.insert_by_id(x_id, ptr);888});889890assert!(e.contains::<Y>());891}892893#[test]894fn remove_component_and_its_runtime_required_components() {895#[derive(Component)]896struct X;897898#[derive(Component, Default)]899struct Y;900901#[derive(Component, Default)]902struct Z;903904#[derive(Component)]905struct V;906907let mut world = World::new();908world.register_required_components::<X, Y>();909world.register_required_components::<Y, Z>();910911let e = world.spawn((X, V)).id();912assert!(world.entity(e).contains::<X>());913assert!(world.entity(e).contains::<Y>());914assert!(world.entity(e).contains::<Z>());915assert!(world.entity(e).contains::<V>());916917//check that `remove` works as expected918world.entity_mut(e).remove::<X>();919assert!(!world.entity(e).contains::<X>());920assert!(world.entity(e).contains::<Y>());921assert!(world.entity(e).contains::<Z>());922assert!(world.entity(e).contains::<V>());923924world.entity_mut(e).insert(X);925assert!(world.entity(e).contains::<X>());926assert!(world.entity(e).contains::<Y>());927assert!(world.entity(e).contains::<Z>());928assert!(world.entity(e).contains::<V>());929930//remove `X` again and ensure that `Y` and `Z` was removed too931world.entity_mut(e).remove_with_requires::<X>();932assert!(!world.entity(e).contains::<X>());933assert!(!world.entity(e).contains::<Y>());934assert!(!world.entity(e).contains::<Z>());935assert!(world.entity(e).contains::<V>());936}937938#[test]939fn remove_component_and_its_required_components() {940#[derive(Component)]941#[require(Y)]942struct X;943944#[derive(Component, Default)]945#[require(Z)]946struct Y;947948#[derive(Component, Default)]949struct Z;950951#[derive(Component)]952struct V;953954let mut world = World::new();955956let e = world.spawn((X, V)).id();957assert!(world.entity(e).contains::<X>());958assert!(world.entity(e).contains::<Y>());959assert!(world.entity(e).contains::<Z>());960assert!(world.entity(e).contains::<V>());961962//check that `remove` works as expected963world.entity_mut(e).remove::<X>();964assert!(!world.entity(e).contains::<X>());965assert!(world.entity(e).contains::<Y>());966assert!(world.entity(e).contains::<Z>());967assert!(world.entity(e).contains::<V>());968969world.entity_mut(e).insert(X);970assert!(world.entity(e).contains::<X>());971assert!(world.entity(e).contains::<Y>());972assert!(world.entity(e).contains::<Z>());973assert!(world.entity(e).contains::<V>());974975//remove `X` again and ensure that `Y` and `Z` was removed too976world.entity_mut(e).remove_with_requires::<X>();977assert!(!world.entity(e).contains::<X>());978assert!(!world.entity(e).contains::<Y>());979assert!(!world.entity(e).contains::<Z>());980assert!(world.entity(e).contains::<V>());981}982983#[test]984fn remove_bundle_and_his_required_components() {985#[derive(Component, Default)]986#[require(Y)]987struct X;988989#[derive(Component, Default)]990struct Y;991992#[derive(Component, Default)]993#[require(W)]994struct Z;995996#[derive(Component, Default)]997struct W;998999#[derive(Component)]1000struct V;10011002#[derive(Bundle, Default)]1003struct TestBundle {1004x: X,1005z: Z,1006}10071008let mut world = World::new();1009let e = world.spawn((TestBundle::default(), V)).id();10101011assert!(world.entity(e).contains::<X>());1012assert!(world.entity(e).contains::<Y>());1013assert!(world.entity(e).contains::<Z>());1014assert!(world.entity(e).contains::<W>());1015assert!(world.entity(e).contains::<V>());10161017world.entity_mut(e).remove_with_requires::<TestBundle>();1018assert!(!world.entity(e).contains::<X>());1019assert!(!world.entity(e).contains::<Y>());1020assert!(!world.entity(e).contains::<Z>());1021assert!(!world.entity(e).contains::<W>());1022assert!(world.entity(e).contains::<V>());1023}10241025#[test]1026fn runtime_required_components() {1027// Same as `required_components` test but with runtime registration10281029#[derive(Component)]1030struct X;10311032#[derive(Component)]1033struct Y {1034value: String,1035}10361037#[derive(Component)]1038struct Z(u32);10391040impl Default for Y {1041fn default() -> Self {1042Self {1043value: "hello".to_string(),1044}1045}1046}10471048let mut world = World::new();10491050world.register_required_components::<X, Y>();1051world.register_required_components_with::<Y, Z>(|| Z(7));10521053let id = world.spawn(X).id();10541055assert_eq!(1056"hello",1057world.entity(id).get::<Y>().unwrap().value,1058"Y should have the default value"1059);1060assert_eq!(10617,1062world.entity(id).get::<Z>().unwrap().0,1063"Z should have the value provided by the constructor defined in Y"1064);10651066let id = world1067.spawn((1068X,1069Y {1070value: "foo".to_string(),1071},1072))1073.id();1074assert_eq!(1075"foo",1076world.entity(id).get::<Y>().unwrap().value,1077"Y should have the manually provided value"1078);1079assert_eq!(10807,1081world.entity(id).get::<Z>().unwrap().0,1082"Z should have the value provided by the constructor defined in Y"1083);10841085let id = world.spawn((X, Z(8))).id();1086assert_eq!(1087"hello",1088world.entity(id).get::<Y>().unwrap().value,1089"Y should have the default value"1090);1091assert_eq!(10928,1093world.entity(id).get::<Z>().unwrap().0,1094"Z should have the manually provided value"1095);1096}10971098#[test]1099fn runtime_required_components_override_1() {1100#[derive(Component)]1101struct X;11021103#[derive(Component, Default)]1104struct Y;11051106#[derive(Component)]1107struct Z(u32);11081109let mut world = World::new();11101111// - X requires Y with default constructor1112// - Y requires Z with custom constructor1113// - X requires Z with custom constructor (more specific than X -> Y -> Z)1114world.register_required_components::<X, Y>();1115world.register_required_components_with::<Y, Z>(|| Z(5));1116world.register_required_components_with::<X, Z>(|| Z(7));11171118let id = world.spawn(X).id();11191120assert_eq!(11217,1122world.entity(id).get::<Z>().unwrap().0,1123"Z should have the value provided by the constructor defined in X"1124);1125}11261127#[test]1128fn runtime_required_components_override_2() {1129// Same as `runtime_required_components_override_1` test but with different registration order11301131#[derive(Component)]1132struct X;11331134#[derive(Component, Default)]1135struct Y;11361137#[derive(Component)]1138struct Z(u32);11391140let mut world = World::new();11411142// - X requires Y with default constructor1143// - X requires Z with custom constructor (more specific than X -> Y -> Z)1144// - Y requires Z with custom constructor1145world.register_required_components::<X, Y>();1146world.register_required_components_with::<X, Z>(|| Z(7));1147world.register_required_components_with::<Y, Z>(|| Z(5));11481149let id = world.spawn(X).id();11501151assert_eq!(11527,1153world.entity(id).get::<Z>().unwrap().0,1154"Z should have the value provided by the constructor defined in X"1155);1156}11571158#[test]1159fn runtime_required_components_propagate_up() {1160// `A` requires `B` directly.1161#[derive(Component)]1162#[require(B)]1163struct A;11641165#[derive(Component, Default)]1166struct B;11671168#[derive(Component, Default)]1169struct C;11701171let mut world = World::new();11721173// `B` requires `C` with a runtime registration.1174// `A` should also require `C` because it requires `B`.1175world.register_required_components::<B, C>();11761177let id = world.spawn(A).id();11781179assert!(world.entity(id).get::<C>().is_some());1180}11811182#[test]1183fn runtime_required_components_propagate_up_even_more() {1184#[derive(Component)]1185struct A;11861187#[derive(Component, Default)]1188struct B;11891190#[derive(Component, Default)]1191struct C;11921193#[derive(Component, Default)]1194struct D;11951196let mut world = World::new();11971198world.register_required_components::<A, B>();1199world.register_required_components::<B, C>();1200world.register_required_components::<C, D>();12011202let id = world.spawn(A).id();12031204assert!(world.entity(id).get::<D>().is_some());1205}12061207#[test]1208fn runtime_required_components_deep_require_does_not_override_shallow_require() {1209#[derive(Component)]1210struct A;1211#[derive(Component, Default)]1212struct B;1213#[derive(Component, Default)]1214struct C;1215#[derive(Component)]1216struct Counter(i32);1217#[derive(Component, Default)]1218struct D;12191220let mut world = World::new();12211222world.register_required_components::<A, B>();1223world.register_required_components::<B, C>();1224world.register_required_components::<C, D>();1225world.register_required_components_with::<D, Counter>(|| Counter(2));1226// This should replace the require constructor in A since it is1227// shallower.1228world.register_required_components_with::<C, Counter>(|| Counter(1));12291230let id = world.spawn(A).id();12311232// The "shallower" of the two components is used.1233assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);1234}12351236#[test]1237fn runtime_required_components_deep_require_does_not_override_shallow_require_deep_subtree_after_shallow(1238) {1239#[derive(Component)]1240struct A;1241#[derive(Component, Default)]1242struct B;1243#[derive(Component, Default)]1244struct C;1245#[derive(Component, Default)]1246struct D;1247#[derive(Component, Default)]1248struct E;1249#[derive(Component)]1250struct Counter(i32);1251#[derive(Component, Default)]1252struct F;12531254let mut world = World::new();12551256world.register_required_components::<A, B>();1257world.register_required_components::<B, C>();1258world.register_required_components::<C, D>();1259world.register_required_components::<D, E>();1260world.register_required_components_with::<E, Counter>(|| Counter(1));1261world.register_required_components_with::<F, Counter>(|| Counter(2));1262world.register_required_components::<E, F>();12631264let id = world.spawn(A).id();12651266// The "shallower" of the two components is used.1267assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);1268}12691270#[test]1271fn runtime_required_components_existing_archetype() {1272#[derive(Component)]1273struct X;12741275#[derive(Component, Default)]1276struct Y;12771278let mut world = World::new();12791280// Registering required components after the archetype has already been created should panic.1281// This may change in the future.1282world.spawn(X);1283assert!(matches!(1284world.try_register_required_components::<X, Y>(),1285Err(RequiredComponentsError::ArchetypeExists(_))1286));1287}12881289#[test]1290fn runtime_required_components_fail_with_duplicate() {1291#[derive(Component)]1292#[require(Y)]1293struct X;12941295#[derive(Component, Default)]1296struct Y;12971298let mut world = World::new();12991300// This should fail: Tried to register Y as a requirement for X, but the requirement already exists.1301assert!(matches!(1302world.try_register_required_components::<X, Y>(),1303Err(RequiredComponentsError::DuplicateRegistration(_, _))1304));1305}13061307#[test]1308fn required_components_bundle_priority() {1309#[derive(Component, PartialEq, Eq, Clone, Copy, Debug)]1310struct MyRequired(bool);13111312#[derive(Component, Default)]1313#[require(MyRequired(false))]1314struct MiddleMan;13151316#[derive(Component, Default)]1317#[require(MiddleMan)]1318struct ConflictingRequire;13191320#[derive(Component, Default)]1321#[require(MyRequired(true))]1322struct MyComponent;13231324let mut world = World::new();1325let order_a = world1326.spawn((ConflictingRequire, MyComponent))1327.get::<MyRequired>()1328.cloned();1329let order_b = world1330.spawn((MyComponent, ConflictingRequire))1331.get::<MyRequired>()1332.cloned();13331334assert_eq!(order_a, Some(MyRequired(false)));1335assert_eq!(order_b, Some(MyRequired(true)));1336}13371338#[test]1339#[should_panic]1340fn required_components_recursion_errors() {1341#[derive(Component, Default)]1342#[require(B)]1343struct A;13441345#[derive(Component, Default)]1346#[require(C)]1347struct B;13481349#[derive(Component, Default)]1350#[require(B)]1351struct C;13521353World::new().register_component::<A>();1354}13551356#[test]1357#[should_panic]1358fn required_components_self_errors() {1359#[derive(Component, Default)]1360#[require(A)]1361struct A;13621363World::new().register_component::<A>();1364}13651366#[test]1367fn regression_19333() {1368#[derive(Component)]1369struct X(usize);13701371#[derive(Default, Component)]1372#[require(X(0))]1373struct Base;13741375#[derive(Default, Component)]1376#[require(X(1), Base)]1377struct A;13781379#[derive(Default, Component)]1380#[require(A, Base)]1381struct B;13821383#[derive(Default, Component)]1384#[require(B, Base)]1385struct C;13861387let mut w = World::new();13881389assert_eq!(w.spawn(B).get::<X>().unwrap().0, 1);1390assert_eq!(w.spawn(C).get::<X>().unwrap().0, 1);1391}13921393#[test]1394fn required_components_depth_first_2v1() {1395#[derive(Component)]1396struct X(usize);13971398#[derive(Component)]1399#[require(Left, Right)]1400struct Root;14011402#[derive(Component, Default)]1403#[require(LeftLeft)]1404struct Left;14051406#[derive(Component, Default)]1407#[require(X(0))] // This is at depth 2 but is more on the left of the tree1408struct LeftLeft;14091410#[derive(Component, Default)]1411#[require(X(1))] //. This is at depth 1 but is more on the right of the tree1412struct Right;14131414let mut world = World::new();14151416// LeftLeft should have priority over Right1417assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);1418}14191420#[test]1421fn required_components_depth_first_3v1() {1422#[derive(Component)]1423struct X(usize);14241425#[derive(Component)]1426#[require(Left, Right)]1427struct Root;14281429#[derive(Component, Default)]1430#[require(LeftLeft)]1431struct Left;14321433#[derive(Component, Default)]1434#[require(LeftLeftLeft)]1435struct LeftLeft;14361437#[derive(Component, Default)]1438#[require(X(0))] // This is at depth 3 but is more on the left of the tree1439struct LeftLeftLeft;14401441#[derive(Component, Default)]1442#[require(X(1))] //. This is at depth 1 but is more on the right of the tree1443struct Right;14441445let mut world = World::new();14461447// LeftLeftLeft should have priority over Right1448assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);1449}14501451#[test]1452fn runtime_required_components_depth_first_2v1() {1453#[derive(Component)]1454struct X(usize);14551456#[derive(Component)]1457struct Root;14581459#[derive(Component, Default)]1460struct Left;14611462#[derive(Component, Default)]1463struct LeftLeft;14641465#[derive(Component, Default)]1466struct Right;14671468// Register bottom up: registering higher level components should pick up lower level ones.1469let mut world = World::new();1470world.register_required_components_with::<LeftLeft, X>(|| X(0));1471world.register_required_components_with::<Right, X>(|| X(1));1472world.register_required_components::<Left, LeftLeft>();1473world.register_required_components::<Root, Left>();1474world.register_required_components::<Root, Right>();1475assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);14761477// Register top down: registering lower components should propagate to higher ones1478let mut world = World::new();1479world.register_required_components::<Root, Left>(); // Note: still register Left before Right1480world.register_required_components::<Root, Right>();1481world.register_required_components::<Left, LeftLeft>();1482world.register_required_components_with::<Right, X>(|| X(1));1483world.register_required_components_with::<LeftLeft, X>(|| X(0));1484assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);14851486// Register top down again, but this time LeftLeft before Right1487let mut world = World::new();1488world.register_required_components::<Root, Left>();1489world.register_required_components::<Root, Right>();1490world.register_required_components::<Left, LeftLeft>();1491world.register_required_components_with::<LeftLeft, X>(|| X(0));1492world.register_required_components_with::<Right, X>(|| X(1));1493assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);1494}14951496#[test]1497fn runtime_required_components_propagate_metadata_alternate() {1498#[derive(Component, Default)]1499#[require(L1)]1500struct L0;15011502#[derive(Component, Default)]1503struct L1;15041505#[derive(Component, Default)]1506#[require(L3)]1507struct L2;15081509#[derive(Component, Default)]1510struct L3;15111512#[derive(Component, Default)]1513#[require(L5)]1514struct L4;15151516#[derive(Component, Default)]1517struct L5;15181519// Try to piece the 3 requirements together1520let mut world = World::new();1521world.register_required_components::<L1, L2>();1522world.register_required_components::<L3, L4>();1523let e = world.spawn(L0).id();1524assert!(world1525.query::<(&L0, &L1, &L2, &L3, &L4, &L5)>()1526.get(&world, e)1527.is_ok());15281529// Repeat but in the opposite order1530let mut world = World::new();1531world.register_required_components::<L3, L4>();1532world.register_required_components::<L1, L2>();1533let e = world.spawn(L0).id();1534assert!(world1535.query::<(&L0, &L1, &L2, &L3, &L4, &L5)>()1536.get(&world, e)1537.is_ok());1538}15391540#[test]1541fn runtime_required_components_propagate_metadata_chain() {1542#[derive(Component, Default)]1543#[require(L1)]1544struct L0;15451546#[derive(Component, Default)]1547struct L1;15481549#[derive(Component, Default)]1550struct L2;15511552#[derive(Component, Default)]1553#[require(L4)]1554struct L3;15551556#[derive(Component, Default)]1557struct L4;15581559// Try to piece the 3 requirements together1560let mut world = World::new();1561world.register_required_components::<L1, L2>();1562world.register_required_components::<L2, L3>();1563let e = world.spawn(L0).id();1564assert!(world1565.query::<(&L0, &L1, &L2, &L3, &L4)>()1566.get(&world, e)1567.is_ok());15681569// Repeat but in the opposite order1570let mut world = World::new();1571world.register_required_components::<L2, L3>();1572world.register_required_components::<L1, L2>();1573let e = world.spawn(L0).id();1574assert!(world1575.query::<(&L0, &L1, &L2, &L3, &L4)>()1576.get(&world, e)1577.is_ok());1578}15791580#[test]1581fn runtime_required_components_cyclic() {1582#[derive(Component, Default)]1583#[require(B)]1584struct A;15851586#[derive(Component, Default)]1587struct B;15881589#[derive(Component, Default)]1590struct C;15911592let mut world = World::new();15931594assert!(world.try_register_required_components::<B, C>().is_ok());1595assert!(matches!(1596world.try_register_required_components::<C, A>(),1597Err(RequiredComponentsError::CyclicRequirement(_, _))1598));1599}1600}160116021603