bevy_ecs/
bundle.rs

1//! Types for handling [`Bundle`]s.
2//!
3//! This module contains the [`Bundle`] trait and some other helper types.
4
5pub use bevy_ecs_macros::Bundle;
6
7use crate::{
8    archetype::{
9        Archetype, ArchetypeAfterBundleInsert, ArchetypeId, Archetypes, BundleComponentStatus,
10        ComponentStatus, SpawnBundleStatus,
11    },
12    change_detection::MaybeLocation,
13    component::{
14        Component, ComponentId, Components, ComponentsRegistrator, RequiredComponentConstructor,
15        RequiredComponents, StorageType, Tick,
16    },
17    entity::{Entities, Entity, EntityLocation},
18    observer::Observers,
19    prelude::World,
20    query::DebugCheckedUnwrap,
21    relationship::RelationshipHookMode,
22    storage::{SparseSetIndex, SparseSets, Storages, Table, TableRow},
23    world::{unsafe_world_cell::UnsafeWorldCell, EntityWorldMut, ON_ADD, ON_INSERT, ON_REPLACE},
24};
25use alloc::{boxed::Box, vec, vec::Vec};
26use bevy_platform::collections::{HashMap, HashSet};
27use bevy_ptr::{ConstNonNull, OwningPtr};
28use bevy_utils::TypeIdMap;
29use core::{any::TypeId, ptr::NonNull};
30use variadics_please::all_tuples;
31
32/// The `Bundle` trait enables insertion and removal of [`Component`]s from an entity.
33///
34/// Implementers of the `Bundle` trait are called 'bundles'.
35///
36/// Each bundle represents a static set of [`Component`] types.
37/// Currently, bundles can only contain one of each [`Component`], and will
38/// panic once initialized if this is not met.
39///
40/// ## Insertion
41///
42/// The primary use for bundles is to add a useful collection of components to an entity.
43///
44/// Adding a value of bundle to an entity will add the components from the set it
45/// represents to the entity.
46/// The values of these components are taken from the bundle.
47/// If an entity already had one of these components, the entity's original component value
48/// will be overwritten.
49///
50/// Importantly, bundles are only their constituent set of components.
51/// You **should not** use bundles as a unit of behavior.
52/// The behavior of your app can only be considered in terms of components, as systems,
53/// which drive the behavior of a `bevy` application, operate on combinations of
54/// components.
55///
56/// This rule is also important because multiple bundles may contain the same component type,
57/// calculated in different ways — adding both of these bundles to one entity
58/// would create incoherent behavior.
59/// This would be unexpected if bundles were treated as an abstraction boundary, as
60/// the abstraction would be unmaintainable for these cases.
61///
62/// For this reason, there is intentionally no [`Query`] to match whether an entity
63/// contains the components of a bundle.
64/// Queries should instead only select the components they logically operate on.
65///
66/// ## Removal
67///
68/// Bundles are also used when removing components from an entity.
69///
70/// Removing a bundle from an entity will remove any of its components attached
71/// to the entity from the entity.
72/// That is, if the entity does not have all the components of the bundle, those
73/// which are present will be removed.
74///
75/// # Implementers
76///
77/// Every type which implements [`Component`] also implements `Bundle`, since
78/// [`Component`] types can be added to or removed from an entity.
79///
80/// Additionally, [Tuples](`tuple`) of bundles are also [`Bundle`] (with up to 15 bundles).
81/// These bundles contain the items of the 'inner' bundles.
82/// This is a convenient shorthand which is primarily used when spawning entities.
83///
84/// [`unit`], otherwise known as [`()`](`unit`), is a [`Bundle`] containing no components (since it
85/// can also be considered as the empty tuple).
86/// This can be useful for spawning large numbers of empty entities using
87/// [`World::spawn_batch`](crate::world::World::spawn_batch).
88///
89/// Tuple bundles can be nested, which can be used to create an anonymous bundle with more than
90/// 15 items.
91/// However, in most cases where this is required, the derive macro [`derive@Bundle`] should be
92/// used instead.
93/// The derived `Bundle` implementation contains the items of its fields, which all must
94/// implement `Bundle`.
95/// As explained above, this includes any [`Component`] type, and other derived bundles.
96///
97/// If you want to add `PhantomData` to your `Bundle` you have to mark it with `#[bundle(ignore)]`.
98/// ```
99/// # use std::marker::PhantomData;
100/// use bevy_ecs::{component::Component, bundle::Bundle};
101///
102/// #[derive(Component)]
103/// struct XPosition(i32);
104/// #[derive(Component)]
105/// struct YPosition(i32);
106///
107/// #[derive(Bundle)]
108/// struct PositionBundle {
109///     // A bundle can contain components
110///     x: XPosition,
111///     y: YPosition,
112/// }
113///
114/// // You have to implement `Default` for ignored field types in bundle structs.
115/// #[derive(Default)]
116/// struct Other(f32);
117///
118/// #[derive(Bundle)]
119/// struct NamedPointBundle<T: Send + Sync + 'static> {
120///     // Or other bundles
121///     a: PositionBundle,
122///     // In addition to more components
123///     z: PointName,
124///
125///     // when you need to use `PhantomData` you have to mark it as ignored
126///     #[bundle(ignore)]
127///     _phantom_data: PhantomData<T>
128/// }
129///
130/// #[derive(Component)]
131/// struct PointName(String);
132/// ```
133///
134/// # Safety
135///
136/// Manual implementations of this trait are unsupported.
137/// That is, there is no safe way to implement this trait, and you must not do so.
138/// If you want a type to implement [`Bundle`], you must use [`derive@Bundle`](derive@Bundle).
139///
140/// [`Query`]: crate::system::Query
141// Some safety points:
142// - [`Bundle::component_ids`] must return the [`ComponentId`] for each component type in the
143// bundle, in the _exact_ order that [`DynamicBundle::get_components`] is called.
144// - [`Bundle::from_components`] must call `func` exactly once for each [`ComponentId`] returned by
145//   [`Bundle::component_ids`].
146#[diagnostic::on_unimplemented(
147    message = "`{Self}` is not a `Bundle`",
148    label = "invalid `Bundle`",
149    note = "consider annotating `{Self}` with `#[derive(Component)]` or `#[derive(Bundle)]`"
150)]
151pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static {
152    /// Gets this [`Bundle`]'s component ids, in the order of this bundle's [`Component`]s
153    #[doc(hidden)]
154    fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId));
155
156    /// Gets this [`Bundle`]'s component ids. This will be [`None`] if the component has not been registered.
157    fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option<ComponentId>));
158
159    /// Registers components that are required by the components in this [`Bundle`].
160    fn register_required_components(
161        _components: &mut ComponentsRegistrator,
162        _required_components: &mut RequiredComponents,
163    );
164}
165
166/// Creates a [`Bundle`] by taking it from internal storage.
167///
168/// # Safety
169///
170/// Manual implementations of this trait are unsupported.
171/// That is, there is no safe way to implement this trait, and you must not do so.
172/// If you want a type to implement [`Bundle`], you must use [`derive@Bundle`](derive@Bundle).
173///
174/// [`Query`]: crate::system::Query
175// Some safety points:
176// - [`Bundle::component_ids`] must return the [`ComponentId`] for each component type in the
177// bundle, in the _exact_ order that [`DynamicBundle::get_components`] is called.
178// - [`Bundle::from_components`] must call `func` exactly once for each [`ComponentId`] returned by
179//   [`Bundle::component_ids`].
180pub unsafe trait BundleFromComponents {
181    /// Calls `func`, which should return data for each component in the bundle, in the order of
182    /// this bundle's [`Component`]s
183    ///
184    /// # Safety
185    /// Caller must return data for each component in the bundle, in the order of this bundle's
186    /// [`Component`]s
187    #[doc(hidden)]
188    unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> Self
189    where
190        // Ensure that the `OwningPtr` is used correctly
191        F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>,
192        Self: Sized;
193}
194
195/// The parts from [`Bundle`] that don't require statically knowing the components of the bundle.
196pub trait DynamicBundle {
197    /// An operation on the entity that happens _after_ inserting this bundle.
198    type Effect: BundleEffect;
199    // SAFETY:
200    // The `StorageType` argument passed into [`Bundle::get_components`] must be correct for the
201    // component being fetched.
202    //
203    /// Calls `func` on each value, in the order of this bundle's [`Component`]s. This passes
204    /// ownership of the component values to `func`.
205    #[doc(hidden)]
206    fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) -> Self::Effect;
207}
208
209/// An operation on an [`Entity`] that occurs _after_ inserting the [`Bundle`] that defined this bundle effect.
210/// The order of operations is:
211///
212/// 1. The [`Bundle`] is inserted on the entity
213/// 2. Relevant Hooks are run for the insert, then Observers
214/// 3. The [`BundleEffect`] is run.
215///
216/// See [`DynamicBundle::Effect`].
217pub trait BundleEffect {
218    /// Applies this effect to the given `entity`.
219    fn apply(self, entity: &mut EntityWorldMut);
220}
221
222// SAFETY:
223// - `Bundle::component_ids` calls `ids` for C's component id (and nothing else)
224// - `Bundle::get_components` is called exactly once for C and passes the component's storage type based on its associated constant.
225unsafe impl<C: Component> Bundle for C {
226    fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)) {
227        ids(components.register_component::<C>());
228    }
229
230    fn register_required_components(
231        components: &mut ComponentsRegistrator,
232        required_components: &mut RequiredComponents,
233    ) {
234        let component_id = components.register_component::<C>();
235        <C as Component>::register_required_components(
236            component_id,
237            components,
238            required_components,
239            0,
240            &mut Vec::new(),
241        );
242    }
243
244    fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option<ComponentId>)) {
245        ids(components.get_id(TypeId::of::<C>()));
246    }
247}
248
249// SAFETY:
250// - `Bundle::from_components` calls `func` exactly once for C, which is the exact value returned by `Bundle::component_ids`.
251unsafe impl<C: Component> BundleFromComponents for C {
252    unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> Self
253    where
254        // Ensure that the `OwningPtr` is used correctly
255        F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>,
256        Self: Sized,
257    {
258        let ptr = func(ctx);
259        // Safety: The id given in `component_ids` is for `Self`
260        unsafe { ptr.read() }
261    }
262}
263
264impl<C: Component> DynamicBundle for C {
265    type Effect = ();
266    #[inline]
267    fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) -> Self::Effect {
268        OwningPtr::make(self, |ptr| func(C::STORAGE_TYPE, ptr));
269    }
270}
271
272macro_rules! tuple_impl {
273    ($(#[$meta:meta])* $($name: ident),*) => {
274        #[expect(
275            clippy::allow_attributes,
276            reason = "This is a tuple-related macro; as such, the lints below may not always apply."
277        )]
278        #[allow(
279            unused_mut,
280            unused_variables,
281            reason = "Zero-length tuples won't use any of the parameters."
282        )]
283        $(#[$meta])*
284        // SAFETY:
285        // - `Bundle::component_ids` calls `ids` for each component type in the
286        // bundle, in the exact order that `DynamicBundle::get_components` is called.
287        // - `Bundle::from_components` calls `func` exactly once for each `ComponentId` returned by `Bundle::component_ids`.
288        // - `Bundle::get_components` is called exactly once for each member. Relies on the above implementation to pass the correct
289        //   `StorageType` into the callback.
290        unsafe impl<$($name: Bundle),*> Bundle for ($($name,)*) {
291            fn component_ids(components: &mut ComponentsRegistrator,  ids: &mut impl FnMut(ComponentId)){
292                $(<$name as Bundle>::component_ids(components, ids);)*
293            }
294
295            fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option<ComponentId>)){
296                $(<$name as Bundle>::get_component_ids(components, ids);)*
297            }
298
299            fn register_required_components(
300                components: &mut ComponentsRegistrator,
301                required_components: &mut RequiredComponents,
302            ) {
303                $(<$name as Bundle>::register_required_components(components, required_components);)*
304            }
305        }
306
307        #[expect(
308            clippy::allow_attributes,
309            reason = "This is a tuple-related macro; as such, the lints below may not always apply."
310        )]
311        #[allow(
312            unused_mut,
313            unused_variables,
314            reason = "Zero-length tuples won't use any of the parameters."
315        )]
316        $(#[$meta])*
317        // SAFETY:
318        // - `Bundle::component_ids` calls `ids` for each component type in the
319        // bundle, in the exact order that `DynamicBundle::get_components` is called.
320        // - `Bundle::from_components` calls `func` exactly once for each `ComponentId` returned by `Bundle::component_ids`.
321        // - `Bundle::get_components` is called exactly once for each member. Relies on the above implementation to pass the correct
322        //   `StorageType` into the callback.
323        unsafe impl<$($name: BundleFromComponents),*> BundleFromComponents for ($($name,)*) {
324            #[allow(
325                clippy::unused_unit,
326                reason = "Zero-length tuples will generate a function body equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
327            )]
328            unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> Self
329            where
330                F: FnMut(&mut T) -> OwningPtr<'_>
331            {
332                #[allow(
333                    unused_unsafe,
334                    reason = "Zero-length tuples will not run anything in the unsafe block. Additionally, rewriting this to move the () outside of the unsafe would require putting the safety comment inside the tuple, hurting readability of the code."
335                )]
336                // SAFETY: Rust guarantees that tuple calls are evaluated 'left to right'.
337                // https://doc.rust-lang.org/reference/expressions.html#evaluation-order-of-operands
338                unsafe { ($(<$name as BundleFromComponents>::from_components(ctx, func),)*) }
339            }
340        }
341
342        #[expect(
343            clippy::allow_attributes,
344            reason = "This is a tuple-related macro; as such, the lints below may not always apply."
345        )]
346        #[allow(
347            unused_mut,
348            unused_variables,
349            reason = "Zero-length tuples won't use any of the parameters."
350        )]
351        $(#[$meta])*
352        impl<$($name: Bundle),*> DynamicBundle for ($($name,)*) {
353            type Effect = ($($name::Effect,)*);
354            #[allow(
355                clippy::unused_unit,
356                reason = "Zero-length tuples will generate a function body equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
357            )]
358            #[inline(always)]
359            fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) -> Self::Effect {
360                #[allow(
361                    non_snake_case,
362                    reason = "The names of these variables are provided by the caller, not by us."
363                )]
364                let ($(mut $name,)*) = self;
365                ($(
366                    $name.get_components(&mut *func),
367                )*)
368            }
369        }
370    }
371}
372
373all_tuples!(
374    #[doc(fake_variadic)]
375    tuple_impl,
376    0,
377    15,
378    B
379);
380
381/// A trait implemented for [`BundleEffect`] implementations that do nothing. This is used as a type constraint for
382/// [`Bundle`] APIs that do not / cannot run [`DynamicBundle::Effect`], such as "batch spawn" APIs.
383pub trait NoBundleEffect {}
384
385macro_rules! after_effect_impl {
386    ($($after_effect: ident),*) => {
387        #[expect(
388            clippy::allow_attributes,
389            reason = "This is a tuple-related macro; as such, the lints below may not always apply."
390        )]
391        impl<$($after_effect: BundleEffect),*> BundleEffect for ($($after_effect,)*) {
392            #[allow(
393                clippy::unused_unit,
394                reason = "Zero-length tuples will generate a function body equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case.")
395            ]
396            fn apply(self, _entity: &mut EntityWorldMut) {
397                #[allow(
398                    non_snake_case,
399                    reason = "The names of these variables are provided by the caller, not by us."
400                )]
401                let ($($after_effect,)*) = self;
402                $($after_effect.apply(_entity);)*
403            }
404        }
405
406        impl<$($after_effect: NoBundleEffect),*> NoBundleEffect for ($($after_effect,)*) { }
407    }
408}
409
410all_tuples!(after_effect_impl, 0, 15, P);
411
412/// For a specific [`World`], this stores a unique value identifying a type of a registered [`Bundle`].
413///
414/// [`World`]: crate::world::World
415#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
416pub struct BundleId(usize);
417
418impl BundleId {
419    /// Returns the index of the associated [`Bundle`] type.
420    ///
421    /// Note that this is unique per-world, and should not be reused across them.
422    #[inline]
423    pub fn index(self) -> usize {
424        self.0
425    }
426}
427
428impl SparseSetIndex for BundleId {
429    #[inline]
430    fn sparse_set_index(&self) -> usize {
431        self.index()
432    }
433
434    #[inline]
435    fn get_sparse_set_index(value: usize) -> Self {
436        Self(value)
437    }
438}
439
440/// What to do on insertion if a component already exists.
441#[derive(Clone, Copy, Eq, PartialEq)]
442pub enum InsertMode {
443    /// Any existing components of a matching type will be overwritten.
444    Replace,
445    /// Any existing components of a matching type will be left unchanged.
446    Keep,
447}
448
449/// Stores metadata associated with a specific type of [`Bundle`] for a given [`World`].
450///
451/// [`World`]: crate::world::World
452pub struct BundleInfo {
453    id: BundleId,
454    /// The list of all components contributed by the bundle (including Required Components). This is in
455    /// the order `[EXPLICIT_COMPONENTS][REQUIRED_COMPONENTS]`
456    ///
457    /// # Safety
458    /// Every ID in this list must be valid within the World that owns the [`BundleInfo`],
459    /// must have its storage initialized (i.e. columns created in tables, sparse set created),
460    /// and the range (0..`explicit_components_len`) must be in the same order as the source bundle
461    /// type writes its components in.
462    component_ids: Vec<ComponentId>,
463    required_components: Vec<RequiredComponentConstructor>,
464    explicit_components_len: usize,
465}
466
467impl BundleInfo {
468    /// Create a new [`BundleInfo`].
469    ///
470    /// # Safety
471    ///
472    /// Every ID in `component_ids` must be valid within the World that owns the `BundleInfo`
473    /// and must be in the same order as the source bundle type writes its components in.
474    unsafe fn new(
475        bundle_type_name: &'static str,
476        storages: &mut Storages,
477        components: &Components,
478        mut component_ids: Vec<ComponentId>,
479        id: BundleId,
480    ) -> BundleInfo {
481        // check for duplicates
482        let mut deduped = component_ids.clone();
483        deduped.sort_unstable();
484        deduped.dedup();
485        if deduped.len() != component_ids.len() {
486            // TODO: Replace with `Vec::partition_dedup` once https://github.com/rust-lang/rust/issues/54279 is stabilized
487            let mut seen = <HashSet<_>>::default();
488            let mut dups = Vec::new();
489            for id in component_ids {
490                if !seen.insert(id) {
491                    dups.push(id);
492                }
493            }
494
495            let names = dups
496                .into_iter()
497                .map(|id| {
498                    // SAFETY: the caller ensures component_id is valid.
499                    unsafe { components.get_info_unchecked(id).name() }
500                })
501                .collect::<Vec<_>>()
502                .join(", ");
503
504            panic!("Bundle {bundle_type_name} has duplicate components: {names}");
505        }
506
507        // handle explicit components
508        let explicit_components_len = component_ids.len();
509        let mut required_components = RequiredComponents::default();
510        for component_id in component_ids.iter().copied() {
511            // SAFETY: caller has verified that all ids are valid
512            let info = unsafe { components.get_info_unchecked(component_id) };
513            required_components.merge(info.required_components());
514            storages.prepare_component(info);
515        }
516        required_components.remove_explicit_components(&component_ids);
517
518        // handle required components
519        let required_components = required_components
520            .0
521            .into_iter()
522            .map(|(component_id, v)| {
523                // Safety: These ids came out of the passed `components`, so they must be valid.
524                let info = unsafe { components.get_info_unchecked(component_id) };
525                storages.prepare_component(info);
526                // This adds required components to the component_ids list _after_ using that list to remove explicitly provided
527                // components. This ordering is important!
528                component_ids.push(component_id);
529                v.constructor
530            })
531            .collect();
532
533        // SAFETY: The caller ensures that component_ids:
534        // - is valid for the associated world
535        // - has had its storage initialized
536        // - is in the same order as the source bundle type
537        BundleInfo {
538            id,
539            component_ids,
540            required_components,
541            explicit_components_len,
542        }
543    }
544
545    /// Returns a value identifying the associated [`Bundle`] type.
546    #[inline]
547    pub const fn id(&self) -> BundleId {
548        self.id
549    }
550
551    /// Returns the [ID](ComponentId) of each component explicitly defined in this bundle (ex: Required Components are excluded).
552    ///
553    /// For all components contributed by this bundle (including Required Components), see [`BundleInfo::contributed_components`]
554    #[inline]
555    pub fn explicit_components(&self) -> &[ComponentId] {
556        &self.component_ids[0..self.explicit_components_len]
557    }
558
559    /// Returns the [ID](ComponentId) of each Required Component needed by this bundle. This _does not include_ Required Components that are
560    /// explicitly provided by the bundle.
561    #[inline]
562    pub fn required_components(&self) -> &[ComponentId] {
563        &self.component_ids[self.explicit_components_len..]
564    }
565
566    /// Returns the [ID](ComponentId) of each component contributed by this bundle. This includes Required Components.
567    ///
568    /// For only components explicitly defined in this bundle, see [`BundleInfo::explicit_components`]
569    #[inline]
570    pub fn contributed_components(&self) -> &[ComponentId] {
571        &self.component_ids
572    }
573
574    /// Returns an iterator over the [ID](ComponentId) of each component explicitly defined in this bundle (ex: this excludes Required Components).
575    /// To iterate all components contributed by this bundle (including Required Components), see [`BundleInfo::iter_contributed_components`]
576    #[inline]
577    pub fn iter_explicit_components(&self) -> impl Iterator<Item = ComponentId> + Clone + '_ {
578        self.explicit_components().iter().copied()
579    }
580
581    /// Returns an iterator over the [ID](ComponentId) of each component contributed by this bundle. This includes Required Components.
582    ///
583    /// To iterate only components explicitly defined in this bundle, see [`BundleInfo::iter_explicit_components`]
584    #[inline]
585    pub fn iter_contributed_components(&self) -> impl Iterator<Item = ComponentId> + Clone + '_ {
586        self.component_ids.iter().copied()
587    }
588
589    /// Returns an iterator over the [ID](ComponentId) of each Required Component needed by this bundle. This _does not include_ Required Components that are
590    /// explicitly provided by the bundle.
591    pub fn iter_required_components(&self) -> impl Iterator<Item = ComponentId> + '_ {
592        self.required_components().iter().copied()
593    }
594
595    /// This writes components from a given [`Bundle`] to the given entity.
596    ///
597    /// # Safety
598    ///
599    /// `bundle_component_status` must return the "correct" [`ComponentStatus`] for each component
600    /// in the [`Bundle`], with respect to the entity's original archetype (prior to the bundle being added).
601    ///
602    /// For example, if the original archetype already has `ComponentA` and `T` also has `ComponentA`, the status
603    /// should be `Existing`. If the original archetype does not have `ComponentA`, the status should be `Added`.
604    ///
605    /// When "inserting" a bundle into an existing entity, [`ArchetypeAfterBundleInsert`]
606    /// should be used, which will report `Added` vs `Existing` status based on the current archetype's structure.
607    ///
608    /// When spawning a bundle, [`SpawnBundleStatus`] can be used instead, which removes the need
609    /// to look up the [`ArchetypeAfterBundleInsert`] in the archetype graph, which requires
610    /// ownership of the entity's current archetype.
611    ///
612    /// `table` must be the "new" table for `entity`. `table_row` must have space allocated for the
613    /// `entity`, `bundle` must match this [`BundleInfo`]'s type
614    #[inline]
615    unsafe fn write_components<'a, T: DynamicBundle, S: BundleComponentStatus>(
616        &self,
617        table: &mut Table,
618        sparse_sets: &mut SparseSets,
619        bundle_component_status: &S,
620        required_components: impl Iterator<Item = &'a RequiredComponentConstructor>,
621        entity: Entity,
622        table_row: TableRow,
623        change_tick: Tick,
624        bundle: T,
625        insert_mode: InsertMode,
626        caller: MaybeLocation,
627    ) -> T::Effect {
628        // NOTE: get_components calls this closure on each component in "bundle order".
629        // bundle_info.component_ids are also in "bundle order"
630        let mut bundle_component = 0;
631        let after_effect = bundle.get_components(&mut |storage_type, component_ptr| {
632            let component_id = *self.component_ids.get_unchecked(bundle_component);
633            match storage_type {
634                StorageType::Table => {
635                    // SAFETY: bundle_component is a valid index for this bundle
636                    let status = unsafe { bundle_component_status.get_status(bundle_component) };
637                    // SAFETY: If component_id is in self.component_ids, BundleInfo::new ensures that
638                    // the target table contains the component.
639                    let column = table.get_column_mut(component_id).debug_checked_unwrap();
640                    match (status, insert_mode) {
641                        (ComponentStatus::Added, _) => {
642                            column.initialize(table_row, component_ptr, change_tick, caller);
643                        }
644                        (ComponentStatus::Existing, InsertMode::Replace) => {
645                            column.replace(table_row, component_ptr, change_tick, caller);
646                        }
647                        (ComponentStatus::Existing, InsertMode::Keep) => {
648                            if let Some(drop_fn) = table.get_drop_for(component_id) {
649                                drop_fn(component_ptr);
650                            }
651                        }
652                    }
653                }
654                StorageType::SparseSet => {
655                    let sparse_set =
656                        // SAFETY: If component_id is in self.component_ids, BundleInfo::new ensures that
657                        // a sparse set exists for the component.
658                        unsafe { sparse_sets.get_mut(component_id).debug_checked_unwrap() };
659                    sparse_set.insert(entity, component_ptr, change_tick, caller);
660                }
661            }
662            bundle_component += 1;
663        });
664
665        for required_component in required_components {
666            required_component.initialize(
667                table,
668                sparse_sets,
669                change_tick,
670                table_row,
671                entity,
672                caller,
673            );
674        }
675
676        after_effect
677    }
678
679    /// Internal method to initialize a required component from an [`OwningPtr`]. This should ultimately be called
680    /// in the context of [`BundleInfo::write_components`], via [`RequiredComponentConstructor::initialize`].
681    ///
682    /// # Safety
683    ///
684    /// `component_ptr` must point to a required component value that matches the given `component_id`. The `storage_type` must match
685    /// the type associated with `component_id`. The `entity` and `table_row` must correspond to an entity with an uninitialized
686    /// component matching `component_id`.
687    ///
688    /// This method _should not_ be called outside of [`BundleInfo::write_components`].
689    /// For more information, read the [`BundleInfo::write_components`] safety docs.
690    /// This function inherits the safety requirements defined there.
691    pub(crate) unsafe fn initialize_required_component(
692        table: &mut Table,
693        sparse_sets: &mut SparseSets,
694        change_tick: Tick,
695        table_row: TableRow,
696        entity: Entity,
697        component_id: ComponentId,
698        storage_type: StorageType,
699        component_ptr: OwningPtr,
700        caller: MaybeLocation,
701    ) {
702        {
703            match storage_type {
704                StorageType::Table => {
705                    let column =
706                        // SAFETY: If component_id is in required_components, BundleInfo::new requires that
707                        // the target table contains the component.
708                        unsafe { table.get_column_mut(component_id).debug_checked_unwrap() };
709                    column.initialize(table_row, component_ptr, change_tick, caller);
710                }
711                StorageType::SparseSet => {
712                    let sparse_set =
713                        // SAFETY: If component_id is in required_components, BundleInfo::new requires that
714                        // a sparse set exists for the component.
715                        unsafe { sparse_sets.get_mut(component_id).debug_checked_unwrap() };
716                    sparse_set.insert(entity, component_ptr, change_tick, caller);
717                }
718            }
719        }
720    }
721
722    /// Inserts a bundle into the given archetype and returns the resulting archetype.
723    /// This could be the same [`ArchetypeId`], in the event that inserting the given bundle
724    /// does not result in an [`Archetype`] change.
725    ///
726    /// Results are cached in the [`Archetype`] graph to avoid redundant work.
727    ///
728    /// # Safety
729    /// `components` must be the same components as passed in [`Self::new`]
730    pub(crate) unsafe fn insert_bundle_into_archetype(
731        &self,
732        archetypes: &mut Archetypes,
733        storages: &mut Storages,
734        components: &Components,
735        observers: &Observers,
736        archetype_id: ArchetypeId,
737    ) -> ArchetypeId {
738        if let Some(archetype_after_insert_id) = archetypes[archetype_id]
739            .edges()
740            .get_archetype_after_bundle_insert(self.id)
741        {
742            return archetype_after_insert_id;
743        }
744        let mut new_table_components = Vec::new();
745        let mut new_sparse_set_components = Vec::new();
746        let mut bundle_status = Vec::with_capacity(self.explicit_components_len);
747        let mut added_required_components = Vec::new();
748        let mut added = Vec::new();
749        let mut existing = Vec::new();
750
751        let current_archetype = &mut archetypes[archetype_id];
752        for component_id in self.iter_explicit_components() {
753            if current_archetype.contains(component_id) {
754                bundle_status.push(ComponentStatus::Existing);
755                existing.push(component_id);
756            } else {
757                bundle_status.push(ComponentStatus::Added);
758                added.push(component_id);
759                // SAFETY: component_id exists
760                let component_info = unsafe { components.get_info_unchecked(component_id) };
761                match component_info.storage_type() {
762                    StorageType::Table => new_table_components.push(component_id),
763                    StorageType::SparseSet => new_sparse_set_components.push(component_id),
764                }
765            }
766        }
767
768        for (index, component_id) in self.iter_required_components().enumerate() {
769            if !current_archetype.contains(component_id) {
770                added_required_components.push(self.required_components[index].clone());
771                added.push(component_id);
772                // SAFETY: component_id exists
773                let component_info = unsafe { components.get_info_unchecked(component_id) };
774                match component_info.storage_type() {
775                    StorageType::Table => {
776                        new_table_components.push(component_id);
777                    }
778                    StorageType::SparseSet => {
779                        new_sparse_set_components.push(component_id);
780                    }
781                }
782            }
783        }
784
785        if new_table_components.is_empty() && new_sparse_set_components.is_empty() {
786            let edges = current_archetype.edges_mut();
787            // The archetype does not change when we insert this bundle.
788            edges.cache_archetype_after_bundle_insert(
789                self.id,
790                archetype_id,
791                bundle_status,
792                added_required_components,
793                added,
794                existing,
795            );
796            archetype_id
797        } else {
798            let table_id;
799            let table_components;
800            let sparse_set_components;
801            // The archetype changes when we insert this bundle. Prepare the new archetype and storages.
802            {
803                let current_archetype = &archetypes[archetype_id];
804                table_components = if new_table_components.is_empty() {
805                    // If there are no new table components, we can keep using this table.
806                    table_id = current_archetype.table_id();
807                    current_archetype.table_components().collect()
808                } else {
809                    new_table_components.extend(current_archetype.table_components());
810                    // Sort to ignore order while hashing.
811                    new_table_components.sort_unstable();
812                    // SAFETY: all component ids in `new_table_components` exist
813                    table_id = unsafe {
814                        storages
815                            .tables
816                            .get_id_or_insert(&new_table_components, components)
817                    };
818
819                    new_table_components
820                };
821
822                sparse_set_components = if new_sparse_set_components.is_empty() {
823                    current_archetype.sparse_set_components().collect()
824                } else {
825                    new_sparse_set_components.extend(current_archetype.sparse_set_components());
826                    // Sort to ignore order while hashing.
827                    new_sparse_set_components.sort_unstable();
828                    new_sparse_set_components
829                };
830            };
831            // SAFETY: ids in self must be valid
832            let new_archetype_id = archetypes.get_id_or_insert(
833                components,
834                observers,
835                table_id,
836                table_components,
837                sparse_set_components,
838            );
839            // Add an edge from the old archetype to the new archetype.
840            archetypes[archetype_id]
841                .edges_mut()
842                .cache_archetype_after_bundle_insert(
843                    self.id,
844                    new_archetype_id,
845                    bundle_status,
846                    added_required_components,
847                    added,
848                    existing,
849                );
850            new_archetype_id
851        }
852    }
853
854    /// Removes a bundle from the given archetype and returns the resulting archetype
855    /// (or `None` if the removal was invalid).
856    /// This could be the same [`ArchetypeId`], in the event that removing the given bundle
857    /// does not result in an [`Archetype`] change.
858    ///
859    /// Results are cached in the [`Archetype`] graph to avoid redundant work.
860    ///
861    /// If `intersection` is false, attempting to remove a bundle with components not contained in the
862    /// current archetype will fail, returning `None`.
863    ///
864    /// If `intersection` is true, components in the bundle but not in the current archetype
865    /// will be ignored.
866    ///
867    /// # Safety
868    /// `archetype_id` must exist and components in `bundle_info` must exist
869    pub(crate) unsafe fn remove_bundle_from_archetype(
870        &self,
871        archetypes: &mut Archetypes,
872        storages: &mut Storages,
873        components: &Components,
874        observers: &Observers,
875        archetype_id: ArchetypeId,
876        intersection: bool,
877    ) -> Option<ArchetypeId> {
878        // Check the archetype graph to see if the bundle has been
879        // removed from this archetype in the past.
880        let archetype_after_remove_result = {
881            let edges = archetypes[archetype_id].edges();
882            if intersection {
883                edges.get_archetype_after_bundle_remove(self.id())
884            } else {
885                edges.get_archetype_after_bundle_take(self.id())
886            }
887        };
888        let result = if let Some(result) = archetype_after_remove_result {
889            // This bundle removal result is cached. Just return that!
890            result
891        } else {
892            let mut next_table_components;
893            let mut next_sparse_set_components;
894            let next_table_id;
895            {
896                let current_archetype = &mut archetypes[archetype_id];
897                let mut removed_table_components = Vec::new();
898                let mut removed_sparse_set_components = Vec::new();
899                for component_id in self.iter_explicit_components() {
900                    if current_archetype.contains(component_id) {
901                        // SAFETY: bundle components were already initialized by bundles.get_info
902                        let component_info = unsafe { components.get_info_unchecked(component_id) };
903                        match component_info.storage_type() {
904                            StorageType::Table => removed_table_components.push(component_id),
905                            StorageType::SparseSet => {
906                                removed_sparse_set_components.push(component_id);
907                            }
908                        }
909                    } else if !intersection {
910                        // A component in the bundle was not present in the entity's archetype, so this
911                        // removal is invalid. Cache the result in the archetype graph.
912                        current_archetype
913                            .edges_mut()
914                            .cache_archetype_after_bundle_take(self.id(), None);
915                        return None;
916                    }
917                }
918
919                // Sort removed components so we can do an efficient "sorted remove".
920                // Archetype components are already sorted.
921                removed_table_components.sort_unstable();
922                removed_sparse_set_components.sort_unstable();
923                next_table_components = current_archetype.table_components().collect();
924                next_sparse_set_components = current_archetype.sparse_set_components().collect();
925                sorted_remove(&mut next_table_components, &removed_table_components);
926                sorted_remove(
927                    &mut next_sparse_set_components,
928                    &removed_sparse_set_components,
929                );
930
931                next_table_id = if removed_table_components.is_empty() {
932                    current_archetype.table_id()
933                } else {
934                    // SAFETY: all components in next_table_components exist
935                    unsafe {
936                        storages
937                            .tables
938                            .get_id_or_insert(&next_table_components, components)
939                    }
940                };
941            }
942
943            let new_archetype_id = archetypes.get_id_or_insert(
944                components,
945                observers,
946                next_table_id,
947                next_table_components,
948                next_sparse_set_components,
949            );
950            Some(new_archetype_id)
951        };
952        let current_archetype = &mut archetypes[archetype_id];
953        // Cache the result in an edge.
954        if intersection {
955            current_archetype
956                .edges_mut()
957                .cache_archetype_after_bundle_remove(self.id(), result);
958        } else {
959            current_archetype
960                .edges_mut()
961                .cache_archetype_after_bundle_take(self.id(), result);
962        }
963        result
964    }
965}
966
967// SAFETY: We have exclusive world access so our pointers can't be invalidated externally
968pub(crate) struct BundleInserter<'w> {
969    world: UnsafeWorldCell<'w>,
970    bundle_info: ConstNonNull<BundleInfo>,
971    archetype_after_insert: ConstNonNull<ArchetypeAfterBundleInsert>,
972    table: NonNull<Table>,
973    archetype: NonNull<Archetype>,
974    archetype_move_type: ArchetypeMoveType,
975    change_tick: Tick,
976}
977
978/// The type of archetype move (or lack thereof) that will result from a bundle
979/// being inserted into an entity.
980pub(crate) enum ArchetypeMoveType {
981    /// If the entity already has all of the components that are being inserted,
982    /// its archetype won't change.
983    SameArchetype,
984    /// If only [`sparse set`](StorageType::SparseSet) components are being added,
985    /// the entity's archetype will change while keeping the same table.
986    NewArchetypeSameTable { new_archetype: NonNull<Archetype> },
987    /// If any [`table-stored`](StorageType::Table) components are being added,
988    /// both the entity's archetype and table will change.
989    NewArchetypeNewTable {
990        new_archetype: NonNull<Archetype>,
991        new_table: NonNull<Table>,
992    },
993}
994
995impl<'w> BundleInserter<'w> {
996    #[inline]
997    pub(crate) fn new<T: Bundle>(
998        world: &'w mut World,
999        archetype_id: ArchetypeId,
1000        change_tick: Tick,
1001    ) -> Self {
1002        // SAFETY: These come from the same world. `world.components_registrator` can't be used since we borrow other fields too.
1003        let mut registrator =
1004            unsafe { ComponentsRegistrator::new(&mut world.components, &mut world.component_ids) };
1005        let bundle_id = world
1006            .bundles
1007            .register_info::<T>(&mut registrator, &mut world.storages);
1008        // SAFETY: We just ensured this bundle exists
1009        unsafe { Self::new_with_id(world, archetype_id, bundle_id, change_tick) }
1010    }
1011
1012    /// Creates a new [`BundleInserter`].
1013    ///
1014    /// # Safety
1015    /// - Caller must ensure that `bundle_id` exists in `world.bundles`.
1016    #[inline]
1017    pub(crate) unsafe fn new_with_id(
1018        world: &'w mut World,
1019        archetype_id: ArchetypeId,
1020        bundle_id: BundleId,
1021        change_tick: Tick,
1022    ) -> Self {
1023        // SAFETY: We will not make any accesses to the command queue, component or resource data of this world
1024        let bundle_info = world.bundles.get_unchecked(bundle_id);
1025        let bundle_id = bundle_info.id();
1026        let new_archetype_id = bundle_info.insert_bundle_into_archetype(
1027            &mut world.archetypes,
1028            &mut world.storages,
1029            &world.components,
1030            &world.observers,
1031            archetype_id,
1032        );
1033        if new_archetype_id == archetype_id {
1034            let archetype = &mut world.archetypes[archetype_id];
1035            // SAFETY: The edge is assured to be initialized when we called insert_bundle_into_archetype
1036            let archetype_after_insert = unsafe {
1037                archetype
1038                    .edges()
1039                    .get_archetype_after_bundle_insert_internal(bundle_id)
1040                    .debug_checked_unwrap()
1041            };
1042            let table_id = archetype.table_id();
1043            let table = &mut world.storages.tables[table_id];
1044            Self {
1045                archetype_after_insert: archetype_after_insert.into(),
1046                archetype: archetype.into(),
1047                bundle_info: bundle_info.into(),
1048                table: table.into(),
1049                archetype_move_type: ArchetypeMoveType::SameArchetype,
1050                change_tick,
1051                world: world.as_unsafe_world_cell(),
1052            }
1053        } else {
1054            let (archetype, new_archetype) =
1055                world.archetypes.get_2_mut(archetype_id, new_archetype_id);
1056            // SAFETY: The edge is assured to be initialized when we called insert_bundle_into_archetype
1057            let archetype_after_insert = unsafe {
1058                archetype
1059                    .edges()
1060                    .get_archetype_after_bundle_insert_internal(bundle_id)
1061                    .debug_checked_unwrap()
1062            };
1063            let table_id = archetype.table_id();
1064            let new_table_id = new_archetype.table_id();
1065            if table_id == new_table_id {
1066                let table = &mut world.storages.tables[table_id];
1067                Self {
1068                    archetype_after_insert: archetype_after_insert.into(),
1069                    archetype: archetype.into(),
1070                    bundle_info: bundle_info.into(),
1071                    table: table.into(),
1072                    archetype_move_type: ArchetypeMoveType::NewArchetypeSameTable {
1073                        new_archetype: new_archetype.into(),
1074                    },
1075                    change_tick,
1076                    world: world.as_unsafe_world_cell(),
1077                }
1078            } else {
1079                let (table, new_table) = world.storages.tables.get_2_mut(table_id, new_table_id);
1080                Self {
1081                    archetype_after_insert: archetype_after_insert.into(),
1082                    archetype: archetype.into(),
1083                    bundle_info: bundle_info.into(),
1084                    table: table.into(),
1085                    archetype_move_type: ArchetypeMoveType::NewArchetypeNewTable {
1086                        new_archetype: new_archetype.into(),
1087                        new_table: new_table.into(),
1088                    },
1089                    change_tick,
1090                    world: world.as_unsafe_world_cell(),
1091                }
1092            }
1093        }
1094    }
1095
1096    /// # Safety
1097    /// `entity` must currently exist in the source archetype for this inserter. `location`
1098    /// must be `entity`'s location in the archetype. `T` must match this [`BundleInfo`]'s type
1099    #[inline]
1100    pub(crate) unsafe fn insert<T: DynamicBundle>(
1101        &mut self,
1102        entity: Entity,
1103        location: EntityLocation,
1104        bundle: T,
1105        insert_mode: InsertMode,
1106        caller: MaybeLocation,
1107        relationship_hook_mode: RelationshipHookMode,
1108    ) -> (EntityLocation, T::Effect) {
1109        let bundle_info = self.bundle_info.as_ref();
1110        let archetype_after_insert = self.archetype_after_insert.as_ref();
1111        let archetype = self.archetype.as_ref();
1112
1113        // SAFETY: All components in the bundle are guaranteed to exist in the World
1114        // as they must be initialized before creating the BundleInfo.
1115        unsafe {
1116            // SAFETY: Mutable references do not alias and will be dropped after this block
1117            let mut deferred_world = self.world.into_deferred();
1118
1119            if insert_mode == InsertMode::Replace {
1120                if archetype.has_replace_observer() {
1121                    deferred_world.trigger_observers(
1122                        ON_REPLACE,
1123                        entity,
1124                        archetype_after_insert.iter_existing(),
1125                        caller,
1126                    );
1127                }
1128                deferred_world.trigger_on_replace(
1129                    archetype,
1130                    entity,
1131                    archetype_after_insert.iter_existing(),
1132                    caller,
1133                    relationship_hook_mode,
1134                );
1135            }
1136        }
1137
1138        let table = self.table.as_mut();
1139
1140        // SAFETY: Archetype gets borrowed when running the on_replace observers above,
1141        // so this reference can only be promoted from shared to &mut down here, after they have been ran
1142        let archetype = self.archetype.as_mut();
1143
1144        let (new_archetype, new_location, after_effect) = match &mut self.archetype_move_type {
1145            ArchetypeMoveType::SameArchetype => {
1146                // SAFETY: Mutable references do not alias and will be dropped after this block
1147                let sparse_sets = {
1148                    let world = self.world.world_mut();
1149                    &mut world.storages.sparse_sets
1150                };
1151
1152                let after_effect = bundle_info.write_components(
1153                    table,
1154                    sparse_sets,
1155                    archetype_after_insert,
1156                    archetype_after_insert.required_components.iter(),
1157                    entity,
1158                    location.table_row,
1159                    self.change_tick,
1160                    bundle,
1161                    insert_mode,
1162                    caller,
1163                );
1164
1165                (archetype, location, after_effect)
1166            }
1167            ArchetypeMoveType::NewArchetypeSameTable { new_archetype } => {
1168                let new_archetype = new_archetype.as_mut();
1169
1170                // SAFETY: Mutable references do not alias and will be dropped after this block
1171                let (sparse_sets, entities) = {
1172                    let world = self.world.world_mut();
1173                    (&mut world.storages.sparse_sets, &mut world.entities)
1174                };
1175
1176                let result = archetype.swap_remove(location.archetype_row);
1177                if let Some(swapped_entity) = result.swapped_entity {
1178                    let swapped_location =
1179                        // SAFETY: If the swap was successful, swapped_entity must be valid.
1180                        unsafe { entities.get(swapped_entity).debug_checked_unwrap() };
1181                    entities.set(
1182                        swapped_entity.index(),
1183                        EntityLocation {
1184                            archetype_id: swapped_location.archetype_id,
1185                            archetype_row: location.archetype_row,
1186                            table_id: swapped_location.table_id,
1187                            table_row: swapped_location.table_row,
1188                        },
1189                    );
1190                }
1191                let new_location = new_archetype.allocate(entity, result.table_row);
1192                entities.set(entity.index(), new_location);
1193                let after_effect = bundle_info.write_components(
1194                    table,
1195                    sparse_sets,
1196                    archetype_after_insert,
1197                    archetype_after_insert.required_components.iter(),
1198                    entity,
1199                    result.table_row,
1200                    self.change_tick,
1201                    bundle,
1202                    insert_mode,
1203                    caller,
1204                );
1205
1206                (new_archetype, new_location, after_effect)
1207            }
1208            ArchetypeMoveType::NewArchetypeNewTable {
1209                new_archetype,
1210                new_table,
1211            } => {
1212                let new_table = new_table.as_mut();
1213                let new_archetype = new_archetype.as_mut();
1214
1215                // SAFETY: Mutable references do not alias and will be dropped after this block
1216                let (archetypes_ptr, sparse_sets, entities) = {
1217                    let world = self.world.world_mut();
1218                    let archetype_ptr: *mut Archetype = world.archetypes.archetypes.as_mut_ptr();
1219                    (
1220                        archetype_ptr,
1221                        &mut world.storages.sparse_sets,
1222                        &mut world.entities,
1223                    )
1224                };
1225                let result = archetype.swap_remove(location.archetype_row);
1226                if let Some(swapped_entity) = result.swapped_entity {
1227                    let swapped_location =
1228                        // SAFETY: If the swap was successful, swapped_entity must be valid.
1229                        unsafe { entities.get(swapped_entity).debug_checked_unwrap() };
1230                    entities.set(
1231                        swapped_entity.index(),
1232                        EntityLocation {
1233                            archetype_id: swapped_location.archetype_id,
1234                            archetype_row: location.archetype_row,
1235                            table_id: swapped_location.table_id,
1236                            table_row: swapped_location.table_row,
1237                        },
1238                    );
1239                }
1240                // PERF: store "non bundle" components in edge, then just move those to avoid
1241                // redundant copies
1242                let move_result = table.move_to_superset_unchecked(result.table_row, new_table);
1243                let new_location = new_archetype.allocate(entity, move_result.new_row);
1244                entities.set(entity.index(), new_location);
1245
1246                // If an entity was moved into this entity's table spot, update its table row.
1247                if let Some(swapped_entity) = move_result.swapped_entity {
1248                    let swapped_location =
1249                        // SAFETY: If the swap was successful, swapped_entity must be valid.
1250                        unsafe { entities.get(swapped_entity).debug_checked_unwrap() };
1251
1252                    entities.set(
1253                        swapped_entity.index(),
1254                        EntityLocation {
1255                            archetype_id: swapped_location.archetype_id,
1256                            archetype_row: swapped_location.archetype_row,
1257                            table_id: swapped_location.table_id,
1258                            table_row: result.table_row,
1259                        },
1260                    );
1261
1262                    if archetype.id() == swapped_location.archetype_id {
1263                        archetype
1264                            .set_entity_table_row(swapped_location.archetype_row, result.table_row);
1265                    } else if new_archetype.id() == swapped_location.archetype_id {
1266                        new_archetype
1267                            .set_entity_table_row(swapped_location.archetype_row, result.table_row);
1268                    } else {
1269                        // SAFETY: the only two borrowed archetypes are above and we just did collision checks
1270                        (*archetypes_ptr.add(swapped_location.archetype_id.index()))
1271                            .set_entity_table_row(swapped_location.archetype_row, result.table_row);
1272                    }
1273                }
1274
1275                let after_effect = bundle_info.write_components(
1276                    new_table,
1277                    sparse_sets,
1278                    archetype_after_insert,
1279                    archetype_after_insert.required_components.iter(),
1280                    entity,
1281                    move_result.new_row,
1282                    self.change_tick,
1283                    bundle,
1284                    insert_mode,
1285                    caller,
1286                );
1287
1288                (new_archetype, new_location, after_effect)
1289            }
1290        };
1291
1292        let new_archetype = &*new_archetype;
1293        // SAFETY: We have no outstanding mutable references to world as they were dropped
1294        let mut deferred_world = unsafe { self.world.into_deferred() };
1295
1296        // SAFETY: All components in the bundle are guaranteed to exist in the World
1297        // as they must be initialized before creating the BundleInfo.
1298        unsafe {
1299            deferred_world.trigger_on_add(
1300                new_archetype,
1301                entity,
1302                archetype_after_insert.iter_added(),
1303                caller,
1304            );
1305            if new_archetype.has_add_observer() {
1306                deferred_world.trigger_observers(
1307                    ON_ADD,
1308                    entity,
1309                    archetype_after_insert.iter_added(),
1310                    caller,
1311                );
1312            }
1313            match insert_mode {
1314                InsertMode::Replace => {
1315                    // Insert triggers for both new and existing components if we're replacing them.
1316                    deferred_world.trigger_on_insert(
1317                        new_archetype,
1318                        entity,
1319                        archetype_after_insert.iter_inserted(),
1320                        caller,
1321                        relationship_hook_mode,
1322                    );
1323                    if new_archetype.has_insert_observer() {
1324                        deferred_world.trigger_observers(
1325                            ON_INSERT,
1326                            entity,
1327                            archetype_after_insert.iter_inserted(),
1328                            caller,
1329                        );
1330                    }
1331                }
1332                InsertMode::Keep => {
1333                    // Insert triggers only for new components if we're not replacing them (since
1334                    // nothing is actually inserted).
1335                    deferred_world.trigger_on_insert(
1336                        new_archetype,
1337                        entity,
1338                        archetype_after_insert.iter_added(),
1339                        caller,
1340                        relationship_hook_mode,
1341                    );
1342                    if new_archetype.has_insert_observer() {
1343                        deferred_world.trigger_observers(
1344                            ON_INSERT,
1345                            entity,
1346                            archetype_after_insert.iter_added(),
1347                            caller,
1348                        );
1349                    }
1350                }
1351            }
1352        }
1353
1354        (new_location, after_effect)
1355    }
1356
1357    #[inline]
1358    pub(crate) fn entities(&mut self) -> &mut Entities {
1359        // SAFETY: No outstanding references to self.world, changes to entities cannot invalidate our internal pointers
1360        unsafe { &mut self.world.world_mut().entities }
1361    }
1362}
1363
1364// SAFETY: We have exclusive world access so our pointers can't be invalidated externally
1365pub(crate) struct BundleSpawner<'w> {
1366    world: UnsafeWorldCell<'w>,
1367    bundle_info: ConstNonNull<BundleInfo>,
1368    table: NonNull<Table>,
1369    archetype: NonNull<Archetype>,
1370    change_tick: Tick,
1371}
1372
1373impl<'w> BundleSpawner<'w> {
1374    #[inline]
1375    pub fn new<T: Bundle>(world: &'w mut World, change_tick: Tick) -> Self {
1376        // SAFETY: These come from the same world. `world.components_registrator` can't be used since we borrow other fields too.
1377        let mut registrator =
1378            unsafe { ComponentsRegistrator::new(&mut world.components, &mut world.component_ids) };
1379        let bundle_id = world
1380            .bundles
1381            .register_info::<T>(&mut registrator, &mut world.storages);
1382        // SAFETY: we initialized this bundle_id in `init_info`
1383        unsafe { Self::new_with_id(world, bundle_id, change_tick) }
1384    }
1385
1386    /// Creates a new [`BundleSpawner`].
1387    ///
1388    /// # Safety
1389    /// Caller must ensure that `bundle_id` exists in `world.bundles`
1390    #[inline]
1391    pub(crate) unsafe fn new_with_id(
1392        world: &'w mut World,
1393        bundle_id: BundleId,
1394        change_tick: Tick,
1395    ) -> Self {
1396        let bundle_info = world.bundles.get_unchecked(bundle_id);
1397        let new_archetype_id = bundle_info.insert_bundle_into_archetype(
1398            &mut world.archetypes,
1399            &mut world.storages,
1400            &world.components,
1401            &world.observers,
1402            ArchetypeId::EMPTY,
1403        );
1404        let archetype = &mut world.archetypes[new_archetype_id];
1405        let table = &mut world.storages.tables[archetype.table_id()];
1406        Self {
1407            bundle_info: bundle_info.into(),
1408            table: table.into(),
1409            archetype: archetype.into(),
1410            change_tick,
1411            world: world.as_unsafe_world_cell(),
1412        }
1413    }
1414
1415    #[inline]
1416    pub fn reserve_storage(&mut self, additional: usize) {
1417        // SAFETY: There are no outstanding world references
1418        let (archetype, table) = unsafe { (self.archetype.as_mut(), self.table.as_mut()) };
1419        archetype.reserve(additional);
1420        table.reserve(additional);
1421    }
1422
1423    /// # Safety
1424    /// `entity` must be allocated (but non-existent), `T` must match this [`BundleInfo`]'s type
1425    #[inline]
1426    #[track_caller]
1427    pub unsafe fn spawn_non_existent<T: DynamicBundle>(
1428        &mut self,
1429        entity: Entity,
1430        bundle: T,
1431        caller: MaybeLocation,
1432    ) -> (EntityLocation, T::Effect) {
1433        // SAFETY: We do not make any structural changes to the archetype graph through self.world so these pointers always remain valid
1434        let bundle_info = self.bundle_info.as_ref();
1435        let (location, after_effect) = {
1436            let table = self.table.as_mut();
1437            let archetype = self.archetype.as_mut();
1438
1439            // SAFETY: Mutable references do not alias and will be dropped after this block
1440            let (sparse_sets, entities) = {
1441                let world = self.world.world_mut();
1442                (&mut world.storages.sparse_sets, &mut world.entities)
1443            };
1444            let table_row = table.allocate(entity);
1445            let location = archetype.allocate(entity, table_row);
1446            let after_effect = bundle_info.write_components(
1447                table,
1448                sparse_sets,
1449                &SpawnBundleStatus,
1450                bundle_info.required_components.iter(),
1451                entity,
1452                table_row,
1453                self.change_tick,
1454                bundle,
1455                InsertMode::Replace,
1456                caller,
1457            );
1458            entities.set(entity.index(), location);
1459            (location, after_effect)
1460        };
1461
1462        // SAFETY: We have no outstanding mutable references to world as they were dropped
1463        let mut deferred_world = unsafe { self.world.into_deferred() };
1464        // SAFETY: `DeferredWorld` cannot provide mutable access to `Archetypes`.
1465        let archetype = self.archetype.as_ref();
1466        // SAFETY: All components in the bundle are guaranteed to exist in the World
1467        // as they must be initialized before creating the BundleInfo.
1468        unsafe {
1469            deferred_world.trigger_on_add(
1470                archetype,
1471                entity,
1472                bundle_info.iter_contributed_components(),
1473                caller,
1474            );
1475            if archetype.has_add_observer() {
1476                deferred_world.trigger_observers(
1477                    ON_ADD,
1478                    entity,
1479                    bundle_info.iter_contributed_components(),
1480                    caller,
1481                );
1482            }
1483            deferred_world.trigger_on_insert(
1484                archetype,
1485                entity,
1486                bundle_info.iter_contributed_components(),
1487                caller,
1488                RelationshipHookMode::Run,
1489            );
1490            if archetype.has_insert_observer() {
1491                deferred_world.trigger_observers(
1492                    ON_INSERT,
1493                    entity,
1494                    bundle_info.iter_contributed_components(),
1495                    caller,
1496                );
1497            }
1498        };
1499
1500        (location, after_effect)
1501    }
1502
1503    /// # Safety
1504    /// `T` must match this [`BundleInfo`]'s type
1505    #[inline]
1506    pub unsafe fn spawn<T: Bundle>(
1507        &mut self,
1508        bundle: T,
1509        caller: MaybeLocation,
1510    ) -> (Entity, T::Effect) {
1511        let entity = self.entities().alloc();
1512        // SAFETY: entity is allocated (but non-existent), `T` matches this BundleInfo's type
1513        let (_, after_effect) = unsafe { self.spawn_non_existent(entity, bundle, caller) };
1514        (entity, after_effect)
1515    }
1516
1517    #[inline]
1518    pub(crate) fn entities(&mut self) -> &mut Entities {
1519        // SAFETY: No outstanding references to self.world, changes to entities cannot invalidate our internal pointers
1520        unsafe { &mut self.world.world_mut().entities }
1521    }
1522
1523    /// # Safety
1524    /// - `Self` must be dropped after running this function as it may invalidate internal pointers.
1525    #[inline]
1526    pub(crate) unsafe fn flush_commands(&mut self) {
1527        // SAFETY: pointers on self can be invalidated,
1528        self.world.world_mut().flush();
1529    }
1530}
1531
1532/// Metadata for bundles. Stores a [`BundleInfo`] for each type of [`Bundle`] in a given world.
1533#[derive(Default)]
1534pub struct Bundles {
1535    bundle_infos: Vec<BundleInfo>,
1536    /// Cache static [`BundleId`]
1537    bundle_ids: TypeIdMap<BundleId>,
1538    /// Cache bundles, which contains both explicit and required components of [`Bundle`]
1539    contributed_bundle_ids: TypeIdMap<BundleId>,
1540    /// Cache dynamic [`BundleId`] with multiple components
1541    dynamic_bundle_ids: HashMap<Box<[ComponentId]>, BundleId>,
1542    dynamic_bundle_storages: HashMap<BundleId, Vec<StorageType>>,
1543    /// Cache optimized dynamic [`BundleId`] with single component
1544    dynamic_component_bundle_ids: HashMap<ComponentId, BundleId>,
1545    dynamic_component_storages: HashMap<BundleId, StorageType>,
1546}
1547
1548impl Bundles {
1549    /// The total number of [`Bundle`] registered in [`Storages`].
1550    pub fn len(&self) -> usize {
1551        self.bundle_infos.len()
1552    }
1553
1554    /// Returns true if no [`Bundle`] registered in [`Storages`].
1555    pub fn is_empty(&self) -> bool {
1556        self.len() == 0
1557    }
1558
1559    /// Iterate over [`BundleInfo`].
1560    pub fn iter(&self) -> impl Iterator<Item = &BundleInfo> {
1561        self.bundle_infos.iter()
1562    }
1563
1564    /// Gets the metadata associated with a specific type of bundle.
1565    /// Returns `None` if the bundle is not registered with the world.
1566    #[inline]
1567    pub fn get(&self, bundle_id: BundleId) -> Option<&BundleInfo> {
1568        self.bundle_infos.get(bundle_id.index())
1569    }
1570
1571    /// Gets the value identifying a specific type of bundle.
1572    /// Returns `None` if the bundle does not exist in the world,
1573    /// or if `type_id` does not correspond to a type of bundle.
1574    #[inline]
1575    pub fn get_id(&self, type_id: TypeId) -> Option<BundleId> {
1576        self.bundle_ids.get(&type_id).cloned()
1577    }
1578
1579    /// Registers a new [`BundleInfo`] for a statically known type.
1580    ///
1581    /// Also registers all the components in the bundle.
1582    pub(crate) fn register_info<T: Bundle>(
1583        &mut self,
1584        components: &mut ComponentsRegistrator,
1585        storages: &mut Storages,
1586    ) -> BundleId {
1587        let bundle_infos = &mut self.bundle_infos;
1588        *self.bundle_ids.entry(TypeId::of::<T>()).or_insert_with(|| {
1589            let mut component_ids= Vec::new();
1590            T::component_ids(components, &mut |id| component_ids.push(id));
1591            let id = BundleId(bundle_infos.len());
1592            let bundle_info =
1593                // SAFETY: T::component_id ensures:
1594                // - its info was created
1595                // - appropriate storage for it has been initialized.
1596                // - it was created in the same order as the components in T
1597                unsafe { BundleInfo::new(core::any::type_name::<T>(), storages, components, component_ids, id) };
1598            bundle_infos.push(bundle_info);
1599            id
1600        })
1601    }
1602
1603    /// Registers a new [`BundleInfo`], which contains both explicit and required components for a statically known type.
1604    ///
1605    /// Also registers all the components in the bundle.
1606    pub(crate) fn register_contributed_bundle_info<T: Bundle>(
1607        &mut self,
1608        components: &mut ComponentsRegistrator,
1609        storages: &mut Storages,
1610    ) -> BundleId {
1611        if let Some(id) = self.contributed_bundle_ids.get(&TypeId::of::<T>()).cloned() {
1612            id
1613        } else {
1614            let explicit_bundle_id = self.register_info::<T>(components, storages);
1615            // SAFETY: reading from `explicit_bundle_id` and creating new bundle in same time. Its valid because bundle hashmap allow this
1616            let id = unsafe {
1617                let (ptr, len) = {
1618                    // SAFETY: `explicit_bundle_id` is valid and defined above
1619                    let contributed = self
1620                        .get_unchecked(explicit_bundle_id)
1621                        .contributed_components();
1622                    (contributed.as_ptr(), contributed.len())
1623                };
1624                // SAFETY: this is sound because the contributed_components Vec for explicit_bundle_id will not be accessed mutably as
1625                // part of init_dynamic_info. No mutable references will be created and the allocation will remain valid.
1626                self.init_dynamic_info(storages, components, core::slice::from_raw_parts(ptr, len))
1627            };
1628            self.contributed_bundle_ids.insert(TypeId::of::<T>(), id);
1629            id
1630        }
1631    }
1632
1633    /// # Safety
1634    /// A [`BundleInfo`] with the given [`BundleId`] must have been initialized for this instance of `Bundles`.
1635    pub(crate) unsafe fn get_unchecked(&self, id: BundleId) -> &BundleInfo {
1636        self.bundle_infos.get_unchecked(id.0)
1637    }
1638
1639    /// # Safety
1640    /// This [`BundleId`] must have been initialized with a single [`Component`] (via [`init_component_info`](Self::init_dynamic_info))
1641    pub(crate) unsafe fn get_storage_unchecked(&self, id: BundleId) -> StorageType {
1642        *self
1643            .dynamic_component_storages
1644            .get(&id)
1645            .debug_checked_unwrap()
1646    }
1647
1648    /// # Safety
1649    /// This [`BundleId`] must have been initialized with multiple [`Component`]s (via [`init_dynamic_info`](Self::init_dynamic_info))
1650    pub(crate) unsafe fn get_storages_unchecked(&mut self, id: BundleId) -> &mut Vec<StorageType> {
1651        self.dynamic_bundle_storages
1652            .get_mut(&id)
1653            .debug_checked_unwrap()
1654    }
1655
1656    /// Initializes a new [`BundleInfo`] for a dynamic [`Bundle`].
1657    ///
1658    /// # Panics
1659    ///
1660    /// Panics if any of the provided [`ComponentId`]s do not exist in the
1661    /// provided [`Components`].
1662    pub(crate) fn init_dynamic_info(
1663        &mut self,
1664        storages: &mut Storages,
1665        components: &Components,
1666        component_ids: &[ComponentId],
1667    ) -> BundleId {
1668        let bundle_infos = &mut self.bundle_infos;
1669
1670        // Use `raw_entry_mut` to avoid cloning `component_ids` to access `Entry`
1671        let (_, bundle_id) = self
1672            .dynamic_bundle_ids
1673            .raw_entry_mut()
1674            .from_key(component_ids)
1675            .or_insert_with(|| {
1676                let (id, storages) = initialize_dynamic_bundle(
1677                    bundle_infos,
1678                    storages,
1679                    components,
1680                    Vec::from(component_ids),
1681                );
1682                // SAFETY: The ID always increases when new bundles are added, and so, the ID is unique.
1683                unsafe {
1684                    self.dynamic_bundle_storages
1685                        .insert_unique_unchecked(id, storages);
1686                }
1687                (component_ids.into(), id)
1688            });
1689        *bundle_id
1690    }
1691
1692    /// Initializes a new [`BundleInfo`] for a dynamic [`Bundle`] with single component.
1693    ///
1694    /// # Panics
1695    ///
1696    /// Panics if the provided [`ComponentId`] does not exist in the provided [`Components`].
1697    pub(crate) fn init_component_info(
1698        &mut self,
1699        storages: &mut Storages,
1700        components: &Components,
1701        component_id: ComponentId,
1702    ) -> BundleId {
1703        let bundle_infos = &mut self.bundle_infos;
1704        let bundle_id = self
1705            .dynamic_component_bundle_ids
1706            .entry(component_id)
1707            .or_insert_with(|| {
1708                let (id, storage_type) = initialize_dynamic_bundle(
1709                    bundle_infos,
1710                    storages,
1711                    components,
1712                    vec![component_id],
1713                );
1714                self.dynamic_component_storages.insert(id, storage_type[0]);
1715                id
1716            });
1717        *bundle_id
1718    }
1719}
1720
1721/// Asserts that all components are part of [`Components`]
1722/// and initializes a [`BundleInfo`].
1723fn initialize_dynamic_bundle(
1724    bundle_infos: &mut Vec<BundleInfo>,
1725    storages: &mut Storages,
1726    components: &Components,
1727    component_ids: Vec<ComponentId>,
1728) -> (BundleId, Vec<StorageType>) {
1729    // Assert component existence
1730    let storage_types = component_ids.iter().map(|&id| {
1731        components.get_info(id).unwrap_or_else(|| {
1732            panic!(
1733                "init_dynamic_info called with component id {id:?} which doesn't exist in this world"
1734            )
1735        }).storage_type()
1736    }).collect();
1737
1738    let id = BundleId(bundle_infos.len());
1739    let bundle_info =
1740        // SAFETY: `component_ids` are valid as they were just checked
1741        unsafe { BundleInfo::new("<dynamic bundle>", storages, components, component_ids, id) };
1742    bundle_infos.push(bundle_info);
1743
1744    (id, storage_types)
1745}
1746
1747fn sorted_remove<T: Eq + Ord + Copy>(source: &mut Vec<T>, remove: &[T]) {
1748    let mut remove_index = 0;
1749    source.retain(|value| {
1750        while remove_index < remove.len() && *value > remove[remove_index] {
1751            remove_index += 1;
1752        }
1753
1754        if remove_index < remove.len() {
1755            *value != remove[remove_index]
1756        } else {
1757            true
1758        }
1759    });
1760}
1761
1762#[cfg(test)]
1763mod tests {
1764    use crate::{component::HookContext, prelude::*, world::DeferredWorld};
1765    use alloc::vec;
1766
1767    #[derive(Component)]
1768    struct A;
1769
1770    #[derive(Component)]
1771    #[component(on_add = a_on_add, on_insert = a_on_insert, on_replace = a_on_replace, on_remove = a_on_remove)]
1772    struct AMacroHooks;
1773
1774    fn a_on_add(mut world: DeferredWorld, _: HookContext) {
1775        world.resource_mut::<R>().assert_order(0);
1776    }
1777
1778    fn a_on_insert(mut world: DeferredWorld, _: HookContext) {
1779        world.resource_mut::<R>().assert_order(1);
1780    }
1781
1782    fn a_on_replace(mut world: DeferredWorld, _: HookContext) {
1783        world.resource_mut::<R>().assert_order(2);
1784    }
1785
1786    fn a_on_remove(mut world: DeferredWorld, _: HookContext) {
1787        world.resource_mut::<R>().assert_order(3);
1788    }
1789
1790    #[derive(Component)]
1791    struct B;
1792
1793    #[derive(Component)]
1794    struct C;
1795
1796    #[derive(Component)]
1797    struct D;
1798
1799    #[derive(Component, Eq, PartialEq, Debug)]
1800    struct V(&'static str); // component with a value
1801
1802    #[derive(Resource, Default)]
1803    struct R(usize);
1804
1805    impl R {
1806        #[track_caller]
1807        fn assert_order(&mut self, count: usize) {
1808            assert_eq!(count, self.0);
1809            self.0 += 1;
1810        }
1811    }
1812
1813    #[test]
1814    fn component_hook_order_spawn_despawn() {
1815        let mut world = World::new();
1816        world.init_resource::<R>();
1817        world
1818            .register_component_hooks::<A>()
1819            .on_add(|mut world, _| world.resource_mut::<R>().assert_order(0))
1820            .on_insert(|mut world, _| world.resource_mut::<R>().assert_order(1))
1821            .on_replace(|mut world, _| world.resource_mut::<R>().assert_order(2))
1822            .on_remove(|mut world, _| world.resource_mut::<R>().assert_order(3));
1823
1824        let entity = world.spawn(A).id();
1825        world.despawn(entity);
1826        assert_eq!(4, world.resource::<R>().0);
1827    }
1828
1829    #[test]
1830    fn component_hook_order_spawn_despawn_with_macro_hooks() {
1831        let mut world = World::new();
1832        world.init_resource::<R>();
1833
1834        let entity = world.spawn(AMacroHooks).id();
1835        world.despawn(entity);
1836
1837        assert_eq!(4, world.resource::<R>().0);
1838    }
1839
1840    #[test]
1841    fn component_hook_order_insert_remove() {
1842        let mut world = World::new();
1843        world.init_resource::<R>();
1844        world
1845            .register_component_hooks::<A>()
1846            .on_add(|mut world, _| world.resource_mut::<R>().assert_order(0))
1847            .on_insert(|mut world, _| world.resource_mut::<R>().assert_order(1))
1848            .on_replace(|mut world, _| world.resource_mut::<R>().assert_order(2))
1849            .on_remove(|mut world, _| world.resource_mut::<R>().assert_order(3));
1850
1851        let mut entity = world.spawn_empty();
1852        entity.insert(A);
1853        entity.remove::<A>();
1854        entity.flush();
1855        assert_eq!(4, world.resource::<R>().0);
1856    }
1857
1858    #[test]
1859    fn component_hook_order_replace() {
1860        let mut world = World::new();
1861        world
1862            .register_component_hooks::<A>()
1863            .on_replace(|mut world, _| world.resource_mut::<R>().assert_order(0))
1864            .on_insert(|mut world, _| {
1865                if let Some(mut r) = world.get_resource_mut::<R>() {
1866                    r.assert_order(1);
1867                }
1868            });
1869
1870        let entity = world.spawn(A).id();
1871        world.init_resource::<R>();
1872        let mut entity = world.entity_mut(entity);
1873        entity.insert(A);
1874        entity.insert_if_new(A); // this will not trigger on_replace or on_insert
1875        entity.flush();
1876        assert_eq!(2, world.resource::<R>().0);
1877    }
1878
1879    #[test]
1880    fn component_hook_order_recursive() {
1881        let mut world = World::new();
1882        world.init_resource::<R>();
1883        world
1884            .register_component_hooks::<A>()
1885            .on_add(|mut world, context| {
1886                world.resource_mut::<R>().assert_order(0);
1887                world.commands().entity(context.entity).insert(B);
1888            })
1889            .on_remove(|mut world, context| {
1890                world.resource_mut::<R>().assert_order(2);
1891                world.commands().entity(context.entity).remove::<B>();
1892            });
1893
1894        world
1895            .register_component_hooks::<B>()
1896            .on_add(|mut world, context| {
1897                world.resource_mut::<R>().assert_order(1);
1898                world.commands().entity(context.entity).remove::<A>();
1899            })
1900            .on_remove(|mut world, _| {
1901                world.resource_mut::<R>().assert_order(3);
1902            });
1903
1904        let entity = world.spawn(A).flush();
1905        let entity = world.get_entity(entity).unwrap();
1906        assert!(!entity.contains::<A>());
1907        assert!(!entity.contains::<B>());
1908        assert_eq!(4, world.resource::<R>().0);
1909    }
1910
1911    #[test]
1912    fn component_hook_order_recursive_multiple() {
1913        let mut world = World::new();
1914        world.init_resource::<R>();
1915        world
1916            .register_component_hooks::<A>()
1917            .on_add(|mut world, context| {
1918                world.resource_mut::<R>().assert_order(0);
1919                world.commands().entity(context.entity).insert(B).insert(C);
1920            });
1921
1922        world
1923            .register_component_hooks::<B>()
1924            .on_add(|mut world, context| {
1925                world.resource_mut::<R>().assert_order(1);
1926                world.commands().entity(context.entity).insert(D);
1927            });
1928
1929        world
1930            .register_component_hooks::<C>()
1931            .on_add(|mut world, _| {
1932                world.resource_mut::<R>().assert_order(3);
1933            });
1934
1935        world
1936            .register_component_hooks::<D>()
1937            .on_add(|mut world, _| {
1938                world.resource_mut::<R>().assert_order(2);
1939            });
1940
1941        world.spawn(A).flush();
1942        assert_eq!(4, world.resource::<R>().0);
1943    }
1944
1945    #[test]
1946    fn insert_if_new() {
1947        let mut world = World::new();
1948        let id = world.spawn(V("one")).id();
1949        let mut entity = world.entity_mut(id);
1950        entity.insert_if_new(V("two"));
1951        entity.insert_if_new((A, V("three")));
1952        entity.flush();
1953        // should still contain "one"
1954        let entity = world.entity(id);
1955        assert!(entity.contains::<A>());
1956        assert_eq!(entity.get(), Some(&V("one")));
1957    }
1958
1959    #[test]
1960    fn sorted_remove() {
1961        let mut a = vec![1, 2, 3, 4, 5, 6, 7];
1962        let b = vec![1, 2, 3, 5, 7];
1963        super::sorted_remove(&mut a, &b);
1964
1965        assert_eq!(a, vec![4, 6]);
1966
1967        let mut a = vec![1];
1968        let b = vec![1];
1969        super::sorted_remove(&mut a, &b);
1970
1971        assert_eq!(a, vec![]);
1972
1973        let mut a = vec![1];
1974        let b = vec![2];
1975        super::sorted_remove(&mut a, &b);
1976
1977        assert_eq!(a, vec![1]);
1978    }
1979}