//! Types for handling [`Bundle`]s.1//!2//! This module contains the [`Bundle`] trait and some other helper types.34mod impls;5mod info;6mod insert;7mod remove;8mod spawner;9#[cfg(test)]10mod tests;1112pub(crate) use insert::BundleInserter;13pub(crate) use remove::BundleRemover;14pub(crate) use spawner::BundleSpawner;1516use bevy_ptr::MovingPtr;17use core::mem::MaybeUninit;18pub use info::*;1920/// Derive the [`Bundle`] trait21///22/// You can apply this derive macro to structs that are23/// composed of [`Component`](crate::component::Component)s or24/// other [`Bundle`]s.25///26/// ## Attributes27///28/// Sometimes parts of the Bundle should not be inserted.29/// Those can be marked with `#[bundle(ignore)]`, and they will be skipped.30/// In that case, the field needs to implement [`Default`] unless you also ignore31/// the [`BundleFromComponents`] implementation.32///33/// ```rust34/// # use bevy_ecs::prelude::{Component, Bundle};35/// # #[derive(Component)]36/// # struct Hitpoint;37/// #38/// #[derive(Bundle)]39/// struct HitpointMarker {40/// hitpoints: Hitpoint,41///42/// #[bundle(ignore)]43/// creator: Option<String>44/// }45/// ```46///47/// Some fields may be bundles that do not implement48/// [`BundleFromComponents`]. This happens for bundles that cannot be extracted.49/// For example with [`SpawnRelatedBundle`](bevy_ecs::spawn::SpawnRelatedBundle), see below for an50/// example usage.51/// In those cases you can either ignore it as above,52/// or you can opt out the whole Struct by marking it as ignored with53/// `#[bundle(ignore_from_components)]`.54///55/// ```rust56/// # use bevy_ecs::prelude::{Component, Bundle, ChildOf, Spawn};57/// # #[derive(Component)]58/// # struct Hitpoint;59/// # #[derive(Component)]60/// # struct Marker;61/// #62/// use bevy_ecs::spawn::SpawnRelatedBundle;63///64/// #[derive(Bundle)]65/// #[bundle(ignore_from_components)]66/// struct HitpointMarker {67/// hitpoints: Hitpoint,68/// related_spawner: SpawnRelatedBundle<ChildOf, Spawn<Marker>>,69/// }70/// ```71pub use bevy_ecs_macros::Bundle;7273use crate::{74component::{ComponentId, Components, ComponentsRegistrator, StorageType},75world::EntityWorldMut,76};77use bevy_ptr::OwningPtr;7879/// The `Bundle` trait enables insertion and removal of [`Component`]s from an entity.80///81/// Implementers of the `Bundle` trait are called 'bundles'.82///83/// Each bundle represents a static set of [`Component`] types.84/// Currently, bundles can only contain one of each [`Component`], and will85/// panic once initialized if this is not met.86///87/// ## Insertion88///89/// The primary use for bundles is to add a useful collection of components to an entity.90///91/// Adding a value of bundle to an entity will add the components from the set it92/// represents to the entity.93/// The values of these components are taken from the bundle.94/// If an entity already had one of these components, the entity's original component value95/// will be overwritten.96///97/// Importantly, bundles are only their constituent set of components.98/// You **should not** use bundles as a unit of behavior.99/// The behavior of your app can only be considered in terms of components, as systems,100/// which drive the behavior of a `bevy` application, operate on combinations of101/// components.102///103/// This rule is also important because multiple bundles may contain the same component type,104/// calculated in different ways — adding both of these bundles to one entity105/// would create incoherent behavior.106/// This would be unexpected if bundles were treated as an abstraction boundary, as107/// the abstraction would be unmaintainable for these cases.108///109/// For this reason, there is intentionally no [`Query`] to match whether an entity110/// contains the components of a bundle.111/// Queries should instead only select the components they logically operate on.112///113/// ## Removal114///115/// Bundles are also used when removing components from an entity.116///117/// Removing a bundle from an entity will remove any of its components attached118/// to the entity from the entity.119/// That is, if the entity does not have all the components of the bundle, those120/// which are present will be removed.121///122/// # Implementers123///124/// Every type which implements [`Component`] also implements `Bundle`, since125/// [`Component`] types can be added to or removed from an entity.126///127/// Additionally, [Tuples](`tuple`) of bundles are also [`Bundle`] (with up to 15 bundles).128/// These bundles contain the items of the 'inner' bundles.129/// This is a convenient shorthand which is primarily used when spawning entities.130///131/// [`unit`], otherwise known as [`()`](`unit`), is a [`Bundle`] containing no components (since it132/// can also be considered as the empty tuple).133/// This can be useful for spawning large numbers of empty entities using134/// [`World::spawn_batch`](crate::world::World::spawn_batch).135///136/// Tuple bundles can be nested, which can be used to create an anonymous bundle with more than137/// 15 items.138/// However, in most cases where this is required, the derive macro [`derive@Bundle`] should be139/// used instead.140/// The derived `Bundle` implementation contains the items of its fields, which all must141/// implement `Bundle`.142/// As explained above, this includes any [`Component`] type, and other derived bundles.143///144/// If you want to add `PhantomData` to your `Bundle` you have to mark it with `#[bundle(ignore)]`.145/// ```146/// # use std::marker::PhantomData;147/// use bevy_ecs::{component::Component, bundle::Bundle};148///149/// #[derive(Component)]150/// struct XPosition(i32);151/// #[derive(Component)]152/// struct YPosition(i32);153///154/// #[derive(Bundle)]155/// struct PositionBundle {156/// // A bundle can contain components157/// x: XPosition,158/// y: YPosition,159/// }160///161/// // You have to implement `Default` for ignored field types in bundle structs.162/// #[derive(Default)]163/// struct Other(f32);164///165/// #[derive(Bundle)]166/// struct NamedPointBundle<T: Send + Sync + 'static> {167/// // Or other bundles168/// a: PositionBundle,169/// // In addition to more components170/// z: PointName,171///172/// // when you need to use `PhantomData` you have to mark it as ignored173/// #[bundle(ignore)]174/// _phantom_data: PhantomData<T>175/// }176///177/// #[derive(Component)]178/// struct PointName(String);179/// ```180///181/// # Safety182///183/// Manual implementations of this trait are unsupported.184/// That is, there is no safe way to implement this trait, and you must not do so.185/// If you want a type to implement [`Bundle`], you must use [`derive@Bundle`](derive@Bundle).186///187/// [`Component`]: crate::component::Component188/// [`Query`]: crate::system::Query189// Some safety points:190// - [`Bundle::component_ids`] must return the [`ComponentId`] for each component type in the191// bundle, in the _exact_ order that [`DynamicBundle::get_components`] is called.192// - [`Bundle::from_components`] must call `func` exactly once for each [`ComponentId`] returned by193// [`Bundle::component_ids`].194#[diagnostic::on_unimplemented(195message = "`{Self}` is not a `Bundle`",196label = "invalid `Bundle`",197note = "consider annotating `{Self}` with `#[derive(Component)]` or `#[derive(Bundle)]`"198)]199pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static {200/// Gets this [`Bundle`]'s component ids, in the order of this bundle's [`Component`]s201#[doc(hidden)]202fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId));203204/// Gets this [`Bundle`]'s component ids. This will be [`None`] if the component has not been registered.205fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option<ComponentId>));206}207208/// Creates a [`Bundle`] by taking it from internal storage.209///210/// # Safety211///212/// Manual implementations of this trait are unsupported.213/// That is, there is no safe way to implement this trait, and you must not do so.214/// If you want a type to implement [`Bundle`], you must use [`derive@Bundle`](derive@Bundle).215///216/// [`Query`]: crate::system::Query217// Some safety points:218// - [`Bundle::component_ids`] must return the [`ComponentId`] for each component type in the219// bundle, in the _exact_ order that [`DynamicBundle::get_components`] is called.220// - [`Bundle::from_components`] must call `func` exactly once for each [`ComponentId`] returned by221// [`Bundle::component_ids`].222pub unsafe trait BundleFromComponents {223/// Calls `func`, which should return data for each component in the bundle, in the order of224/// this bundle's [`Component`]s225///226/// # Safety227/// Caller must return data for each component in the bundle, in the order of this bundle's228/// [`Component`]s229#[doc(hidden)]230unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> Self231where232// Ensure that the `OwningPtr` is used correctly233F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>,234Self: Sized;235}236237/// The parts from [`Bundle`] that don't require statically knowing the components of the bundle.238pub trait DynamicBundle: Sized {239/// An operation on the entity that happens _after_ inserting this bundle.240type Effect;241242/// Moves the components out of the bundle.243///244/// # Safety245/// For callers:246/// - Must be called exactly once before `apply_effect`247/// - The `StorageType` argument passed into `func` must be correct for the component being fetched.248/// - `apply_effect` must be called exactly once after this has been called if `Effect: !NoBundleEffect`249///250/// For implementors:251/// - Implementors of this function must convert `ptr` into pointers to individual components stored within252/// `Self` and call `func` on each of them in exactly the same order as [`Bundle::get_component_ids`] and253/// [`BundleFromComponents::from_components`].254/// - If any part of `ptr` is to be accessed in `apply_effect`, it must *not* be dropped at any point in this255/// function. Calling [`bevy_ptr::deconstruct_moving_ptr`] in this function automatically ensures this.256///257/// [`Component`]: crate::component::Component258// This function explicitly uses `MovingPtr` to avoid potentially large stack copies of the bundle259// when inserting into ECS storage. See https://github.com/bevyengine/bevy/issues/20571 for more260// information.261unsafe fn get_components(262ptr: MovingPtr<'_, Self>,263func: &mut impl FnMut(StorageType, OwningPtr<'_>),264);265266/// Applies the after-effects of spawning this bundle.267///268/// This is applied after all residual changes to the [`World`], including flushing the internal command269/// queue.270///271/// # Safety272/// For callers:273/// - Must be called exactly once after `get_components` has been called.274/// - `ptr` must point to the instance of `Self` that `get_components` was called on,275/// all of fields that were moved out of in `get_components` will not be valid anymore.276///277/// For implementors:278/// - If any part of `ptr` is to be accessed in this function, it must *not* be dropped at any point in279/// `get_components`. Calling [`bevy_ptr::deconstruct_moving_ptr`] in `get_components` automatically280/// ensures this is the case.281///282/// [`World`]: crate::world::World283// This function explicitly uses `MovingPtr` to avoid potentially large stack copies of the bundle284// when inserting into ECS storage. See https://github.com/bevyengine/bevy/issues/20571 for more285// information.286unsafe fn apply_effect(ptr: MovingPtr<'_, MaybeUninit<Self>>, entity: &mut EntityWorldMut);287}288289/// A trait implemented for [`DynamicBundle::Effect`] implementations that do nothing. This is used as a type constraint for290/// [`Bundle`] APIs that do not / cannot run [`DynamicBundle::Effect`], such as "batch spawn" APIs.291pub trait NoBundleEffect {}292293294