//! Defines the [`World`] and APIs for accessing it directly.12pub(crate) mod command_queue;3mod deferred_world;4mod entity_fetch;5mod entity_ref;6mod filtered_resource;7mod identifier;8mod spawn_batch;910pub mod error;11#[cfg(feature = "bevy_reflect")]12pub mod reflect;13pub mod unsafe_world_cell;1415pub use crate::{16change_detection::{Mut, Ref, CHECK_TICK_THRESHOLD},17world::command_queue::CommandQueue,18};19pub use bevy_ecs_macros::FromWorld;20pub use deferred_world::DeferredWorld;21pub use entity_fetch::{EntityFetcher, WorldEntityFetch};22pub use entity_ref::{23ComponentEntry, DynamicComponentFetch, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,24EntityWorldMut, FilteredEntityMut, FilteredEntityRef, OccupiedComponentEntry,25TryFromFilteredError, VacantComponentEntry,26};27pub use filtered_resource::*;28pub use identifier::WorldId;29pub use spawn_batch::*;3031use crate::{32archetype::{ArchetypeId, Archetypes},33bundle::{34Bundle, BundleEffect, BundleId, BundleInfo, BundleInserter, BundleSpawner, Bundles,35InsertMode, NoBundleEffect,36},37change_detection::{MaybeLocation, MutUntyped, TicksMut},38component::{39CheckChangeTicks, Component, ComponentDescriptor, ComponentId, ComponentIds, ComponentInfo,40ComponentTicks, Components, ComponentsQueuedRegistrator, ComponentsRegistrator, Mutable,41RequiredComponents, RequiredComponentsError, Tick,42},43entity::{Entities, Entity, EntityDoesNotExistError},44entity_disabling::DefaultQueryFilters,45error::{DefaultErrorHandler, ErrorHandler},46event::{BufferedEvent, EventId, Events, WriteBatchIds},47lifecycle::{ComponentHooks, RemovedComponentEvents, ADD, DESPAWN, INSERT, REMOVE, REPLACE},48observer::Observers,49prelude::{Add, Despawn, Insert, Remove, Replace},50query::{DebugCheckedUnwrap, QueryData, QueryFilter, QueryState},51relationship::RelationshipHookMode,52resource::Resource,53schedule::{Schedule, ScheduleLabel, Schedules},54storage::{ResourceData, Storages},55system::Commands,56world::{57command_queue::RawCommandQueue,58error::{59EntityDespawnError, EntityMutableFetchError, TryInsertBatchError, TryRunScheduleError,60},61},62};63use alloc::{boxed::Box, vec::Vec};64use bevy_platform::sync::atomic::{AtomicU32, Ordering};65use bevy_ptr::{OwningPtr, Ptr, UnsafeCellDeref};66use bevy_utils::prelude::DebugName;67use core::{any::TypeId, fmt};68use log::warn;69use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell};7071/// Stores and exposes operations on [entities](Entity), [components](Component), resources,72/// and their associated metadata.73///74/// Each [`Entity`] has a set of unique components, based on their type.75/// Entity components can be created, updated, removed, and queried using a given76///77/// For complex access patterns involving [`SystemParam`](crate::system::SystemParam),78/// consider using [`SystemState`](crate::system::SystemState).79///80/// To mutate different parts of the world simultaneously,81/// use [`World::resource_scope`] or [`SystemState`](crate::system::SystemState).82///83/// ## Resources84///85/// Worlds can also store [`Resource`]s,86/// which are unique instances of a given type that don't belong to a specific Entity.87/// There are also *non send resources*, which can only be accessed on the main thread.88/// See [`Resource`] for usage.89pub struct World {90id: WorldId,91pub(crate) entities: Entities,92pub(crate) components: Components,93pub(crate) component_ids: ComponentIds,94pub(crate) archetypes: Archetypes,95pub(crate) storages: Storages,96pub(crate) bundles: Bundles,97pub(crate) observers: Observers,98pub(crate) removed_components: RemovedComponentEvents,99pub(crate) change_tick: AtomicU32,100pub(crate) last_change_tick: Tick,101pub(crate) last_check_tick: Tick,102pub(crate) last_trigger_id: u32,103pub(crate) command_queue: RawCommandQueue,104}105106impl Default for World {107fn default() -> Self {108let mut world = Self {109id: WorldId::new().expect("More `bevy` `World`s have been created than is supported"),110entities: Entities::new(),111components: Default::default(),112archetypes: Archetypes::new(),113storages: Default::default(),114bundles: Default::default(),115observers: Observers::default(),116removed_components: Default::default(),117// Default value is `1`, and `last_change_tick`s default to `0`, such that changes118// are detected on first system runs and for direct world queries.119change_tick: AtomicU32::new(1),120last_change_tick: Tick::new(0),121last_check_tick: Tick::new(0),122last_trigger_id: 0,123command_queue: RawCommandQueue::new(),124component_ids: ComponentIds::default(),125};126world.bootstrap();127world128}129}130131impl Drop for World {132fn drop(&mut self) {133// SAFETY: Not passing a pointer so the argument is always valid134unsafe { self.command_queue.apply_or_drop_queued(None) };135// SAFETY: Pointers in internal command queue are only invalidated here136drop(unsafe { Box::from_raw(self.command_queue.bytes.as_ptr()) });137// SAFETY: Pointers in internal command queue are only invalidated here138drop(unsafe { Box::from_raw(self.command_queue.cursor.as_ptr()) });139// SAFETY: Pointers in internal command queue are only invalidated here140drop(unsafe { Box::from_raw(self.command_queue.panic_recovery.as_ptr()) });141}142}143144impl World {145/// This performs initialization that _must_ happen for every [`World`] immediately upon creation (such as claiming specific component ids).146/// This _must_ be run as part of constructing a [`World`], before it is returned to the caller.147#[inline]148fn bootstrap(&mut self) {149// The order that we register these events is vital to ensure that the constants are correct!150let on_add = self.register_event_key::<Add>();151assert_eq!(ADD, on_add);152153let on_insert = self.register_event_key::<Insert>();154assert_eq!(INSERT, on_insert);155156let on_replace = self.register_event_key::<Replace>();157assert_eq!(REPLACE, on_replace);158159let on_remove = self.register_event_key::<Remove>();160assert_eq!(REMOVE, on_remove);161162let on_despawn = self.register_event_key::<Despawn>();163assert_eq!(DESPAWN, on_despawn);164165// This sets up `Disabled` as a disabling component, via the FromWorld impl166self.init_resource::<DefaultQueryFilters>();167}168/// Creates a new empty [`World`].169///170/// # Panics171///172/// If [`usize::MAX`] [`World`]s have been created.173/// This guarantee allows System Parameters to safely uniquely identify a [`World`],174/// since its [`WorldId`] is unique175#[inline]176pub fn new() -> World {177World::default()178}179180/// Retrieves this [`World`]'s unique ID181#[inline]182pub fn id(&self) -> WorldId {183self.id184}185186/// Creates a new [`UnsafeWorldCell`] view with complete read+write access.187#[inline]188pub fn as_unsafe_world_cell(&mut self) -> UnsafeWorldCell<'_> {189UnsafeWorldCell::new_mutable(self)190}191192/// Creates a new [`UnsafeWorldCell`] view with only read access to everything.193#[inline]194pub fn as_unsafe_world_cell_readonly(&self) -> UnsafeWorldCell<'_> {195UnsafeWorldCell::new_readonly(self)196}197198/// Retrieves this world's [`Entities`] collection.199#[inline]200pub fn entities(&self) -> &Entities {201&self.entities202}203204/// Retrieves this world's [`Entities`] collection mutably.205///206/// # Safety207/// Mutable reference must not be used to put the [`Entities`] data208/// in an invalid state for this [`World`]209#[inline]210pub unsafe fn entities_mut(&mut self) -> &mut Entities {211&mut self.entities212}213214/// Retrieves this world's [`Archetypes`] collection.215#[inline]216pub fn archetypes(&self) -> &Archetypes {217&self.archetypes218}219220/// Retrieves this world's [`Components`] collection.221#[inline]222pub fn components(&self) -> &Components {223&self.components224}225226/// Prepares a [`ComponentsQueuedRegistrator`] for the world.227/// **NOTE:** [`ComponentsQueuedRegistrator`] is easily misused.228/// See its docs for important notes on when and how it should be used.229#[inline]230pub fn components_queue(&self) -> ComponentsQueuedRegistrator<'_> {231// SAFETY: These are from the same world.232unsafe { ComponentsQueuedRegistrator::new(&self.components, &self.component_ids) }233}234235/// Prepares a [`ComponentsRegistrator`] for the world.236#[inline]237pub fn components_registrator(&mut self) -> ComponentsRegistrator<'_> {238// SAFETY: These are from the same world.239unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) }240}241242/// Retrieves this world's [`Storages`] collection.243#[inline]244pub fn storages(&self) -> &Storages {245&self.storages246}247248/// Retrieves this world's [`Bundles`] collection.249#[inline]250pub fn bundles(&self) -> &Bundles {251&self.bundles252}253254/// Retrieves this world's [`RemovedComponentEvents`] collection255#[inline]256pub fn removed_components(&self) -> &RemovedComponentEvents {257&self.removed_components258}259260/// Retrieves this world's [`Observers`] list261#[inline]262pub fn observers(&self) -> &Observers {263&self.observers264}265266/// Creates a new [`Commands`] instance that writes to the world's command queue267/// Use [`World::flush`] to apply all queued commands268#[inline]269pub fn commands(&mut self) -> Commands<'_, '_> {270// SAFETY: command_queue is stored on world and always valid while the world exists271unsafe { Commands::new_raw_from_entities(self.command_queue.clone(), &self.entities) }272}273274/// Registers a new [`Component`] type and returns the [`ComponentId`] created for it.275///276/// # Usage Notes277/// In most cases, you don't need to call this method directly since component registration278/// happens automatically during system initialization.279pub fn register_component<T: Component>(&mut self) -> ComponentId {280self.components_registrator().register_component::<T>()281}282283/// Registers a component type as "disabling",284/// using [default query filters](DefaultQueryFilters) to exclude entities with the component from queries.285pub fn register_disabling_component<C: Component>(&mut self) {286let component_id = self.register_component::<C>();287let mut dqf = self.resource_mut::<DefaultQueryFilters>();288dqf.register_disabling_component(component_id);289}290291/// Returns a mutable reference to the [`ComponentHooks`] for a [`Component`] type.292///293/// Will panic if `T` exists in any archetypes.294#[must_use]295pub fn register_component_hooks<T: Component>(&mut self) -> &mut ComponentHooks {296let index = self.register_component::<T>();297assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(index)), "Components hooks cannot be modified if the component already exists in an archetype, use register_component if {} may already be in use", core::any::type_name::<T>());298// SAFETY: We just created this component299unsafe { self.components.get_hooks_mut(index).debug_checked_unwrap() }300}301302/// Returns a mutable reference to the [`ComponentHooks`] for a [`Component`] with the given id if it exists.303///304/// Will panic if `id` exists in any archetypes.305pub fn register_component_hooks_by_id(306&mut self,307id: ComponentId,308) -> Option<&mut ComponentHooks> {309assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(id)), "Components hooks cannot be modified if the component already exists in an archetype, use register_component if the component with id {id:?} may already be in use");310self.components.get_hooks_mut(id)311}312313/// Registers the given component `R` as a [required component] for `T`.314///315/// When `T` is added to an entity, `R` and its own required components will also be added316/// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.317/// If a custom constructor is desired, use [`World::register_required_components_with`] instead.318///319/// For the non-panicking version, see [`World::try_register_required_components`].320///321/// Note that requirements must currently be registered before `T` is inserted into the world322/// for the first time. This limitation may be fixed in the future.323///324/// [required component]: Component#required-components325///326/// # Panics327///328/// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added329/// on an entity before the registration.330///331/// Indirect requirements through other components are allowed. In those cases, any existing requirements332/// will only be overwritten if the new requirement is more specific.333///334/// # Example335///336/// ```337/// # use bevy_ecs::prelude::*;338/// #[derive(Component)]339/// struct A;340///341/// #[derive(Component, Default, PartialEq, Eq, Debug)]342/// struct B(usize);343///344/// #[derive(Component, Default, PartialEq, Eq, Debug)]345/// struct C(u32);346///347/// # let mut world = World::default();348/// // Register B as required by A and C as required by B.349/// world.register_required_components::<A, B>();350/// world.register_required_components::<B, C>();351///352/// // This will implicitly also insert B and C with their Default constructors.353/// let id = world.spawn(A).id();354/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());355/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());356/// ```357pub fn register_required_components<T: Component, R: Component + Default>(&mut self) {358self.try_register_required_components::<T, R>().unwrap();359}360361/// Registers the given component `R` as a [required component] for `T`.362///363/// When `T` is added to an entity, `R` and its own required components will also be added364/// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.365/// If a [`Default`] constructor is desired, use [`World::register_required_components`] instead.366///367/// For the non-panicking version, see [`World::try_register_required_components_with`].368///369/// Note that requirements must currently be registered before `T` is inserted into the world370/// for the first time. This limitation may be fixed in the future.371///372/// [required component]: Component#required-components373///374/// # Panics375///376/// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added377/// on an entity before the registration.378///379/// Indirect requirements through other components are allowed. In those cases, any existing requirements380/// will only be overwritten if the new requirement is more specific.381///382/// # Example383///384/// ```385/// # use bevy_ecs::prelude::*;386/// #[derive(Component)]387/// struct A;388///389/// #[derive(Component, Default, PartialEq, Eq, Debug)]390/// struct B(usize);391///392/// #[derive(Component, PartialEq, Eq, Debug)]393/// struct C(u32);394///395/// # let mut world = World::default();396/// // Register B and C as required by A and C as required by B.397/// // A requiring C directly will overwrite the indirect requirement through B.398/// world.register_required_components::<A, B>();399/// world.register_required_components_with::<B, C>(|| C(1));400/// world.register_required_components_with::<A, C>(|| C(2));401///402/// // This will implicitly also insert B with its Default constructor and C403/// // with the custom constructor defined by A.404/// let id = world.spawn(A).id();405/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());406/// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());407/// ```408pub fn register_required_components_with<T: Component, R: Component>(409&mut self,410constructor: fn() -> R,411) {412self.try_register_required_components_with::<T, R>(constructor)413.unwrap();414}415416/// Tries to register the given component `R` as a [required component] for `T`.417///418/// When `T` is added to an entity, `R` and its own required components will also be added419/// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.420/// If a custom constructor is desired, use [`World::register_required_components_with`] instead.421///422/// For the panicking version, see [`World::register_required_components`].423///424/// Note that requirements must currently be registered before `T` is inserted into the world425/// for the first time. This limitation may be fixed in the future.426///427/// [required component]: Component#required-components428///429/// # Errors430///431/// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added432/// on an entity before the registration.433///434/// Indirect requirements through other components are allowed. In those cases, any existing requirements435/// will only be overwritten if the new requirement is more specific.436///437/// # Example438///439/// ```440/// # use bevy_ecs::prelude::*;441/// #[derive(Component)]442/// struct A;443///444/// #[derive(Component, Default, PartialEq, Eq, Debug)]445/// struct B(usize);446///447/// #[derive(Component, Default, PartialEq, Eq, Debug)]448/// struct C(u32);449///450/// # let mut world = World::default();451/// // Register B as required by A and C as required by B.452/// world.register_required_components::<A, B>();453/// world.register_required_components::<B, C>();454///455/// // Duplicate registration! This will fail.456/// assert!(world.try_register_required_components::<A, B>().is_err());457///458/// // This will implicitly also insert B and C with their Default constructors.459/// let id = world.spawn(A).id();460/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());461/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());462/// ```463pub fn try_register_required_components<T: Component, R: Component + Default>(464&mut self,465) -> Result<(), RequiredComponentsError> {466self.try_register_required_components_with::<T, R>(R::default)467}468469/// Tries to register the given component `R` as a [required component] for `T`.470///471/// When `T` is added to an entity, `R` and its own required components will also be added472/// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.473/// If a [`Default`] constructor is desired, use [`World::register_required_components`] instead.474///475/// For the panicking version, see [`World::register_required_components_with`].476///477/// Note that requirements must currently be registered before `T` is inserted into the world478/// for the first time. This limitation may be fixed in the future.479///480/// [required component]: Component#required-components481///482/// # Errors483///484/// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added485/// on an entity before the registration.486///487/// Indirect requirements through other components are allowed. In those cases, any existing requirements488/// will only be overwritten if the new requirement is more specific.489///490/// # Example491///492/// ```493/// # use bevy_ecs::prelude::*;494/// #[derive(Component)]495/// struct A;496///497/// #[derive(Component, Default, PartialEq, Eq, Debug)]498/// struct B(usize);499///500/// #[derive(Component, PartialEq, Eq, Debug)]501/// struct C(u32);502///503/// # let mut world = World::default();504/// // Register B and C as required by A and C as required by B.505/// // A requiring C directly will overwrite the indirect requirement through B.506/// world.register_required_components::<A, B>();507/// world.register_required_components_with::<B, C>(|| C(1));508/// world.register_required_components_with::<A, C>(|| C(2));509///510/// // Duplicate registration! Even if the constructors were different, this would fail.511/// assert!(world.try_register_required_components_with::<B, C>(|| C(1)).is_err());512///513/// // This will implicitly also insert B with its Default constructor and C514/// // with the custom constructor defined by A.515/// let id = world.spawn(A).id();516/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());517/// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());518/// ```519pub fn try_register_required_components_with<T: Component, R: Component>(520&mut self,521constructor: fn() -> R,522) -> Result<(), RequiredComponentsError> {523let requiree = self.register_component::<T>();524525// TODO: Remove this panic and update archetype edges accordingly when required components are added526if self.archetypes().component_index().contains_key(&requiree) {527return Err(RequiredComponentsError::ArchetypeExists(requiree));528}529530let required = self.register_component::<R>();531532// SAFETY: We just created the `required` and `requiree` components.533unsafe {534self.components535.register_required_components::<R>(requiree, required, constructor)536}537}538539/// Retrieves the [required components](RequiredComponents) for the given component type, if it exists.540pub fn get_required_components<C: Component>(&self) -> Option<&RequiredComponents> {541let id = self.components().valid_component_id::<C>()?;542let component_info = self.components().get_info(id)?;543Some(component_info.required_components())544}545546/// Retrieves the [required components](RequiredComponents) for the component of the given [`ComponentId`], if it exists.547pub fn get_required_components_by_id(&self, id: ComponentId) -> Option<&RequiredComponents> {548let component_info = self.components().get_info(id)?;549Some(component_info.required_components())550}551552/// Registers a new [`Component`] type and returns the [`ComponentId`] created for it.553///554/// This method differs from [`World::register_component`] in that it uses a [`ComponentDescriptor`]555/// to register the new component type instead of statically available type information. This556/// enables the dynamic registration of new component definitions at runtime for advanced use cases.557///558/// While the option to register a component from a descriptor is useful in type-erased559/// contexts, the standard [`World::register_component`] function should always be used instead560/// when type information is available at compile time.561pub fn register_component_with_descriptor(562&mut self,563descriptor: ComponentDescriptor,564) -> ComponentId {565self.components_registrator()566.register_component_with_descriptor(descriptor)567}568569/// Returns the [`ComponentId`] of the given [`Component`] type `T`.570///571/// The returned `ComponentId` is specific to the `World` instance572/// it was retrieved from and should not be used with another `World` instance.573///574/// Returns [`None`] if the `Component` type has not yet been initialized within575/// the `World` using [`World::register_component`].576///577/// ```578/// use bevy_ecs::prelude::*;579///580/// let mut world = World::new();581///582/// #[derive(Component)]583/// struct ComponentA;584///585/// let component_a_id = world.register_component::<ComponentA>();586///587/// assert_eq!(component_a_id, world.component_id::<ComponentA>().unwrap())588/// ```589///590/// # See also591///592/// * [`ComponentIdFor`](crate::component::ComponentIdFor)593/// * [`Components::component_id()`]594/// * [`Components::get_id()`]595#[inline]596pub fn component_id<T: Component>(&self) -> Option<ComponentId> {597self.components.component_id::<T>()598}599600/// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.601///602/// The [`Resource`] doesn't have a value in the [`World`], it's only registered. If you want603/// to insert the [`Resource`] in the [`World`], use [`World::init_resource`] or604/// [`World::insert_resource`] instead.605pub fn register_resource<R: Resource>(&mut self) -> ComponentId {606self.components_registrator().register_resource::<R>()607}608609/// Returns the [`ComponentId`] of the given [`Resource`] type `T`.610///611/// The returned [`ComponentId`] is specific to the [`World`] instance it was retrieved from612/// and should not be used with another [`World`] instance.613///614/// Returns [`None`] if the [`Resource`] type has not yet been initialized within the615/// [`World`] using [`World::register_resource`], [`World::init_resource`] or [`World::insert_resource`].616pub fn resource_id<T: Resource>(&self) -> Option<ComponentId> {617self.components.get_resource_id(TypeId::of::<T>())618}619620/// Returns [`EntityRef`]s that expose read-only operations for the given621/// `entities`. This will panic if any of the given entities do not exist. Use622/// [`World::get_entity`] if you want to check for entity existence instead623/// of implicitly panicking.624///625/// This function supports fetching a single entity or multiple entities:626/// - Pass an [`Entity`] to receive a single [`EntityRef`].627/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].628/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.629///630/// # Panics631///632/// If any of the given `entities` do not exist in the world.633///634/// # Examples635///636/// ## Single [`Entity`]637///638/// ```639/// # use bevy_ecs::prelude::*;640/// #[derive(Component)]641/// struct Position {642/// x: f32,643/// y: f32,644/// }645///646/// let mut world = World::new();647/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();648///649/// let position = world.entity(entity).get::<Position>().unwrap();650/// assert_eq!(position.x, 0.0);651/// ```652///653/// ## Array of [`Entity`]s654///655/// ```656/// # use bevy_ecs::prelude::*;657/// #[derive(Component)]658/// struct Position {659/// x: f32,660/// y: f32,661/// }662///663/// let mut world = World::new();664/// let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();665/// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();666///667/// let [e1_ref, e2_ref] = world.entity([e1, e2]);668/// let e1_position = e1_ref.get::<Position>().unwrap();669/// assert_eq!(e1_position.x, 0.0);670/// let e2_position = e2_ref.get::<Position>().unwrap();671/// assert_eq!(e2_position.x, 1.0);672/// ```673///674/// ## Slice of [`Entity`]s675///676/// ```677/// # use bevy_ecs::prelude::*;678/// #[derive(Component)]679/// struct Position {680/// x: f32,681/// y: f32,682/// }683///684/// let mut world = World::new();685/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();686/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();687/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();688///689/// let ids = vec![e1, e2, e3];690/// for eref in world.entity(&ids[..]) {691/// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);692/// }693/// ```694///695/// ## [`EntityHashSet`](crate::entity::EntityHashSet)696///697/// ```698/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};699/// #[derive(Component)]700/// struct Position {701/// x: f32,702/// y: f32,703/// }704///705/// let mut world = World::new();706/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();707/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();708/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();709///710/// let ids = EntityHashSet::from_iter([e1, e2, e3]);711/// for (_id, eref) in world.entity(&ids) {712/// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);713/// }714/// ```715///716/// [`EntityHashSet`]: crate::entity::EntityHashSet717#[inline]718#[track_caller]719pub fn entity<F: WorldEntityFetch>(&self, entities: F) -> F::Ref<'_> {720#[inline(never)]721#[cold]722#[track_caller]723fn panic_no_entity(world: &World, entity: Entity) -> ! {724panic!(725"Entity {entity} {}",726world.entities.entity_does_not_exist_error_details(entity)727);728}729730match self.get_entity(entities) {731Ok(fetched) => fetched,732Err(error) => panic_no_entity(self, error.entity),733}734}735736/// Returns [`EntityMut`]s that expose read and write operations for the737/// given `entities`. This will panic if any of the given entities do not738/// exist. Use [`World::get_entity_mut`] if you want to check for entity739/// existence instead of implicitly panicking.740///741/// This function supports fetching a single entity or multiple entities:742/// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].743/// - This reference type allows for structural changes to the entity,744/// such as adding or removing components, or despawning the entity.745/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].746/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.747/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an748/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).749///750/// In order to perform structural changes on the returned entity reference,751/// such as adding or removing components, or despawning the entity, only a752/// single [`Entity`] can be passed to this function. Allowing multiple753/// entities at the same time with structural access would lead to undefined754/// behavior, so [`EntityMut`] is returned when requesting multiple entities.755///756/// # Panics757///758/// If any of the given `entities` do not exist in the world.759///760/// # Examples761///762/// ## Single [`Entity`]763///764/// ```765/// # use bevy_ecs::prelude::*;766/// #[derive(Component)]767/// struct Position {768/// x: f32,769/// y: f32,770/// }771///772/// let mut world = World::new();773/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();774///775/// let mut entity_mut = world.entity_mut(entity);776/// let mut position = entity_mut.get_mut::<Position>().unwrap();777/// position.y = 1.0;778/// assert_eq!(position.x, 0.0);779/// entity_mut.despawn();780/// # assert!(world.get_entity_mut(entity).is_err());781/// ```782///783/// ## Array of [`Entity`]s784///785/// ```786/// # use bevy_ecs::prelude::*;787/// #[derive(Component)]788/// struct Position {789/// x: f32,790/// y: f32,791/// }792///793/// let mut world = World::new();794/// let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();795/// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();796///797/// let [mut e1_ref, mut e2_ref] = world.entity_mut([e1, e2]);798/// let mut e1_position = e1_ref.get_mut::<Position>().unwrap();799/// e1_position.x = 1.0;800/// assert_eq!(e1_position.x, 1.0);801/// let mut e2_position = e2_ref.get_mut::<Position>().unwrap();802/// e2_position.x = 2.0;803/// assert_eq!(e2_position.x, 2.0);804/// ```805///806/// ## Slice of [`Entity`]s807///808/// ```809/// # use bevy_ecs::prelude::*;810/// #[derive(Component)]811/// struct Position {812/// x: f32,813/// y: f32,814/// }815///816/// let mut world = World::new();817/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();818/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();819/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();820///821/// let ids = vec![e1, e2, e3];822/// for mut eref in world.entity_mut(&ids[..]) {823/// let mut pos = eref.get_mut::<Position>().unwrap();824/// pos.y = 2.0;825/// assert_eq!(pos.y, 2.0);826/// }827/// ```828///829/// ## [`EntityHashSet`](crate::entity::EntityHashSet)830///831/// ```832/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};833/// #[derive(Component)]834/// struct Position {835/// x: f32,836/// y: f32,837/// }838///839/// let mut world = World::new();840/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();841/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();842/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();843///844/// let ids = EntityHashSet::from_iter([e1, e2, e3]);845/// for (_id, mut eref) in world.entity_mut(&ids) {846/// let mut pos = eref.get_mut::<Position>().unwrap();847/// pos.y = 2.0;848/// assert_eq!(pos.y, 2.0);849/// }850/// ```851///852/// [`EntityHashSet`]: crate::entity::EntityHashSet853#[inline]854#[track_caller]855pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::Mut<'_> {856#[inline(never)]857#[cold]858#[track_caller]859fn panic_on_err(e: EntityMutableFetchError) -> ! {860panic!("{e}");861}862863match self.get_entity_mut(entities) {864Ok(fetched) => fetched,865Err(e) => panic_on_err(e),866}867}868869/// Returns the components of an [`Entity`] through [`ComponentInfo`].870#[inline]871pub fn inspect_entity(872&self,873entity: Entity,874) -> Result<impl Iterator<Item = &ComponentInfo>, EntityDoesNotExistError> {875let entity_location = self876.entities()877.get(entity)878.ok_or(EntityDoesNotExistError::new(entity, self.entities()))?;879880let archetype = self881.archetypes()882.get(entity_location.archetype_id)883.expect("ArchetypeId was retrieved from an EntityLocation and should correspond to an Archetype");884885Ok(archetype886.iter_components()887.filter_map(|id| self.components().get_info(id)))888}889890/// Returns [`EntityRef`]s that expose read-only operations for the given891/// `entities`, returning [`Err`] if any of the given entities do not exist.892/// Instead of immediately unwrapping the value returned from this function,893/// prefer [`World::entity`].894///895/// This function supports fetching a single entity or multiple entities:896/// - Pass an [`Entity`] to receive a single [`EntityRef`].897/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].898/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.899/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an900/// [`EntityHashMap<EntityRef>`](crate::entity::EntityHashMap).901///902/// # Errors903///904/// If any of the given `entities` do not exist in the world, the first905/// [`Entity`] found to be missing will return an [`EntityDoesNotExistError`].906///907/// # Examples908///909/// For examples, see [`World::entity`].910///911/// [`EntityHashSet`]: crate::entity::EntityHashSet912#[inline]913pub fn get_entity<F: WorldEntityFetch>(914&self,915entities: F,916) -> Result<F::Ref<'_>, EntityDoesNotExistError> {917let cell = self.as_unsafe_world_cell_readonly();918// SAFETY: `&self` gives read access to the entire world, and prevents mutable access.919unsafe { entities.fetch_ref(cell) }920}921922/// Returns [`EntityMut`]s that expose read and write operations for the923/// given `entities`, returning [`Err`] if any of the given entities do not924/// exist. Instead of immediately unwrapping the value returned from this925/// function, prefer [`World::entity_mut`].926///927/// This function supports fetching a single entity or multiple entities:928/// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].929/// - This reference type allows for structural changes to the entity,930/// such as adding or removing components, or despawning the entity.931/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].932/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.933/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an934/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).935///936/// In order to perform structural changes on the returned entity reference,937/// such as adding or removing components, or despawning the entity, only a938/// single [`Entity`] can be passed to this function. Allowing multiple939/// entities at the same time with structural access would lead to undefined940/// behavior, so [`EntityMut`] is returned when requesting multiple entities.941///942/// # Errors943///944/// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if any of the given `entities` do not exist in the world.945/// - Only the first entity found to be missing will be returned.946/// - Returns [`EntityMutableFetchError::AliasedMutability`] if the same entity is requested multiple times.947///948/// # Examples949///950/// For examples, see [`World::entity_mut`].951///952/// [`EntityHashSet`]: crate::entity::EntityHashSet953#[inline]954pub fn get_entity_mut<F: WorldEntityFetch>(955&mut self,956entities: F,957) -> Result<F::Mut<'_>, EntityMutableFetchError> {958let cell = self.as_unsafe_world_cell();959// SAFETY: `&mut self` gives mutable access to the entire world,960// and prevents any other access to the world.961unsafe { entities.fetch_mut(cell) }962}963964/// Returns an [`Entity`] iterator of current entities.965///966/// This is useful in contexts where you only have read-only access to the [`World`].967#[deprecated(since = "0.17.0", note = "use world.query::<EntityRef>()` instead")]968#[inline]969pub fn iter_entities(&self) -> impl Iterator<Item = EntityRef<'_>> + '_ {970self.archetypes.iter().flat_map(|archetype| {971archetype972.entities_with_location()973.map(|(entity, location)| {974// SAFETY: entity exists and location accurately specifies the archetype where the entity is stored.975let cell = UnsafeEntityCell::new(976self.as_unsafe_world_cell_readonly(),977entity,978location,979self.last_change_tick,980self.read_change_tick(),981);982// SAFETY: `&self` gives read access to the entire world.983unsafe { EntityRef::new(cell) }984})985})986}987988/// Returns a mutable iterator over all entities in the `World`.989#[deprecated(since = "0.17.0", note = "use world.query::<EntityMut>()` instead")]990pub fn iter_entities_mut(&mut self) -> impl Iterator<Item = EntityMut<'_>> + '_ {991let last_change_tick = self.last_change_tick;992let change_tick = self.change_tick();993let world_cell = self.as_unsafe_world_cell();994world_cell.archetypes().iter().flat_map(move |archetype| {995archetype996.entities_with_location()997.map(move |(entity, location)| {998// SAFETY: entity exists and location accurately specifies the archetype where the entity is stored.999let cell = UnsafeEntityCell::new(1000world_cell,1001entity,1002location,1003last_change_tick,1004change_tick,1005);1006// SAFETY: We have exclusive access to the entire world. We only create one borrow for each entity,1007// so none will conflict with one another.1008unsafe { EntityMut::new(cell) }1009})1010})1011}10121013/// Simultaneously provides access to entity data and a command queue, which1014/// will be applied when the world is next flushed.1015///1016/// This allows using borrowed entity data to construct commands where the1017/// borrow checker would otherwise prevent it.1018///1019/// See [`DeferredWorld::entities_and_commands`] for the deferred version.1020///1021/// # Example1022///1023/// ```rust1024/// # use bevy_ecs::{prelude::*, world::DeferredWorld};1025/// #[derive(Component)]1026/// struct Targets(Vec<Entity>);1027/// #[derive(Component)]1028/// struct TargetedBy(Entity);1029///1030/// let mut world: World = // ...1031/// # World::new();1032/// # let e1 = world.spawn_empty().id();1033/// # let e2 = world.spawn_empty().id();1034/// # let eid = world.spawn(Targets(vec![e1, e2])).id();1035/// let (entities, mut commands) = world.entities_and_commands();1036///1037/// let entity = entities.get(eid).unwrap();1038/// for &target in entity.get::<Targets>().unwrap().0.iter() {1039/// commands.entity(target).insert(TargetedBy(eid));1040/// }1041/// # world.flush();1042/// # assert_eq!(world.get::<TargetedBy>(e1).unwrap().0, eid);1043/// # assert_eq!(world.get::<TargetedBy>(e2).unwrap().0, eid);1044/// ```1045pub fn entities_and_commands(&mut self) -> (EntityFetcher<'_>, Commands<'_, '_>) {1046let cell = self.as_unsafe_world_cell();1047// SAFETY: `&mut self` gives mutable access to the entire world, and prevents simultaneous access.1048let fetcher = unsafe { EntityFetcher::new(cell) };1049// SAFETY:1050// - `&mut self` gives mutable access to the entire world, and prevents simultaneous access.1051// - Command queue access does not conflict with entity access.1052let raw_queue = unsafe { cell.get_raw_command_queue() };1053// SAFETY: `&mut self` ensures the commands does not outlive the world.1054let commands = unsafe { Commands::new_raw_from_entities(raw_queue, cell.entities()) };10551056(fetcher, commands)1057}10581059/// Spawns a new [`Entity`] and returns a corresponding [`EntityWorldMut`], which can be used1060/// to add components to the entity or retrieve its id.1061///1062/// ```1063/// use bevy_ecs::{component::Component, world::World};1064///1065/// #[derive(Component)]1066/// struct Position {1067/// x: f32,1068/// y: f32,1069/// }1070/// #[derive(Component)]1071/// struct Label(&'static str);1072/// #[derive(Component)]1073/// struct Num(u32);1074///1075/// let mut world = World::new();1076/// let entity = world.spawn_empty()1077/// .insert(Position { x: 0.0, y: 0.0 }) // add a single component1078/// .insert((Num(1), Label("hello"))) // add a bundle of components1079/// .id();1080///1081/// let position = world.entity(entity).get::<Position>().unwrap();1082/// assert_eq!(position.x, 0.0);1083/// ```1084#[track_caller]1085pub fn spawn_empty(&mut self) -> EntityWorldMut<'_> {1086self.flush();1087let entity = self.entities.alloc();1088// SAFETY: entity was just allocated1089unsafe { self.spawn_at_empty_internal(entity, MaybeLocation::caller()) }1090}10911092/// Spawns a new [`Entity`] with a given [`Bundle`] of [components](`Component`) and returns1093/// a corresponding [`EntityWorldMut`], which can be used to add components to the entity or1094/// retrieve its id. In case large batches of entities need to be spawned, consider using1095/// [`World::spawn_batch`] instead.1096///1097/// ```1098/// use bevy_ecs::{bundle::Bundle, component::Component, world::World};1099///1100/// #[derive(Component)]1101/// struct Position {1102/// x: f32,1103/// y: f32,1104/// }1105///1106/// #[derive(Component)]1107/// struct Velocity {1108/// x: f32,1109/// y: f32,1110/// };1111///1112/// #[derive(Component)]1113/// struct Name(&'static str);1114///1115/// #[derive(Bundle)]1116/// struct PhysicsBundle {1117/// position: Position,1118/// velocity: Velocity,1119/// }1120///1121/// let mut world = World::new();1122///1123/// // `spawn` can accept a single component:1124/// world.spawn(Position { x: 0.0, y: 0.0 });1125///1126/// // It can also accept a tuple of components:1127/// world.spawn((1128/// Position { x: 0.0, y: 0.0 },1129/// Velocity { x: 1.0, y: 1.0 },1130/// ));1131///1132/// // Or it can accept a pre-defined Bundle of components:1133/// world.spawn(PhysicsBundle {1134/// position: Position { x: 2.0, y: 2.0 },1135/// velocity: Velocity { x: 0.0, y: 4.0 },1136/// });1137///1138/// let entity = world1139/// // Tuples can also mix Bundles and Components1140/// .spawn((1141/// PhysicsBundle {1142/// position: Position { x: 2.0, y: 2.0 },1143/// velocity: Velocity { x: 0.0, y: 4.0 },1144/// },1145/// Name("Elaina Proctor"),1146/// ))1147/// // Calling id() will return the unique identifier for the spawned entity1148/// .id();1149/// let position = world.entity(entity).get::<Position>().unwrap();1150/// assert_eq!(position.x, 2.0);1151/// ```1152#[track_caller]1153pub fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityWorldMut<'_> {1154self.spawn_with_caller(bundle, MaybeLocation::caller())1155}11561157pub(crate) fn spawn_with_caller<B: Bundle>(1158&mut self,1159bundle: B,1160caller: MaybeLocation,1161) -> EntityWorldMut<'_> {1162self.flush();1163let change_tick = self.change_tick();1164let entity = self.entities.alloc();1165let mut bundle_spawner = BundleSpawner::new::<B>(self, change_tick);1166// SAFETY: bundle's type matches `bundle_info`, entity is allocated but non-existent1167let (entity_location, after_effect) =1168unsafe { bundle_spawner.spawn_non_existent(entity, bundle, caller) };11691170let mut entity_location = Some(entity_location);11711172// SAFETY: command_queue is not referenced anywhere else1173if !unsafe { self.command_queue.is_empty() } {1174self.flush();1175entity_location = self.entities().get(entity);1176}11771178// SAFETY: entity and location are valid, as they were just created above1179let mut entity = unsafe { EntityWorldMut::new(self, entity, entity_location) };1180after_effect.apply(&mut entity);1181entity1182}11831184/// # Safety1185/// must be called on an entity that was just allocated1186unsafe fn spawn_at_empty_internal(1187&mut self,1188entity: Entity,1189caller: MaybeLocation,1190) -> EntityWorldMut<'_> {1191let archetype = self.archetypes.empty_mut();1192// PERF: consider avoiding allocating entities in the empty archetype unless needed1193let table_row = self.storages.tables[archetype.table_id()].allocate(entity);1194// SAFETY: no components are allocated by archetype.allocate() because the archetype is1195// empty1196let location = unsafe { archetype.allocate(entity, table_row) };1197let change_tick = self.change_tick();1198self.entities.set(entity.index(), Some(location));1199self.entities1200.mark_spawn_despawn(entity.index(), caller, change_tick);12011202EntityWorldMut::new(self, entity, Some(location))1203}12041205/// Spawns a batch of entities with the same component [`Bundle`] type. Takes a given1206/// [`Bundle`] iterator and returns a corresponding [`Entity`] iterator.1207/// This is more efficient than spawning entities and adding components to them individually1208/// using [`World::spawn`], but it is limited to spawning entities with the same [`Bundle`]1209/// type, whereas spawning individually is more flexible.1210///1211/// ```1212/// use bevy_ecs::{component::Component, entity::Entity, world::World};1213///1214/// #[derive(Component)]1215/// struct Str(&'static str);1216/// #[derive(Component)]1217/// struct Num(u32);1218///1219/// let mut world = World::new();1220/// let entities = world.spawn_batch(vec![1221/// (Str("a"), Num(0)), // the first entity1222/// (Str("b"), Num(1)), // the second entity1223/// ]).collect::<Vec<Entity>>();1224///1225/// assert_eq!(entities.len(), 2);1226/// ```1227#[track_caller]1228pub fn spawn_batch<I>(&mut self, iter: I) -> SpawnBatchIter<'_, I::IntoIter>1229where1230I: IntoIterator,1231I::Item: Bundle<Effect: NoBundleEffect>,1232{1233SpawnBatchIter::new(self, iter.into_iter(), MaybeLocation::caller())1234}12351236/// Retrieves a reference to the given `entity`'s [`Component`] of the given type.1237/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1238/// ```1239/// use bevy_ecs::{component::Component, world::World};1240///1241/// #[derive(Component)]1242/// struct Position {1243/// x: f32,1244/// y: f32,1245/// }1246///1247/// let mut world = World::new();1248/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1249/// let position = world.get::<Position>(entity).unwrap();1250/// assert_eq!(position.x, 0.0);1251/// ```1252#[inline]1253pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {1254self.get_entity(entity).ok()?.get()1255}12561257/// Retrieves a mutable reference to the given `entity`'s [`Component`] of the given type.1258/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1259/// ```1260/// use bevy_ecs::{component::Component, world::World};1261///1262/// #[derive(Component)]1263/// struct Position {1264/// x: f32,1265/// y: f32,1266/// }1267///1268/// let mut world = World::new();1269/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1270/// let mut position = world.get_mut::<Position>(entity).unwrap();1271/// position.x = 1.0;1272/// ```1273#[inline]1274pub fn get_mut<T: Component<Mutability = Mutable>>(1275&mut self,1276entity: Entity,1277) -> Option<Mut<'_, T>> {1278self.get_entity_mut(entity).ok()?.into_mut()1279}12801281/// Temporarily removes a [`Component`] `T` from the provided [`Entity`] and1282/// runs the provided closure on it, returning the result if `T` was available.1283/// This will trigger the `Remove` and `Replace` component hooks without1284/// causing an archetype move.1285///1286/// This is most useful with immutable components, where removal and reinsertion1287/// is the only way to modify a value.1288///1289/// If you do not need to ensure the above hooks are triggered, and your component1290/// is mutable, prefer using [`get_mut`](World::get_mut).1291///1292/// # Examples1293///1294/// ```rust1295/// # use bevy_ecs::prelude::*;1296/// #1297/// #[derive(Component, PartialEq, Eq, Debug)]1298/// #[component(immutable)]1299/// struct Foo(bool);1300///1301/// # let mut world = World::default();1302/// # world.register_component::<Foo>();1303/// #1304/// # let entity = world.spawn(Foo(false)).id();1305/// #1306/// world.modify_component(entity, |foo: &mut Foo| {1307/// foo.0 = true;1308/// });1309/// #1310/// # assert_eq!(world.get::<Foo>(entity), Some(&Foo(true)));1311/// ```1312#[inline]1313#[track_caller]1314pub fn modify_component<T: Component, R>(1315&mut self,1316entity: Entity,1317f: impl FnOnce(&mut T) -> R,1318) -> Result<Option<R>, EntityMutableFetchError> {1319let mut world = DeferredWorld::from(&mut *self);13201321let result = world.modify_component_with_relationship_hook_mode(1322entity,1323RelationshipHookMode::Run,1324f,1325)?;13261327self.flush();1328Ok(result)1329}13301331/// Temporarily removes a [`Component`] identified by the provided1332/// [`ComponentId`] from the provided [`Entity`] and runs the provided1333/// closure on it, returning the result if the component was available.1334/// This will trigger the `Remove` and `Replace` component hooks without1335/// causing an archetype move.1336///1337/// This is most useful with immutable components, where removal and reinsertion1338/// is the only way to modify a value.1339///1340/// If you do not need to ensure the above hooks are triggered, and your component1341/// is mutable, prefer using [`get_mut_by_id`](World::get_mut_by_id).1342///1343/// You should prefer the typed [`modify_component`](World::modify_component)1344/// whenever possible.1345#[inline]1346#[track_caller]1347pub fn modify_component_by_id<R>(1348&mut self,1349entity: Entity,1350component_id: ComponentId,1351f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,1352) -> Result<Option<R>, EntityMutableFetchError> {1353let mut world = DeferredWorld::from(&mut *self);13541355let result = world.modify_component_by_id_with_relationship_hook_mode(1356entity,1357component_id,1358RelationshipHookMode::Run,1359f,1360)?;13611362self.flush();1363Ok(result)1364}13651366/// Despawns the given [`Entity`], if it exists. This will also remove all of the entity's1367/// [`Components`](Component).1368///1369/// Returns `true` if the entity is successfully despawned and `false` if1370/// the entity does not exist.1371///1372/// # Note1373///1374/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1375/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1376///1377/// ```1378/// use bevy_ecs::{component::Component, world::World};1379///1380/// #[derive(Component)]1381/// struct Position {1382/// x: f32,1383/// y: f32,1384/// }1385///1386/// let mut world = World::new();1387/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1388/// assert!(world.despawn(entity));1389/// assert!(world.get_entity(entity).is_err());1390/// assert!(world.get::<Position>(entity).is_none());1391/// ```1392#[track_caller]1393#[inline]1394pub fn despawn(&mut self, entity: Entity) -> bool {1395if let Err(error) = self.despawn_with_caller(entity, MaybeLocation::caller()) {1396warn!("{error}");1397false1398} else {1399true1400}1401}14021403/// Despawns the given `entity`, if it exists. This will also remove all of the entity's1404/// [`Components`](Component).1405///1406/// Returns an [`EntityDespawnError`] if the entity does not exist.1407///1408/// # Note1409///1410/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1411/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1412#[track_caller]1413#[inline]1414pub fn try_despawn(&mut self, entity: Entity) -> Result<(), EntityDespawnError> {1415self.despawn_with_caller(entity, MaybeLocation::caller())1416}14171418#[inline]1419pub(crate) fn despawn_with_caller(1420&mut self,1421entity: Entity,1422caller: MaybeLocation,1423) -> Result<(), EntityDespawnError> {1424self.flush();1425let entity = self.get_entity_mut(entity)?;1426entity.despawn_with_caller(caller);1427Ok(())1428}14291430/// Clears the internal component tracker state.1431///1432/// The world maintains some internal state about changed and removed components. This state1433/// is used by [`RemovedComponents`] to provide access to the entities that had a specific type1434/// of component removed since last tick.1435///1436/// The state is also used for change detection when accessing components and resources outside1437/// of a system, for example via [`World::get_mut()`] or [`World::get_resource_mut()`].1438///1439/// By clearing this internal state, the world "forgets" about those changes, allowing a new round1440/// of detection to be recorded.1441///1442/// When using `bevy_ecs` as part of the full Bevy engine, this method is called automatically1443/// by `bevy_app::App::update` and `bevy_app::SubApp::update`, so you don't need to call it manually.1444/// When using `bevy_ecs` as a separate standalone crate however, you do need to call this manually.1445///1446/// ```1447/// # use bevy_ecs::prelude::*;1448/// # #[derive(Component, Default)]1449/// # struct Transform;1450/// // a whole new world1451/// let mut world = World::new();1452///1453/// // you changed it1454/// let entity = world.spawn(Transform::default()).id();1455///1456/// // change is detected1457/// let transform = world.get_mut::<Transform>(entity).unwrap();1458/// assert!(transform.is_changed());1459///1460/// // update the last change tick1461/// world.clear_trackers();1462///1463/// // change is no longer detected1464/// let transform = world.get_mut::<Transform>(entity).unwrap();1465/// assert!(!transform.is_changed());1466/// ```1467///1468/// [`RemovedComponents`]: crate::lifecycle::RemovedComponents1469pub fn clear_trackers(&mut self) {1470self.removed_components.update();1471self.last_change_tick = self.increment_change_tick();1472}14731474/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1475/// run queries on the [`World`] by storing and reusing the [`QueryState`].1476/// ```1477/// use bevy_ecs::{component::Component, entity::Entity, world::World};1478///1479/// #[derive(Component, Debug, PartialEq)]1480/// struct Position {1481/// x: f32,1482/// y: f32,1483/// }1484///1485/// #[derive(Component)]1486/// struct Velocity {1487/// x: f32,1488/// y: f32,1489/// }1490///1491/// let mut world = World::new();1492/// let entities = world.spawn_batch(vec![1493/// (Position { x: 0.0, y: 0.0}, Velocity { x: 1.0, y: 0.0 }),1494/// (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }),1495/// ]).collect::<Vec<Entity>>();1496///1497/// let mut query = world.query::<(&mut Position, &Velocity)>();1498/// for (mut position, velocity) in query.iter_mut(&mut world) {1499/// position.x += velocity.x;1500/// position.y += velocity.y;1501/// }1502///1503/// assert_eq!(world.get::<Position>(entities[0]).unwrap(), &Position { x: 1.0, y: 0.0 });1504/// assert_eq!(world.get::<Position>(entities[1]).unwrap(), &Position { x: 0.0, y: 1.0 });1505/// ```1506///1507/// To iterate over entities in a deterministic order,1508/// sort the results of the query using the desired component as a key.1509/// Note that this requires fetching the whole result set from the query1510/// and allocation of a [`Vec`] to store it.1511///1512/// ```1513/// use bevy_ecs::{component::Component, entity::Entity, world::World};1514///1515/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Debug)]1516/// struct Order(i32);1517/// #[derive(Component, PartialEq, Debug)]1518/// struct Label(&'static str);1519///1520/// let mut world = World::new();1521/// let a = world.spawn((Order(2), Label("second"))).id();1522/// let b = world.spawn((Order(3), Label("third"))).id();1523/// let c = world.spawn((Order(1), Label("first"))).id();1524/// let mut entities = world.query::<(Entity, &Order, &Label)>()1525/// .iter(&world)1526/// .collect::<Vec<_>>();1527/// // Sort the query results by their `Order` component before comparing1528/// // to expected results. Query iteration order should not be relied on.1529/// entities.sort_by_key(|e| e.1);1530/// assert_eq!(entities, vec![1531/// (c, &Order(1), &Label("first")),1532/// (a, &Order(2), &Label("second")),1533/// (b, &Order(3), &Label("third")),1534/// ]);1535/// ```1536#[inline]1537pub fn query<D: QueryData>(&mut self) -> QueryState<D, ()> {1538self.query_filtered::<D, ()>()1539}15401541/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1542/// run queries on the [`World`] by storing and reusing the [`QueryState`].1543/// ```1544/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1545///1546/// #[derive(Component)]1547/// struct A;1548/// #[derive(Component)]1549/// struct B;1550///1551/// let mut world = World::new();1552/// let e1 = world.spawn(A).id();1553/// let e2 = world.spawn((A, B)).id();1554///1555/// let mut query = world.query_filtered::<Entity, With<B>>();1556/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1557///1558/// assert_eq!(matching_entities, vec![e2]);1559/// ```1560#[inline]1561pub fn query_filtered<D: QueryData, F: QueryFilter>(&mut self) -> QueryState<D, F> {1562QueryState::new(self)1563}15641565/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1566/// run queries on the [`World`] by storing and reusing the [`QueryState`].1567/// ```1568/// use bevy_ecs::{component::Component, entity::Entity, world::World};1569///1570/// #[derive(Component, Debug, PartialEq)]1571/// struct Position {1572/// x: f32,1573/// y: f32,1574/// }1575///1576/// let mut world = World::new();1577/// world.spawn_batch(vec![1578/// Position { x: 0.0, y: 0.0 },1579/// Position { x: 1.0, y: 1.0 },1580/// ]);1581///1582/// fn get_positions(world: &World) -> Vec<(Entity, &Position)> {1583/// let mut query = world.try_query::<(Entity, &Position)>().unwrap();1584/// query.iter(world).collect()1585/// }1586///1587/// let positions = get_positions(&world);1588///1589/// assert_eq!(world.get::<Position>(positions[0].0).unwrap(), positions[0].1);1590/// assert_eq!(world.get::<Position>(positions[1].0).unwrap(), positions[1].1);1591/// ```1592///1593/// Requires only an immutable world reference, but may fail if, for example,1594/// the components that make up this query have not been registered into the world.1595/// ```1596/// use bevy_ecs::{component::Component, entity::Entity, world::World};1597///1598/// #[derive(Component)]1599/// struct A;1600///1601/// let mut world = World::new();1602///1603/// let none_query = world.try_query::<&A>();1604/// assert!(none_query.is_none());1605///1606/// world.register_component::<A>();1607///1608/// let some_query = world.try_query::<&A>();1609/// assert!(some_query.is_some());1610/// ```1611#[inline]1612pub fn try_query<D: QueryData>(&self) -> Option<QueryState<D, ()>> {1613self.try_query_filtered::<D, ()>()1614}16151616/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1617/// run queries on the [`World`] by storing and reusing the [`QueryState`].1618/// ```1619/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1620///1621/// #[derive(Component)]1622/// struct A;1623/// #[derive(Component)]1624/// struct B;1625///1626/// let mut world = World::new();1627/// let e1 = world.spawn(A).id();1628/// let e2 = world.spawn((A, B)).id();1629///1630/// let mut query = world.try_query_filtered::<Entity, With<B>>().unwrap();1631/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1632///1633/// assert_eq!(matching_entities, vec![e2]);1634/// ```1635///1636/// Requires only an immutable world reference, but may fail if, for example,1637/// the components that make up this query have not been registered into the world.1638#[inline]1639pub fn try_query_filtered<D: QueryData, F: QueryFilter>(&self) -> Option<QueryState<D, F>> {1640QueryState::try_new(self)1641}16421643/// Returns an iterator of entities that had components of type `T` removed1644/// since the last call to [`World::clear_trackers`].1645pub fn removed<T: Component>(&self) -> impl Iterator<Item = Entity> + '_ {1646self.components1647.get_valid_id(TypeId::of::<T>())1648.map(|component_id| self.removed_with_id(component_id))1649.into_iter()1650.flatten()1651}16521653/// Returns an iterator of entities that had components with the given `component_id` removed1654/// since the last call to [`World::clear_trackers`].1655pub fn removed_with_id(&self, component_id: ComponentId) -> impl Iterator<Item = Entity> + '_ {1656self.removed_components1657.get(component_id)1658.map(|removed| removed.iter_current_update_events().cloned())1659.into_iter()1660.flatten()1661.map(Into::into)1662}16631664/// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.1665///1666/// This enables the dynamic registration of new [`Resource`] definitions at runtime for1667/// advanced use cases.1668///1669/// # Note1670///1671/// Registering a [`Resource`] does not insert it into [`World`]. For insertion, you could use1672/// [`World::insert_resource_by_id`].1673pub fn register_resource_with_descriptor(1674&mut self,1675descriptor: ComponentDescriptor,1676) -> ComponentId {1677self.components_registrator()1678.register_resource_with_descriptor(descriptor)1679}16801681/// Initializes a new resource and returns the [`ComponentId`] created for it.1682///1683/// If the resource already exists, nothing happens.1684///1685/// The value given by the [`FromWorld::from_world`] method will be used.1686/// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],1687/// and those default values will be here instead.1688#[inline]1689#[track_caller]1690pub fn init_resource<R: Resource + FromWorld>(&mut self) -> ComponentId {1691let caller = MaybeLocation::caller();1692let component_id = self.components_registrator().register_resource::<R>();1693if self1694.storages1695.resources1696.get(component_id)1697.is_none_or(|data| !data.is_present())1698{1699let value = R::from_world(self);1700OwningPtr::make(value, |ptr| {1701// SAFETY: component_id was just initialized and corresponds to resource of type R.1702unsafe {1703self.insert_resource_by_id(component_id, ptr, caller);1704}1705});1706}1707component_id1708}17091710/// Inserts a new resource with the given `value`.1711///1712/// Resources are "unique" data of a given type.1713/// If you insert a resource of a type that already exists,1714/// you will overwrite any existing data.1715#[inline]1716#[track_caller]1717pub fn insert_resource<R: Resource>(&mut self, value: R) {1718self.insert_resource_with_caller(value, MaybeLocation::caller());1719}17201721/// Split into a new function so we can pass the calling location into the function when using1722/// as a command.1723#[inline]1724pub(crate) fn insert_resource_with_caller<R: Resource>(1725&mut self,1726value: R,1727caller: MaybeLocation,1728) {1729let component_id = self.components_registrator().register_resource::<R>();1730OwningPtr::make(value, |ptr| {1731// SAFETY: component_id was just initialized and corresponds to resource of type R.1732unsafe {1733self.insert_resource_by_id(component_id, ptr, caller);1734}1735});1736}17371738/// Initializes a new non-send resource and returns the [`ComponentId`] created for it.1739///1740/// If the resource already exists, nothing happens.1741///1742/// The value given by the [`FromWorld::from_world`] method will be used.1743/// Note that any resource with the `Default` trait automatically implements `FromWorld`,1744/// and those default values will be here instead.1745///1746/// # Panics1747///1748/// Panics if called from a thread other than the main thread.1749#[inline]1750#[track_caller]1751pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> ComponentId {1752let caller = MaybeLocation::caller();1753let component_id = self.components_registrator().register_non_send::<R>();1754if self1755.storages1756.non_send_resources1757.get(component_id)1758.is_none_or(|data| !data.is_present())1759{1760let value = R::from_world(self);1761OwningPtr::make(value, |ptr| {1762// SAFETY: component_id was just initialized and corresponds to resource of type R.1763unsafe {1764self.insert_non_send_by_id(component_id, ptr, caller);1765}1766});1767}1768component_id1769}17701771/// Inserts a new non-send resource with the given `value`.1772///1773/// `NonSend` resources cannot be sent across threads,1774/// and do not need the `Send + Sync` bounds.1775/// Systems with `NonSend` resources are always scheduled on the main thread.1776///1777/// # Panics1778/// If a value is already present, this function will panic if called1779/// from a different thread than where the original value was inserted from.1780#[inline]1781#[track_caller]1782pub fn insert_non_send_resource<R: 'static>(&mut self, value: R) {1783let caller = MaybeLocation::caller();1784let component_id = self.components_registrator().register_non_send::<R>();1785OwningPtr::make(value, |ptr| {1786// SAFETY: component_id was just initialized and corresponds to resource of type R.1787unsafe {1788self.insert_non_send_by_id(component_id, ptr, caller);1789}1790});1791}17921793/// Removes the resource of a given type and returns it, if it exists. Otherwise returns `None`.1794#[inline]1795pub fn remove_resource<R: Resource>(&mut self) -> Option<R> {1796let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;1797let (ptr, _, _) = self.storages.resources.get_mut(component_id)?.remove()?;1798// SAFETY: `component_id` was gotten via looking up the `R` type1799unsafe { Some(ptr.read::<R>()) }1800}18011802/// Removes a `!Send` resource from the world and returns it, if present.1803///1804/// `NonSend` resources cannot be sent across threads,1805/// and do not need the `Send + Sync` bounds.1806/// Systems with `NonSend` resources are always scheduled on the main thread.1807///1808/// Returns `None` if a value was not previously present.1809///1810/// # Panics1811/// If a value is present, this function will panic if called from a different1812/// thread than where the value was inserted from.1813#[inline]1814pub fn remove_non_send_resource<R: 'static>(&mut self) -> Option<R> {1815let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;1816let (ptr, _, _) = self1817.storages1818.non_send_resources1819.get_mut(component_id)?1820.remove()?;1821// SAFETY: `component_id` was gotten via looking up the `R` type1822unsafe { Some(ptr.read::<R>()) }1823}18241825/// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.1826#[inline]1827pub fn contains_resource<R: Resource>(&self) -> bool {1828self.components1829.get_valid_resource_id(TypeId::of::<R>())1830.and_then(|component_id| self.storages.resources.get(component_id))1831.is_some_and(ResourceData::is_present)1832}18331834/// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.1835#[inline]1836pub fn contains_resource_by_id(&self, component_id: ComponentId) -> bool {1837self.storages1838.resources1839.get(component_id)1840.is_some_and(ResourceData::is_present)1841}18421843/// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.1844#[inline]1845pub fn contains_non_send<R: 'static>(&self) -> bool {1846self.components1847.get_valid_resource_id(TypeId::of::<R>())1848.and_then(|component_id| self.storages.non_send_resources.get(component_id))1849.is_some_and(ResourceData::is_present)1850}18511852/// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.1853#[inline]1854pub fn contains_non_send_by_id(&self, component_id: ComponentId) -> bool {1855self.storages1856.non_send_resources1857.get(component_id)1858.is_some_and(ResourceData::is_present)1859}18601861/// Returns `true` if a resource of type `R` exists and was added since the world's1862/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1863///1864/// This means that:1865/// - When called from an exclusive system, this will check for additions since the system last ran.1866/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]1867/// was called.1868pub fn is_resource_added<R: Resource>(&self) -> bool {1869self.components1870.get_valid_resource_id(TypeId::of::<R>())1871.is_some_and(|component_id| self.is_resource_added_by_id(component_id))1872}18731874/// Returns `true` if a resource with id `component_id` exists and was added since the world's1875/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1876///1877/// This means that:1878/// - When called from an exclusive system, this will check for additions since the system last ran.1879/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]1880/// was called.1881pub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool {1882self.storages1883.resources1884.get(component_id)1885.is_some_and(|resource| {1886resource.get_ticks().is_some_and(|ticks| {1887ticks.is_added(self.last_change_tick(), self.read_change_tick())1888})1889})1890}18911892/// Returns `true` if a resource of type `R` exists and was modified since the world's1893/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1894///1895/// This means that:1896/// - When called from an exclusive system, this will check for changes since the system last ran.1897/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]1898/// was called.1899pub fn is_resource_changed<R: Resource>(&self) -> bool {1900self.components1901.get_valid_resource_id(TypeId::of::<R>())1902.is_some_and(|component_id| self.is_resource_changed_by_id(component_id))1903}19041905/// Returns `true` if a resource with id `component_id` exists and was modified since the world's1906/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1907///1908/// This means that:1909/// - When called from an exclusive system, this will check for changes since the system last ran.1910/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]1911/// was called.1912pub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool {1913self.storages1914.resources1915.get(component_id)1916.is_some_and(|resource| {1917resource.get_ticks().is_some_and(|ticks| {1918ticks.is_changed(self.last_change_tick(), self.read_change_tick())1919})1920})1921}19221923/// Retrieves the change ticks for the given resource.1924pub fn get_resource_change_ticks<R: Resource>(&self) -> Option<ComponentTicks> {1925self.components1926.get_valid_resource_id(TypeId::of::<R>())1927.and_then(|component_id| self.get_resource_change_ticks_by_id(component_id))1928}19291930/// Retrieves the change ticks for the given [`ComponentId`].1931///1932/// **You should prefer to use the typed API [`World::get_resource_change_ticks`] where possible.**1933pub fn get_resource_change_ticks_by_id(1934&self,1935component_id: ComponentId,1936) -> Option<ComponentTicks> {1937self.storages1938.resources1939.get(component_id)1940.and_then(ResourceData::get_ticks)1941}19421943/// Gets a reference to the resource of the given type1944///1945/// # Panics1946///1947/// Panics if the resource does not exist.1948/// Use [`get_resource`](World::get_resource) instead if you want to handle this case.1949///1950/// If you want to instead insert a value if the resource does not exist,1951/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).1952#[inline]1953#[track_caller]1954pub fn resource<R: Resource>(&self) -> &R {1955match self.get_resource() {1956Some(x) => x,1957None => panic!(1958"Requested resource {} does not exist in the `World`.1959Did you forget to add it using `app.insert_resource` / `app.init_resource`?1960Resources are also implicitly added via `app.add_event`,1961and can be added by plugins.",1962DebugName::type_name::<R>()1963),1964}1965}19661967/// Gets a reference to the resource of the given type1968///1969/// # Panics1970///1971/// Panics if the resource does not exist.1972/// Use [`get_resource_ref`](World::get_resource_ref) instead if you want to handle this case.1973///1974/// If you want to instead insert a value if the resource does not exist,1975/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).1976#[inline]1977#[track_caller]1978pub fn resource_ref<R: Resource>(&self) -> Ref<'_, R> {1979match self.get_resource_ref() {1980Some(x) => x,1981None => panic!(1982"Requested resource {} does not exist in the `World`.1983Did you forget to add it using `app.insert_resource` / `app.init_resource`?1984Resources are also implicitly added via `app.add_event`,1985and can be added by plugins.",1986DebugName::type_name::<R>()1987),1988}1989}19901991/// Gets a mutable reference to the resource of the given type1992///1993/// # Panics1994///1995/// Panics if the resource does not exist.1996/// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.1997///1998/// If you want to instead insert a value if the resource does not exist,1999/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2000#[inline]2001#[track_caller]2002pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {2003match self.get_resource_mut() {2004Some(x) => x,2005None => panic!(2006"Requested resource {} does not exist in the `World`.2007Did you forget to add it using `app.insert_resource` / `app.init_resource`?2008Resources are also implicitly added via `app.add_event`,2009and can be added by plugins.",2010DebugName::type_name::<R>()2011),2012}2013}20142015/// Gets a reference to the resource of the given type if it exists2016#[inline]2017pub fn get_resource<R: Resource>(&self) -> Option<&R> {2018// SAFETY:2019// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2020// - `&self` ensures nothing in world is borrowed mutably2021unsafe { self.as_unsafe_world_cell_readonly().get_resource() }2022}20232024/// Gets a reference including change detection to the resource of the given type if it exists.2025#[inline]2026pub fn get_resource_ref<R: Resource>(&self) -> Option<Ref<'_, R>> {2027// SAFETY:2028// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2029// - `&self` ensures nothing in world is borrowed mutably2030unsafe { self.as_unsafe_world_cell_readonly().get_resource_ref() }2031}20322033/// Gets a mutable reference to the resource of the given type if it exists2034#[inline]2035pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {2036// SAFETY:2037// - `as_unsafe_world_cell` gives permission to access everything mutably2038// - `&mut self` ensures nothing in world is borrowed2039unsafe { self.as_unsafe_world_cell().get_resource_mut() }2040}20412042/// Gets a mutable reference to the resource of type `T` if it exists,2043/// otherwise inserts the resource using the result of calling `func`.2044///2045/// # Example2046///2047/// ```2048/// # use bevy_ecs::prelude::*;2049/// #2050/// #[derive(Resource)]2051/// struct MyResource(i32);2052///2053/// # let mut world = World::new();2054/// let my_res = world.get_resource_or_insert_with(|| MyResource(10));2055/// assert_eq!(my_res.0, 10);2056/// ```2057#[inline]2058#[track_caller]2059pub fn get_resource_or_insert_with<R: Resource>(2060&mut self,2061func: impl FnOnce() -> R,2062) -> Mut<'_, R> {2063let caller = MaybeLocation::caller();2064let change_tick = self.change_tick();2065let last_change_tick = self.last_change_tick();20662067let component_id = self.components_registrator().register_resource::<R>();2068let data = self.initialize_resource_internal(component_id);2069if !data.is_present() {2070OwningPtr::make(func(), |ptr| {2071// SAFETY: component_id was just initialized and corresponds to resource of type R.2072unsafe {2073data.insert(ptr, change_tick, caller);2074}2075});2076}20772078// SAFETY: The resource must be present, as we would have inserted it if it was empty.2079let data = unsafe {2080data.get_mut(last_change_tick, change_tick)2081.debug_checked_unwrap()2082};2083// SAFETY: The underlying type of the resource is `R`.2084unsafe { data.with_type::<R>() }2085}20862087/// Gets a mutable reference to the resource of type `T` if it exists,2088/// otherwise initializes the resource by calling its [`FromWorld`]2089/// implementation.2090///2091/// # Example2092///2093/// ```2094/// # use bevy_ecs::prelude::*;2095/// #2096/// #[derive(Resource)]2097/// struct Foo(i32);2098///2099/// impl Default for Foo {2100/// fn default() -> Self {2101/// Self(15)2102/// }2103/// }2104///2105/// #[derive(Resource)]2106/// struct MyResource(i32);2107///2108/// impl FromWorld for MyResource {2109/// fn from_world(world: &mut World) -> Self {2110/// let foo = world.get_resource_or_init::<Foo>();2111/// Self(foo.0 * 2)2112/// }2113/// }2114///2115/// # let mut world = World::new();2116/// let my_res = world.get_resource_or_init::<MyResource>();2117/// assert_eq!(my_res.0, 30);2118/// ```2119#[track_caller]2120pub fn get_resource_or_init<R: Resource + FromWorld>(&mut self) -> Mut<'_, R> {2121let caller = MaybeLocation::caller();2122let change_tick = self.change_tick();2123let last_change_tick = self.last_change_tick();21242125let component_id = self.components_registrator().register_resource::<R>();2126if self2127.storages2128.resources2129.get(component_id)2130.is_none_or(|data| !data.is_present())2131{2132let value = R::from_world(self);2133OwningPtr::make(value, |ptr| {2134// SAFETY: component_id was just initialized and corresponds to resource of type R.2135unsafe {2136self.insert_resource_by_id(component_id, ptr, caller);2137}2138});2139}21402141// SAFETY: The resource was just initialized if it was empty.2142let data = unsafe {2143self.storages2144.resources2145.get_mut(component_id)2146.debug_checked_unwrap()2147};2148// SAFETY: The resource must be present, as we would have inserted it if it was empty.2149let data = unsafe {2150data.get_mut(last_change_tick, change_tick)2151.debug_checked_unwrap()2152};2153// SAFETY: The underlying type of the resource is `R`.2154unsafe { data.with_type::<R>() }2155}21562157/// Gets an immutable reference to the non-send resource of the given type, if it exists.2158///2159/// # Panics2160///2161/// Panics if the resource does not exist.2162/// Use [`get_non_send_resource`](World::get_non_send_resource) instead if you want to handle this case.2163///2164/// This function will panic if it isn't called from the same thread that the resource was inserted from.2165#[inline]2166#[track_caller]2167pub fn non_send_resource<R: 'static>(&self) -> &R {2168match self.get_non_send_resource() {2169Some(x) => x,2170None => panic!(2171"Requested non-send resource {} does not exist in the `World`.2172Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?2173Non-send resources can also be added by plugins.",2174DebugName::type_name::<R>()2175),2176}2177}21782179/// Gets a mutable reference to the non-send resource of the given type, if it exists.2180///2181/// # Panics2182///2183/// Panics if the resource does not exist.2184/// Use [`get_non_send_resource_mut`](World::get_non_send_resource_mut) instead if you want to handle this case.2185///2186/// This function will panic if it isn't called from the same thread that the resource was inserted from.2187#[inline]2188#[track_caller]2189pub fn non_send_resource_mut<R: 'static>(&mut self) -> Mut<'_, R> {2190match self.get_non_send_resource_mut() {2191Some(x) => x,2192None => panic!(2193"Requested non-send resource {} does not exist in the `World`.2194Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?2195Non-send resources can also be added by plugins.",2196DebugName::type_name::<R>()2197),2198}2199}22002201/// Gets a reference to the non-send resource of the given type, if it exists.2202/// Otherwise returns `None`.2203///2204/// # Panics2205/// This function will panic if it isn't called from the same thread that the resource was inserted from.2206#[inline]2207pub fn get_non_send_resource<R: 'static>(&self) -> Option<&R> {2208// SAFETY:2209// - `as_unsafe_world_cell_readonly` gives permission to access the entire world immutably2210// - `&self` ensures that there are no mutable borrows of world data2211unsafe { self.as_unsafe_world_cell_readonly().get_non_send_resource() }2212}22132214/// Gets a mutable reference to the non-send resource of the given type, if it exists.2215/// Otherwise returns `None`.2216///2217/// # Panics2218/// This function will panic if it isn't called from the same thread that the resource was inserted from.2219#[inline]2220pub fn get_non_send_resource_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {2221// SAFETY:2222// - `as_unsafe_world_cell` gives permission to access the entire world mutably2223// - `&mut self` ensures that there are no borrows of world data2224unsafe { self.as_unsafe_world_cell().get_non_send_resource_mut() }2225}22262227/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2228/// adds the `Bundle` of components to each `Entity`.2229/// This is faster than doing equivalent operations one-by-one.2230///2231/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2232/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2233///2234/// This will overwrite any previous values of components shared by the `Bundle`.2235/// See [`World::insert_batch_if_new`] to keep the old values instead.2236///2237/// # Panics2238///2239/// This function will panic if any of the associated entities do not exist.2240///2241/// For the fallible version, see [`World::try_insert_batch`].2242#[track_caller]2243pub fn insert_batch<I, B>(&mut self, batch: I)2244where2245I: IntoIterator,2246I::IntoIter: Iterator<Item = (Entity, B)>,2247B: Bundle<Effect: NoBundleEffect>,2248{2249self.insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller());2250}22512252/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2253/// adds the `Bundle` of components to each `Entity` without overwriting.2254/// This is faster than doing equivalent operations one-by-one.2255///2256/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2257/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2258///2259/// This is the same as [`World::insert_batch`], but in case of duplicate2260/// components it will leave the old values instead of replacing them with new ones.2261///2262/// # Panics2263///2264/// This function will panic if any of the associated entities do not exist.2265///2266/// For the fallible version, see [`World::try_insert_batch_if_new`].2267#[track_caller]2268pub fn insert_batch_if_new<I, B>(&mut self, batch: I)2269where2270I: IntoIterator,2271I::IntoIter: Iterator<Item = (Entity, B)>,2272B: Bundle<Effect: NoBundleEffect>,2273{2274self.insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller());2275}22762277/// Split into a new function so we can differentiate the calling location.2278///2279/// This can be called by:2280/// - [`World::insert_batch`]2281/// - [`World::insert_batch_if_new`]2282#[inline]2283pub(crate) fn insert_batch_with_caller<I, B>(2284&mut self,2285batch: I,2286insert_mode: InsertMode,2287caller: MaybeLocation,2288) where2289I: IntoIterator,2290I::IntoIter: Iterator<Item = (Entity, B)>,2291B: Bundle<Effect: NoBundleEffect>,2292{2293struct InserterArchetypeCache<'w> {2294inserter: BundleInserter<'w>,2295archetype_id: ArchetypeId,2296}22972298self.flush();2299let change_tick = self.change_tick();2300let bundle_id = self.register_bundle_info::<B>();23012302let mut batch_iter = batch.into_iter();23032304if let Some((first_entity, first_bundle)) = batch_iter.next() {2305if let Some(first_location) = self.entities().get(first_entity) {2306let mut cache = InserterArchetypeCache {2307// SAFETY: we initialized this bundle_id in `register_info`2308inserter: unsafe {2309BundleInserter::new_with_id(2310self,2311first_location.archetype_id,2312bundle_id,2313change_tick,2314)2315},2316archetype_id: first_location.archetype_id,2317};2318// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2319unsafe {2320cache.inserter.insert(2321first_entity,2322first_location,2323first_bundle,2324insert_mode,2325caller,2326RelationshipHookMode::Run,2327)2328};23292330for (entity, bundle) in batch_iter {2331if let Some(location) = cache.inserter.entities().get(entity) {2332if location.archetype_id != cache.archetype_id {2333cache = InserterArchetypeCache {2334// SAFETY: we initialized this bundle_id in `register_info`2335inserter: unsafe {2336BundleInserter::new_with_id(2337self,2338location.archetype_id,2339bundle_id,2340change_tick,2341)2342},2343archetype_id: location.archetype_id,2344}2345}2346// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2347unsafe {2348cache.inserter.insert(2349entity,2350location,2351bundle,2352insert_mode,2353caller,2354RelationshipHookMode::Run,2355)2356};2357} else {2358panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {entity}, which {}. See: https://bevy.org/learn/errors/b0003", DebugName::type_name::<B>(), self.entities.entity_does_not_exist_error_details(entity));2359}2360}2361} else {2362panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {first_entity}, which {}. See: https://bevy.org/learn/errors/b0003", DebugName::type_name::<B>(), self.entities.entity_does_not_exist_error_details(first_entity));2363}2364}2365}23662367/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2368/// adds the `Bundle` of components to each `Entity`.2369/// This is faster than doing equivalent operations one-by-one.2370///2371/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2372/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2373///2374/// This will overwrite any previous values of components shared by the `Bundle`.2375/// See [`World::try_insert_batch_if_new`] to keep the old values instead.2376///2377/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2378///2379/// For the panicking version, see [`World::insert_batch`].2380#[track_caller]2381pub fn try_insert_batch<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2382where2383I: IntoIterator,2384I::IntoIter: Iterator<Item = (Entity, B)>,2385B: Bundle<Effect: NoBundleEffect>,2386{2387self.try_insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller())2388}2389/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2390/// adds the `Bundle` of components to each `Entity` without overwriting.2391/// This is faster than doing equivalent operations one-by-one.2392///2393/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2394/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2395///2396/// This is the same as [`World::try_insert_batch`], but in case of duplicate2397/// components it will leave the old values instead of replacing them with new ones.2398///2399/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2400///2401/// For the panicking version, see [`World::insert_batch_if_new`].2402#[track_caller]2403pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2404where2405I: IntoIterator,2406I::IntoIter: Iterator<Item = (Entity, B)>,2407B: Bundle<Effect: NoBundleEffect>,2408{2409self.try_insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller())2410}24112412/// Split into a new function so we can differentiate the calling location.2413///2414/// This can be called by:2415/// - [`World::try_insert_batch`]2416/// - [`World::try_insert_batch_if_new`]2417/// - [`Commands::insert_batch`]2418/// - [`Commands::insert_batch_if_new`]2419/// - [`Commands::try_insert_batch`]2420/// - [`Commands::try_insert_batch_if_new`]2421#[inline]2422pub(crate) fn try_insert_batch_with_caller<I, B>(2423&mut self,2424batch: I,2425insert_mode: InsertMode,2426caller: MaybeLocation,2427) -> Result<(), TryInsertBatchError>2428where2429I: IntoIterator,2430I::IntoIter: Iterator<Item = (Entity, B)>,2431B: Bundle<Effect: NoBundleEffect>,2432{2433struct InserterArchetypeCache<'w> {2434inserter: BundleInserter<'w>,2435archetype_id: ArchetypeId,2436}24372438self.flush();2439let change_tick = self.change_tick();2440let bundle_id = self.register_bundle_info::<B>();24412442let mut invalid_entities = Vec::<Entity>::new();2443let mut batch_iter = batch.into_iter();24442445// We need to find the first valid entity so we can initialize the bundle inserter.2446// This differs from `insert_batch_with_caller` because that method can just panic2447// if the first entity is invalid, whereas this method needs to keep going.2448let cache = loop {2449if let Some((first_entity, first_bundle)) = batch_iter.next() {2450if let Some(first_location) = self.entities().get(first_entity) {2451let mut cache = InserterArchetypeCache {2452// SAFETY: we initialized this bundle_id in `register_bundle_info`2453inserter: unsafe {2454BundleInserter::new_with_id(2455self,2456first_location.archetype_id,2457bundle_id,2458change_tick,2459)2460},2461archetype_id: first_location.archetype_id,2462};2463// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2464unsafe {2465cache.inserter.insert(2466first_entity,2467first_location,2468first_bundle,2469insert_mode,2470caller,2471RelationshipHookMode::Run,2472)2473};2474break Some(cache);2475}2476invalid_entities.push(first_entity);2477} else {2478// We reached the end of the entities the caller provided and none were valid.2479break None;2480}2481};24822483if let Some(mut cache) = cache {2484for (entity, bundle) in batch_iter {2485if let Some(location) = cache.inserter.entities().get(entity) {2486if location.archetype_id != cache.archetype_id {2487cache = InserterArchetypeCache {2488// SAFETY: we initialized this bundle_id in `register_info`2489inserter: unsafe {2490BundleInserter::new_with_id(2491self,2492location.archetype_id,2493bundle_id,2494change_tick,2495)2496},2497archetype_id: location.archetype_id,2498}2499}2500// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2501unsafe {2502cache.inserter.insert(2503entity,2504location,2505bundle,2506insert_mode,2507caller,2508RelationshipHookMode::Run,2509)2510};2511} else {2512invalid_entities.push(entity);2513}2514}2515}25162517if invalid_entities.is_empty() {2518Ok(())2519} else {2520Err(TryInsertBatchError {2521bundle_type: DebugName::type_name::<B>(),2522entities: invalid_entities,2523})2524}2525}25262527/// Temporarily removes the requested resource from this [`World`], runs custom user code,2528/// then re-adds the resource before returning.2529///2530/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2531/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2532///2533/// # Panics2534///2535/// Panics if the resource does not exist.2536/// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.2537///2538/// # Example2539/// ```2540/// use bevy_ecs::prelude::*;2541/// #[derive(Resource)]2542/// struct A(u32);2543/// #[derive(Component)]2544/// struct B(u32);2545/// let mut world = World::new();2546/// world.insert_resource(A(1));2547/// let entity = world.spawn(B(1)).id();2548///2549/// world.resource_scope(|world, mut a: Mut<A>| {2550/// let b = world.get_mut::<B>(entity).unwrap();2551/// a.0 += b.0;2552/// });2553/// assert_eq!(world.get_resource::<A>().unwrap().0, 2);2554/// ```2555#[track_caller]2556pub fn resource_scope<R: Resource, U>(&mut self, f: impl FnOnce(&mut World, Mut<R>) -> U) -> U {2557self.try_resource_scope(f)2558.unwrap_or_else(|| panic!("resource does not exist: {}", DebugName::type_name::<R>()))2559}25602561/// Temporarily removes the requested resource from this [`World`] if it exists, runs custom user code,2562/// then re-adds the resource before returning. Returns `None` if the resource does not exist in this [`World`].2563///2564/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2565/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2566///2567/// See also [`resource_scope`](Self::resource_scope).2568pub fn try_resource_scope<R: Resource, U>(2569&mut self,2570f: impl FnOnce(&mut World, Mut<R>) -> U,2571) -> Option<U> {2572let last_change_tick = self.last_change_tick();2573let change_tick = self.change_tick();25742575let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;2576let (ptr, mut ticks, mut caller) = self2577.storages2578.resources2579.get_mut(component_id)2580.and_then(ResourceData::remove)?;2581// Read the value onto the stack to avoid potential mut aliasing.2582// SAFETY: `ptr` was obtained from the TypeId of `R`.2583let mut value = unsafe { ptr.read::<R>() };2584let value_mut = Mut {2585value: &mut value,2586ticks: TicksMut {2587added: &mut ticks.added,2588changed: &mut ticks.changed,2589last_run: last_change_tick,2590this_run: change_tick,2591},2592changed_by: caller.as_mut(),2593};2594let result = f(self, value_mut);2595assert!(!self.contains_resource::<R>(),2596"Resource `{}` was inserted during a call to World::resource_scope.\n\2597This is not allowed as the original resource is reinserted to the world after the closure is invoked.",2598DebugName::type_name::<R>());25992600OwningPtr::make(value, |ptr| {2601// SAFETY: pointer is of type R2602unsafe {2603self.storages.resources.get_mut(component_id).map(|info| {2604info.insert_with_ticks(ptr, ticks, caller);2605})2606}2607})?;26082609Some(result)2610}26112612/// Writes a [`BufferedEvent`].2613/// This method returns the [ID](`EventId`) of the written `event`,2614/// or [`None`] if the `event` could not be written.2615#[inline]2616pub fn write_event<E: BufferedEvent>(&mut self, event: E) -> Option<EventId<E>> {2617self.write_event_batch(core::iter::once(event))?.next()2618}26192620/// Writes a [`BufferedEvent`].2621/// This method returns the [ID](`EventId`) of the written `event`,2622/// or [`None`] if the `event` could not be written.2623#[inline]2624#[deprecated(since = "0.17.0", note = "Use `World::write_event` instead.")]2625pub fn send_event<E: BufferedEvent>(&mut self, event: E) -> Option<EventId<E>> {2626self.write_event(event)2627}26282629/// Writes the default value of the [`BufferedEvent`] of type `E`.2630/// This method returns the [ID](`EventId`) of the written `event`,2631/// or [`None`] if the `event` could not be written.2632#[inline]2633pub fn write_event_default<E: BufferedEvent + Default>(&mut self) -> Option<EventId<E>> {2634self.write_event(E::default())2635}26362637/// Writes the default value of the [`BufferedEvent`] of type `E`.2638/// This method returns the [ID](`EventId`) of the written `event`,2639/// or [`None`] if the `event` could not be written.2640#[inline]2641#[deprecated(since = "0.17.0", note = "Use `World::write_event_default` instead.")]2642pub fn send_event_default<E: BufferedEvent + Default>(&mut self) -> Option<EventId<E>> {2643self.write_event_default::<E>()2644}26452646/// Writes a batch of [`BufferedEvent`]s from an iterator.2647/// This method returns the [IDs](`EventId`) of the written `events`,2648/// or [`None`] if the `event` could not be written.2649#[inline]2650pub fn write_event_batch<E: BufferedEvent>(2651&mut self,2652events: impl IntoIterator<Item = E>,2653) -> Option<WriteBatchIds<E>> {2654let Some(mut events_resource) = self.get_resource_mut::<Events<E>>() else {2655log::error!(2656"Unable to send event `{}`\n\tEvent must be added to the app with `add_event()`\n\thttps://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event ",2657DebugName::type_name::<E>()2658);2659return None;2660};2661Some(events_resource.write_batch(events))2662}26632664/// Writes a batch of [`BufferedEvent`]s from an iterator.2665/// This method returns the [IDs](`EventId`) of the written `events`,2666/// or [`None`] if the `event` could not be written.2667#[inline]2668#[deprecated(since = "0.17.0", note = "Use `World::write_event_batch` instead.")]2669pub fn send_event_batch<E: BufferedEvent>(2670&mut self,2671events: impl IntoIterator<Item = E>,2672) -> Option<WriteBatchIds<E>> {2673self.write_event_batch(events)2674}26752676/// Inserts a new resource with the given `value`. Will replace the value if it already existed.2677///2678/// **You should prefer to use the typed API [`World::insert_resource`] where possible and only2679/// use this in cases where the actual types are not known at compile time.**2680///2681/// # Safety2682/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.2683#[inline]2684#[track_caller]2685pub unsafe fn insert_resource_by_id(2686&mut self,2687component_id: ComponentId,2688value: OwningPtr<'_>,2689caller: MaybeLocation,2690) {2691let change_tick = self.change_tick();26922693let resource = self.initialize_resource_internal(component_id);2694// SAFETY: `value` is valid for `component_id`, ensured by caller2695unsafe {2696resource.insert(value, change_tick, caller);2697}2698}26992700/// Inserts a new `!Send` resource with the given `value`. Will replace the value if it already2701/// existed.2702///2703/// **You should prefer to use the typed API [`World::insert_non_send_resource`] where possible and only2704/// use this in cases where the actual types are not known at compile time.**2705///2706/// # Panics2707/// If a value is already present, this function will panic if not called from the same2708/// thread that the original value was inserted from.2709///2710/// # Safety2711/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.2712#[inline]2713#[track_caller]2714pub unsafe fn insert_non_send_by_id(2715&mut self,2716component_id: ComponentId,2717value: OwningPtr<'_>,2718caller: MaybeLocation,2719) {2720let change_tick = self.change_tick();27212722let resource = self.initialize_non_send_internal(component_id);2723// SAFETY: `value` is valid for `component_id`, ensured by caller2724unsafe {2725resource.insert(value, change_tick, caller);2726}2727}27282729/// # Panics2730/// Panics if `component_id` is not registered as a `Send` component type in this `World`2731#[inline]2732pub(crate) fn initialize_resource_internal(2733&mut self,2734component_id: ComponentId,2735) -> &mut ResourceData<true> {2736self.flush_components();2737self.storages2738.resources2739.initialize_with(component_id, &self.components)2740}27412742/// # Panics2743/// Panics if `component_id` is not registered in this world2744#[inline]2745pub(crate) fn initialize_non_send_internal(2746&mut self,2747component_id: ComponentId,2748) -> &mut ResourceData<false> {2749self.flush_components();2750self.storages2751.non_send_resources2752.initialize_with(component_id, &self.components)2753}27542755/// Empties queued entities and adds them to the empty [`Archetype`](crate::archetype::Archetype).2756/// This should be called before doing operations that might operate on queued entities,2757/// such as inserting a [`Component`].2758#[track_caller]2759pub(crate) fn flush_entities(&mut self) {2760let by = MaybeLocation::caller();2761let at = self.change_tick();2762let empty_archetype = self.archetypes.empty_mut();2763let table = &mut self.storages.tables[empty_archetype.table_id()];2764// PERF: consider pre-allocating space for flushed entities2765// SAFETY: entity is set to a valid location2766unsafe {2767self.entities.flush(2768|entity, location| {2769// SAFETY: no components are allocated by archetype.allocate() because the archetype2770// is empty2771*location = Some(empty_archetype.allocate(entity, table.allocate(entity)));2772},2773by,2774at,2775);2776}2777}27782779/// Applies any commands in the world's internal [`CommandQueue`].2780/// This does not apply commands from any systems, only those stored in the world.2781///2782/// # Panics2783/// This will panic if any of the queued commands are [`spawn`](Commands::spawn).2784/// If this is possible, you should instead use [`flush`](Self::flush).2785pub(crate) fn flush_commands(&mut self) {2786// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`2787if !unsafe { self.command_queue.is_empty() } {2788// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`2789unsafe {2790self.command_queue2791.clone()2792.apply_or_drop_queued(Some(self.into()));2793};2794}2795}27962797/// Applies any queued component registration.2798/// For spawning vanilla rust component types and resources, this is not strictly necessary.2799/// However, flushing components can make information available more quickly, and can have performance benefits.2800/// Additionally, for components and resources registered dynamically through a raw descriptor or similar,2801/// this is the only way to complete their registration.2802pub(crate) fn flush_components(&mut self) {2803self.components_registrator().apply_queued_registrations();2804}28052806/// Flushes queued entities and commands.2807///2808/// Queued entities will be spawned, and then commands will be applied.2809#[inline]2810#[track_caller]2811pub fn flush(&mut self) {2812self.flush_entities();2813self.flush_components();2814self.flush_commands();2815}28162817/// Increments the world's current change tick and returns the old value.2818///2819/// If you need to call this method, but do not have `&mut` access to the world,2820/// consider using [`as_unsafe_world_cell_readonly`](Self::as_unsafe_world_cell_readonly)2821/// to obtain an [`UnsafeWorldCell`] and calling [`increment_change_tick`](UnsafeWorldCell::increment_change_tick) on that.2822/// Note that this *can* be done in safe code, despite the name of the type.2823#[inline]2824pub fn increment_change_tick(&mut self) -> Tick {2825let change_tick = self.change_tick.get_mut();2826let prev_tick = *change_tick;2827*change_tick = change_tick.wrapping_add(1);2828Tick::new(prev_tick)2829}28302831/// Reads the current change tick of this world.2832///2833/// If you have exclusive (`&mut`) access to the world, consider using [`change_tick()`](Self::change_tick),2834/// which is more efficient since it does not require atomic synchronization.2835#[inline]2836pub fn read_change_tick(&self) -> Tick {2837let tick = self.change_tick.load(Ordering::Acquire);2838Tick::new(tick)2839}28402841/// Reads the current change tick of this world.2842///2843/// This does the same thing as [`read_change_tick()`](Self::read_change_tick), only this method2844/// is more efficient since it does not require atomic synchronization.2845#[inline]2846pub fn change_tick(&mut self) -> Tick {2847let tick = *self.change_tick.get_mut();2848Tick::new(tick)2849}28502851/// When called from within an exclusive system (a [`System`] that takes `&mut World` as its first2852/// parameter), this method returns the [`Tick`] indicating the last time the exclusive system was run.2853///2854/// Otherwise, this returns the `Tick` indicating the last time that [`World::clear_trackers`] was called.2855///2856/// [`System`]: crate::system::System2857#[inline]2858pub fn last_change_tick(&self) -> Tick {2859self.last_change_tick2860}28612862/// Returns the id of the last ECS event that was fired.2863/// Used internally to ensure observers don't trigger multiple times for the same event.2864#[inline]2865pub(crate) fn last_trigger_id(&self) -> u32 {2866self.last_trigger_id2867}28682869/// Sets [`World::last_change_tick()`] to the specified value during a scope.2870/// When the scope terminates, it will return to its old value.2871///2872/// This is useful if you need a region of code to be able to react to earlier changes made in the same system.2873///2874/// # Examples2875///2876/// ```2877/// # use bevy_ecs::prelude::*;2878/// // This function runs an update loop repeatedly, allowing each iteration of the loop2879/// // to react to changes made in the previous loop iteration.2880/// fn update_loop(2881/// world: &mut World,2882/// mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,2883/// ) {2884/// let mut last_change_tick = world.last_change_tick();2885///2886/// // Repeatedly run the update function until it requests a break.2887/// loop {2888/// let control_flow = world.last_change_tick_scope(last_change_tick, |world| {2889/// // Increment the change tick so we can detect changes from the previous update.2890/// last_change_tick = world.change_tick();2891/// world.increment_change_tick();2892///2893/// // Update once.2894/// update_fn(world)2895/// });2896///2897/// // End the loop when the closure returns `ControlFlow::Break`.2898/// if control_flow.is_break() {2899/// break;2900/// }2901/// }2902/// }2903/// #2904/// # #[derive(Resource)] struct Count(u32);2905/// # let mut world = World::new();2906/// # world.insert_resource(Count(0));2907/// # let saved_last_tick = world.last_change_tick();2908/// # let mut num_updates = 0;2909/// # update_loop(&mut world, |world| {2910/// # let mut c = world.resource_mut::<Count>();2911/// # match c.0 {2912/// # 0 => {2913/// # assert_eq!(num_updates, 0);2914/// # assert!(c.is_added());2915/// # c.0 = 1;2916/// # }2917/// # 1 => {2918/// # assert_eq!(num_updates, 1);2919/// # assert!(!c.is_added());2920/// # assert!(c.is_changed());2921/// # c.0 = 2;2922/// # }2923/// # 2 if c.is_changed() => {2924/// # assert_eq!(num_updates, 2);2925/// # assert!(!c.is_added());2926/// # }2927/// # 2 => {2928/// # assert_eq!(num_updates, 3);2929/// # assert!(!c.is_changed());2930/// # world.remove_resource::<Count>();2931/// # world.insert_resource(Count(3));2932/// # }2933/// # 3 if c.is_changed() => {2934/// # assert_eq!(num_updates, 4);2935/// # assert!(c.is_added());2936/// # }2937/// # 3 => {2938/// # assert_eq!(num_updates, 5);2939/// # assert!(!c.is_added());2940/// # c.0 = 4;2941/// # return std::ops::ControlFlow::Break(());2942/// # }2943/// # _ => unreachable!(),2944/// # }2945/// # num_updates += 1;2946/// # std::ops::ControlFlow::Continue(())2947/// # });2948/// # assert_eq!(num_updates, 5);2949/// # assert_eq!(world.resource::<Count>().0, 4);2950/// # assert_eq!(world.last_change_tick(), saved_last_tick);2951/// ```2952pub fn last_change_tick_scope<T>(2953&mut self,2954last_change_tick: Tick,2955f: impl FnOnce(&mut World) -> T,2956) -> T {2957struct LastTickGuard<'a> {2958world: &'a mut World,2959last_tick: Tick,2960}29612962// By setting the change tick in the drop impl, we ensure that2963// the change tick gets reset even if a panic occurs during the scope.2964impl Drop for LastTickGuard<'_> {2965fn drop(&mut self) {2966self.world.last_change_tick = self.last_tick;2967}2968}29692970let guard = LastTickGuard {2971last_tick: self.last_change_tick,2972world: self,2973};29742975guard.world.last_change_tick = last_change_tick;29762977f(guard.world)2978}29792980/// Iterates all component change ticks and clamps any older than [`MAX_CHANGE_AGE`](crate::change_detection::MAX_CHANGE_AGE).2981/// This also triggers [`CheckChangeTicks`] observers and returns the same event here.2982///2983/// Calling this method prevents [`Tick`]s overflowing and thus prevents false positives when comparing them.2984///2985/// **Note:** Does nothing and returns `None` if the [`World`] counter has not been incremented at least [`CHECK_TICK_THRESHOLD`]2986/// times since the previous pass.2987// TODO: benchmark and optimize2988pub fn check_change_ticks(&mut self) -> Option<CheckChangeTicks> {2989let change_tick = self.change_tick();2990if change_tick.relative_to(self.last_check_tick).get() < CHECK_TICK_THRESHOLD {2991return None;2992}29932994let check = CheckChangeTicks(change_tick);29952996let Storages {2997ref mut tables,2998ref mut sparse_sets,2999ref mut resources,3000ref mut non_send_resources,3001} = self.storages;30023003#[cfg(feature = "trace")]3004let _span = tracing::info_span!("check component ticks").entered();3005tables.check_change_ticks(check);3006sparse_sets.check_change_ticks(check);3007resources.check_change_ticks(check);3008non_send_resources.check_change_ticks(check);3009self.entities.check_change_ticks(check);30103011if let Some(mut schedules) = self.get_resource_mut::<Schedules>() {3012schedules.check_change_ticks(check);3013}30143015self.trigger(check);3016self.flush();30173018self.last_check_tick = change_tick;30193020Some(check)3021}30223023/// Runs both [`clear_entities`](Self::clear_entities) and [`clear_resources`](Self::clear_resources),3024/// invalidating all [`Entity`] and resource fetches such as [`Res`](crate::system::Res), [`ResMut`](crate::system::ResMut)3025pub fn clear_all(&mut self) {3026self.clear_entities();3027self.clear_resources();3028}30293030/// Despawns all entities in this [`World`].3031pub fn clear_entities(&mut self) {3032self.storages.tables.clear();3033self.storages.sparse_sets.clear_entities();3034self.archetypes.clear_entities();3035self.entities.clear();3036}30373038/// Clears all resources in this [`World`].3039///3040/// **Note:** Any resource fetch to this [`World`] will fail unless they are re-initialized,3041/// including engine-internal resources that are only initialized on app/world construction.3042///3043/// This can easily cause systems expecting certain resources to immediately start panicking.3044/// Use with caution.3045pub fn clear_resources(&mut self) {3046self.storages.resources.clear();3047self.storages.non_send_resources.clear();3048}30493050/// Registers all of the components in the given [`Bundle`] and returns both the component3051/// ids and the bundle id.3052///3053/// This is largely equivalent to calling [`register_component`](Self::register_component) on each3054/// component in the bundle.3055#[inline]3056pub fn register_bundle<B: Bundle>(&mut self) -> &BundleInfo {3057let id = self.register_bundle_info::<B>();30583059// SAFETY: We just initialized the bundle so its id should definitely be valid.3060unsafe { self.bundles.get(id).debug_checked_unwrap() }3061}30623063pub(crate) fn register_bundle_info<B: Bundle>(&mut self) -> BundleId {3064// SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.3065let mut registrator =3066unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };30673068// SAFETY: `registrator`, `self.storages` and `self.bundles` all come from this world.3069unsafe {3070self.bundles3071.register_info::<B>(&mut registrator, &mut self.storages)3072}3073}30743075pub(crate) fn register_contributed_bundle_info<B: Bundle>(&mut self) -> BundleId {3076// SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.3077let mut registrator =3078unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };30793080// SAFETY: `registrator`, `self.bundles` and `self.storages` are all from this world.3081unsafe {3082self.bundles3083.register_contributed_bundle_info::<B>(&mut registrator, &mut self.storages)3084}3085}30863087/// Registers the given [`ComponentId`]s as a dynamic bundle and returns both the required component ids and the bundle id.3088///3089/// Note that the components need to be registered first, this function only creates a bundle combining them. Components3090/// can be registered with [`World::register_component`]/[`_with_descriptor`](World::register_component_with_descriptor).3091///3092/// **You should prefer to use the typed API [`World::register_bundle`] where possible and only use this in cases where3093/// not all of the actual types are known at compile time.**3094///3095/// # Panics3096/// This function will panic if any of the provided component ids do not belong to a component known to this [`World`].3097#[inline]3098pub fn register_dynamic_bundle(&mut self, component_ids: &[ComponentId]) -> &BundleInfo {3099let id =3100self.bundles3101.init_dynamic_info(&mut self.storages, &self.components, component_ids);3102// SAFETY: We just initialized the bundle so its id should definitely be valid.3103unsafe { self.bundles.get(id).debug_checked_unwrap() }3104}31053106/// Convenience method for accessing the world's default error handler,3107/// which can be overwritten with [`DefaultErrorHandler`].3108#[inline]3109pub fn default_error_handler(&self) -> ErrorHandler {3110self.get_resource::<DefaultErrorHandler>()3111.copied()3112.unwrap_or_default()3113.03114}3115}31163117impl World {3118/// Gets a pointer to the resource with the id [`ComponentId`] if it exists.3119/// The returned pointer must not be used to modify the resource, and must not be3120/// dereferenced after the immutable borrow of the [`World`] ends.3121///3122/// **You should prefer to use the typed API [`World::get_resource`] where possible and only3123/// use this in cases where the actual types are not known at compile time.**3124#[inline]3125pub fn get_resource_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {3126// SAFETY:3127// - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably3128// - `&self` ensures there are no mutable borrows on world data3129unsafe {3130self.as_unsafe_world_cell_readonly()3131.get_resource_by_id(component_id)3132}3133}31343135/// Gets a pointer to the resource with the id [`ComponentId`] if it exists.3136/// The returned pointer may be used to modify the resource, as long as the mutable borrow3137/// of the [`World`] is still valid.3138///3139/// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only3140/// use this in cases where the actual types are not known at compile time.**3141#[inline]3142pub fn get_resource_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {3143// SAFETY:3144// - `&mut self` ensures that all accessed data is unaliased3145// - `as_unsafe_world_cell` provides mutable permission to the whole world3146unsafe {3147self.as_unsafe_world_cell()3148.get_resource_mut_by_id(component_id)3149}3150}31513152/// Iterates over all resources in the world.3153///3154/// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading the contents3155/// of each resource will require the use of unsafe code.3156///3157/// # Examples3158///3159/// ## Printing the size of all resources3160///3161/// ```3162/// # use bevy_ecs::prelude::*;3163/// # #[derive(Resource)]3164/// # struct A(u32);3165/// # #[derive(Resource)]3166/// # struct B(u32);3167/// #3168/// # let mut world = World::new();3169/// # world.remove_resource::<bevy_ecs::entity_disabling::DefaultQueryFilters>();3170/// # world.insert_resource(A(1));3171/// # world.insert_resource(B(2));3172/// let mut total = 0;3173/// for (info, _) in world.iter_resources() {3174/// println!("Resource: {}", info.name());3175/// println!("Size: {} bytes", info.layout().size());3176/// total += info.layout().size();3177/// }3178/// println!("Total size: {} bytes", total);3179/// # assert_eq!(total, size_of::<A>() + size_of::<B>());3180/// ```3181///3182/// ## Dynamically running closures for resources matching specific `TypeId`s3183///3184/// ```3185/// # use bevy_ecs::prelude::*;3186/// # use std::collections::HashMap;3187/// # use std::any::TypeId;3188/// # use bevy_ptr::Ptr;3189/// # #[derive(Resource)]3190/// # struct A(u32);3191/// # #[derive(Resource)]3192/// # struct B(u32);3193/// #3194/// # let mut world = World::new();3195/// # world.insert_resource(A(1));3196/// # world.insert_resource(B(2));3197/// #3198/// // In this example, `A` and `B` are resources. We deliberately do not use the3199/// // `bevy_reflect` crate here to showcase the low-level [`Ptr`] usage. You should3200/// // probably use something like `ReflectFromPtr` in a real-world scenario.3201///3202/// // Create the hash map that will store the closures for each resource type3203/// let mut closures: HashMap<TypeId, Box<dyn Fn(&Ptr<'_>)>> = HashMap::default();3204///3205/// // Add closure for `A`3206/// closures.insert(TypeId::of::<A>(), Box::new(|ptr| {3207/// // SAFETY: We assert ptr is the same type of A with TypeId of A3208/// let a = unsafe { &ptr.deref::<A>() };3209/// # assert_eq!(a.0, 1);3210/// // ... do something with `a` here3211/// }));3212///3213/// // Add closure for `B`3214/// closures.insert(TypeId::of::<B>(), Box::new(|ptr| {3215/// // SAFETY: We assert ptr is the same type of B with TypeId of B3216/// let b = unsafe { &ptr.deref::<B>() };3217/// # assert_eq!(b.0, 2);3218/// // ... do something with `b` here3219/// }));3220///3221/// // Iterate all resources, in order to run the closures for each matching resource type3222/// for (info, ptr) in world.iter_resources() {3223/// let Some(type_id) = info.type_id() else {3224/// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources3225/// // dynamically inserted via a scripting language) in which case we can't match them.3226/// continue;3227/// };3228///3229/// let Some(closure) = closures.get(&type_id) else {3230/// // No closure for this resource type, skip it.3231/// continue;3232/// };3233///3234/// // Run the closure for the resource3235/// closure(&ptr);3236/// }3237/// ```3238#[inline]3239pub fn iter_resources(&self) -> impl Iterator<Item = (&ComponentInfo, Ptr<'_>)> {3240self.storages3241.resources3242.iter()3243.filter_map(|(component_id, data)| {3244// SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.3245let component_info = unsafe {3246self.components3247.get_info(component_id)3248.debug_checked_unwrap()3249};3250Some((component_info, data.get_data()?))3251})3252}32533254/// Mutably iterates over all resources in the world.3255///3256/// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading from or writing3257/// to the contents of each resource will require the use of unsafe code.3258///3259/// # Example3260///3261/// ```3262/// # use bevy_ecs::prelude::*;3263/// # use bevy_ecs::change_detection::MutUntyped;3264/// # use std::collections::HashMap;3265/// # use std::any::TypeId;3266/// # #[derive(Resource)]3267/// # struct A(u32);3268/// # #[derive(Resource)]3269/// # struct B(u32);3270/// #3271/// # let mut world = World::new();3272/// # world.insert_resource(A(1));3273/// # world.insert_resource(B(2));3274/// #3275/// // In this example, `A` and `B` are resources. We deliberately do not use the3276/// // `bevy_reflect` crate here to showcase the low-level `MutUntyped` usage. You should3277/// // probably use something like `ReflectFromPtr` in a real-world scenario.3278///3279/// // Create the hash map that will store the mutator closures for each resource type3280/// let mut mutators: HashMap<TypeId, Box<dyn Fn(&mut MutUntyped<'_>)>> = HashMap::default();3281///3282/// // Add mutator closure for `A`3283/// mutators.insert(TypeId::of::<A>(), Box::new(|mut_untyped| {3284/// // Note: `MutUntyped::as_mut()` automatically marks the resource as changed3285/// // for ECS change detection, and gives us a `PtrMut` we can use to mutate the resource.3286/// // SAFETY: We assert ptr is the same type of A with TypeId of A3287/// let a = unsafe { &mut mut_untyped.as_mut().deref_mut::<A>() };3288/// # a.0 += 1;3289/// // ... mutate `a` here3290/// }));3291///3292/// // Add mutator closure for `B`3293/// mutators.insert(TypeId::of::<B>(), Box::new(|mut_untyped| {3294/// // SAFETY: We assert ptr is the same type of B with TypeId of B3295/// let b = unsafe { &mut mut_untyped.as_mut().deref_mut::<B>() };3296/// # b.0 += 1;3297/// // ... mutate `b` here3298/// }));3299///3300/// // Iterate all resources, in order to run the mutator closures for each matching resource type3301/// for (info, mut mut_untyped) in world.iter_resources_mut() {3302/// let Some(type_id) = info.type_id() else {3303/// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources3304/// // dynamically inserted via a scripting language) in which case we can't match them.3305/// continue;3306/// };3307///3308/// let Some(mutator) = mutators.get(&type_id) else {3309/// // No mutator closure for this resource type, skip it.3310/// continue;3311/// };3312///3313/// // Run the mutator closure for the resource3314/// mutator(&mut mut_untyped);3315/// }3316/// # assert_eq!(world.resource::<A>().0, 2);3317/// # assert_eq!(world.resource::<B>().0, 3);3318/// ```3319#[inline]3320pub fn iter_resources_mut(&mut self) -> impl Iterator<Item = (&ComponentInfo, MutUntyped<'_>)> {3321self.storages3322.resources3323.iter()3324.filter_map(|(component_id, data)| {3325// SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.3326let component_info = unsafe {3327self.components3328.get_info(component_id)3329.debug_checked_unwrap()3330};3331let (ptr, ticks, caller) = data.get_with_ticks()?;33323333// SAFETY:3334// - We have exclusive access to the world, so no other code can be aliasing the `TickCells`3335// - We only hold one `TicksMut` at a time, and we let go of it before getting the next one3336let ticks = unsafe {3337TicksMut::from_tick_cells(3338ticks,3339self.last_change_tick(),3340self.read_change_tick(),3341)3342};33433344let mut_untyped = MutUntyped {3345// SAFETY:3346// - We have exclusive access to the world, so no other code can be aliasing the `Ptr`3347// - We iterate one resource at a time, and we let go of each `PtrMut` before getting the next one3348value: unsafe { ptr.assert_unique() },3349ticks,3350// SAFETY:3351// - We have exclusive access to the world, so no other code can be aliasing the `Ptr`3352// - We iterate one resource at a time, and we let go of each `PtrMut` before getting the next one3353changed_by: unsafe { caller.map(|caller| caller.deref_mut()) },3354};33553356Some((component_info, mut_untyped))3357})3358}33593360/// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.3361/// The returned pointer must not be used to modify the resource, and must not be3362/// dereferenced after the immutable borrow of the [`World`] ends.3363///3364/// **You should prefer to use the typed API [`World::get_resource`] where possible and only3365/// use this in cases where the actual types are not known at compile time.**3366///3367/// # Panics3368/// This function will panic if it isn't called from the same thread that the resource was inserted from.3369#[inline]3370pub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {3371// SAFETY:3372// - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably3373// - `&self` ensures there are no mutable borrows on world data3374unsafe {3375self.as_unsafe_world_cell_readonly()3376.get_non_send_resource_by_id(component_id)3377}3378}33793380/// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.3381/// The returned pointer may be used to modify the resource, as long as the mutable borrow3382/// of the [`World`] is still valid.3383///3384/// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only3385/// use this in cases where the actual types are not known at compile time.**3386///3387/// # Panics3388/// This function will panic if it isn't called from the same thread that the resource was inserted from.3389#[inline]3390pub fn get_non_send_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {3391// SAFETY:3392// - `&mut self` ensures that all accessed data is unaliased3393// - `as_unsafe_world_cell` provides mutable permission to the whole world3394unsafe {3395self.as_unsafe_world_cell()3396.get_non_send_resource_mut_by_id(component_id)3397}3398}33993400/// Removes the resource of a given type, if it exists. Otherwise returns `None`.3401///3402/// **You should prefer to use the typed API [`World::remove_resource`] where possible and only3403/// use this in cases where the actual types are not known at compile time.**3404pub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> Option<()> {3405self.storages3406.resources3407.get_mut(component_id)?3408.remove_and_drop();3409Some(())3410}34113412/// Removes the resource of a given type, if it exists. Otherwise returns `None`.3413///3414/// **You should prefer to use the typed API [`World::remove_resource`] where possible and only3415/// use this in cases where the actual types are not known at compile time.**3416///3417/// # Panics3418/// This function will panic if it isn't called from the same thread that the resource was inserted from.3419pub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()> {3420self.storages3421.non_send_resources3422.get_mut(component_id)?3423.remove_and_drop();3424Some(())3425}34263427/// Retrieves an immutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].3428/// Returns `None` if the `entity` does not have a [`Component`] of the given type.3429///3430/// **You should prefer to use the typed API [`World::get_mut`] where possible and only3431/// use this in cases where the actual types are not known at compile time.**3432///3433/// # Panics3434/// This function will panic if it isn't called from the same thread that the resource was inserted from.3435#[inline]3436pub fn get_by_id(&self, entity: Entity, component_id: ComponentId) -> Option<Ptr<'_>> {3437self.get_entity(entity).ok()?.get_by_id(component_id).ok()3438}34393440/// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].3441/// Returns `None` if the `entity` does not have a [`Component`] of the given type.3442///3443/// **You should prefer to use the typed API [`World::get_mut`] where possible and only3444/// use this in cases where the actual types are not known at compile time.**3445#[inline]3446pub fn get_mut_by_id(3447&mut self,3448entity: Entity,3449component_id: ComponentId,3450) -> Option<MutUntyped<'_>> {3451self.get_entity_mut(entity)3452.ok()?3453.into_mut_by_id(component_id)3454.ok()3455}3456}34573458// Schedule-related methods3459impl World {3460/// Adds the specified [`Schedule`] to the world.3461/// If a schedule already exists with the same [label](Schedule::label), it will be replaced.3462///3463/// The schedule can later be run3464/// by calling [`.run_schedule(label)`](Self::run_schedule) or by directly3465/// accessing the [`Schedules`] resource.3466///3467/// The `Schedules` resource will be initialized if it does not already exist.3468///3469/// An alternative to this is to call [`Schedules::add_systems()`] with some3470/// [`ScheduleLabel`] and let the schedule for that label be created if it3471/// does not already exist.3472pub fn add_schedule(&mut self, schedule: Schedule) {3473let mut schedules = self.get_resource_or_init::<Schedules>();3474schedules.insert(schedule);3475}34763477/// Temporarily removes the schedule associated with `label` from the world,3478/// runs user code, and finally re-adds the schedule.3479/// This returns a [`TryRunScheduleError`] if there is no schedule3480/// associated with `label`.3481///3482/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3483/// and system state is cached.3484///3485/// For simple cases where you just need to call the schedule once,3486/// consider using [`World::try_run_schedule`] instead.3487/// For other use cases, see the example on [`World::schedule_scope`].3488pub fn try_schedule_scope<R>(3489&mut self,3490label: impl ScheduleLabel,3491f: impl FnOnce(&mut World, &mut Schedule) -> R,3492) -> Result<R, TryRunScheduleError> {3493let label = label.intern();3494let Some(mut schedule) = self3495.get_resource_mut::<Schedules>()3496.and_then(|mut s| s.remove(label))3497else {3498return Err(TryRunScheduleError(label));3499};35003501let value = f(self, &mut schedule);35023503let old = self.resource_mut::<Schedules>().insert(schedule);3504if old.is_some() {3505warn!("Schedule `{label:?}` was inserted during a call to `World::schedule_scope`: its value has been overwritten");3506}35073508Ok(value)3509}35103511/// Temporarily removes the schedule associated with `label` from the world,3512/// runs user code, and finally re-adds the schedule.3513///3514/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3515/// and system state is cached.3516///3517/// # Examples3518///3519/// ```3520/// # use bevy_ecs::{prelude::*, schedule::ScheduleLabel};3521/// # #[derive(ScheduleLabel, Debug, Clone, Copy, PartialEq, Eq, Hash)]3522/// # pub struct MySchedule;3523/// # #[derive(Resource)]3524/// # struct Counter(usize);3525/// #3526/// # let mut world = World::new();3527/// # world.insert_resource(Counter(0));3528/// # let mut schedule = Schedule::new(MySchedule);3529/// # schedule.add_systems(tick_counter);3530/// # world.init_resource::<Schedules>();3531/// # world.add_schedule(schedule);3532/// # fn tick_counter(mut counter: ResMut<Counter>) { counter.0 += 1; }3533/// // Run the schedule five times.3534/// world.schedule_scope(MySchedule, |world, schedule| {3535/// for _ in 0..5 {3536/// schedule.run(world);3537/// }3538/// });3539/// # assert_eq!(world.resource::<Counter>().0, 5);3540/// ```3541///3542/// For simple cases where you just need to call the schedule once,3543/// consider using [`World::run_schedule`] instead.3544///3545/// # Panics3546///3547/// If the requested schedule does not exist.3548pub fn schedule_scope<R>(3549&mut self,3550label: impl ScheduleLabel,3551f: impl FnOnce(&mut World, &mut Schedule) -> R,3552) -> R {3553self.try_schedule_scope(label, f)3554.unwrap_or_else(|e| panic!("{e}"))3555}35563557/// Attempts to run the [`Schedule`] associated with the `label` a single time,3558/// and returns a [`TryRunScheduleError`] if the schedule does not exist.3559///3560/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3561/// and system state is cached.3562///3563/// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.3564pub fn try_run_schedule(3565&mut self,3566label: impl ScheduleLabel,3567) -> Result<(), TryRunScheduleError> {3568self.try_schedule_scope(label, |world, sched| sched.run(world))3569}35703571/// Runs the [`Schedule`] associated with the `label` a single time.3572///3573/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3574/// and system state is cached.3575///3576/// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.3577/// This avoids the need to create a unique [`ScheduleLabel`].3578///3579/// # Panics3580///3581/// If the requested schedule does not exist.3582pub fn run_schedule(&mut self, label: impl ScheduleLabel) {3583self.schedule_scope(label, |world, sched| sched.run(world));3584}35853586/// Ignore system order ambiguities caused by conflicts on [`Component`]s of type `T`.3587pub fn allow_ambiguous_component<T: Component>(&mut self) {3588let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();3589schedules.allow_ambiguous_component::<T>(self);3590self.insert_resource(schedules);3591}35923593/// Ignore system order ambiguities caused by conflicts on [`Resource`]s of type `T`.3594pub fn allow_ambiguous_resource<T: Resource>(&mut self) {3595let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();3596schedules.allow_ambiguous_resource::<T>(self);3597self.insert_resource(schedules);3598}3599}36003601impl fmt::Debug for World {3602fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {3603// SAFETY: `UnsafeWorldCell` requires that this must only access metadata.3604// Accessing any data stored in the world would be unsound.3605f.debug_struct("World")3606.field("id", &self.id)3607.field("entity_count", &self.entities.len())3608.field("archetype_count", &self.archetypes.len())3609.field("component_count", &self.components.len())3610.field("resource_count", &self.storages.resources.len())3611.finish()3612}3613}36143615// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread3616unsafe impl Send for World {}3617// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread3618unsafe impl Sync for World {}36193620/// Creates an instance of the type this trait is implemented for3621/// using data from the supplied [`World`].3622///3623/// This can be helpful for complex initialization or context-aware defaults.3624///3625/// [`FromWorld`] is automatically implemented for any type implementing [`Default`]3626/// and may also be derived for:3627/// - any struct whose fields all implement `FromWorld`3628/// - any enum where one variant has the attribute `#[from_world]`3629///3630/// ```rs3631///3632/// #[derive(Default)]3633/// struct A;3634///3635/// #[derive(Default)]3636/// struct B(Option<u32>)3637///3638/// struct C;3639///3640/// impl FromWorld for C {3641/// fn from_world(_world: &mut World) -> Self {3642/// Self3643/// }3644/// }3645///3646/// #[derive(FromWorld)]3647/// struct D(A, B, C);3648///3649/// #[derive(FromWorld)]3650/// enum E {3651/// #[from_world]3652/// F,3653/// G3654/// }3655/// ```3656pub trait FromWorld {3657/// Creates `Self` using data from the given [`World`].3658fn from_world(world: &mut World) -> Self;3659}36603661impl<T: Default> FromWorld for T {3662/// Creates `Self` using [`default()`](`Default::default`).3663fn from_world(_world: &mut World) -> Self {3664T::default()3665}3666}36673668#[cfg(test)]3669#[expect(clippy::print_stdout, reason = "Allowed in tests.")]3670mod tests {3671use super::{FromWorld, World};3672use crate::{3673change_detection::{DetectChangesMut, MaybeLocation},3674component::{ComponentCloneBehavior, ComponentDescriptor, ComponentInfo, StorageType},3675entity::EntityHashSet,3676entity_disabling::{DefaultQueryFilters, Disabled},3677ptr::OwningPtr,3678resource::Resource,3679world::{error::EntityMutableFetchError, DeferredWorld},3680};3681use alloc::{3682borrow::ToOwned,3683string::{String, ToString},3684sync::Arc,3685vec,3686vec::Vec,3687};3688use bevy_ecs_macros::Component;3689use bevy_platform::collections::{HashMap, HashSet};3690use bevy_utils::prelude::DebugName;3691use core::{3692any::TypeId,3693panic,3694sync::atomic::{AtomicBool, AtomicU32, Ordering},3695};3696use std::{println, sync::Mutex};36973698type ID = u8;36993700#[derive(Clone, Copy, Debug, PartialEq, Eq)]3701enum DropLogItem {3702Create(ID),3703Drop(ID),3704}37053706#[derive(Resource, Component)]3707struct MayPanicInDrop {3708drop_log: Arc<Mutex<Vec<DropLogItem>>>,3709expected_panic_flag: Arc<AtomicBool>,3710should_panic: bool,3711id: u8,3712}37133714impl MayPanicInDrop {3715fn new(3716drop_log: &Arc<Mutex<Vec<DropLogItem>>>,3717expected_panic_flag: &Arc<AtomicBool>,3718should_panic: bool,3719id: u8,3720) -> Self {3721println!("creating component with id {id}");3722drop_log.lock().unwrap().push(DropLogItem::Create(id));37233724Self {3725drop_log: Arc::clone(drop_log),3726expected_panic_flag: Arc::clone(expected_panic_flag),3727should_panic,3728id,3729}3730}3731}37323733impl Drop for MayPanicInDrop {3734fn drop(&mut self) {3735println!("dropping component with id {}", self.id);37363737{3738let mut drop_log = self.drop_log.lock().unwrap();3739drop_log.push(DropLogItem::Drop(self.id));3740// Don't keep the mutex while panicking, or we'll poison it.3741drop(drop_log);3742}37433744if self.should_panic {3745self.expected_panic_flag.store(true, Ordering::SeqCst);3746panic!("testing what happens on panic inside drop");3747}3748}3749}37503751struct DropTestHelper {3752drop_log: Arc<Mutex<Vec<DropLogItem>>>,3753/// Set to `true` right before we intentionally panic, so that if we get3754/// a panic, we know if it was intended or not.3755expected_panic_flag: Arc<AtomicBool>,3756}37573758impl DropTestHelper {3759pub fn new() -> Self {3760Self {3761drop_log: Arc::new(Mutex::new(Vec::<DropLogItem>::new())),3762expected_panic_flag: Arc::new(AtomicBool::new(false)),3763}3764}37653766pub fn make_component(&self, should_panic: bool, id: ID) -> MayPanicInDrop {3767MayPanicInDrop::new(&self.drop_log, &self.expected_panic_flag, should_panic, id)3768}37693770pub fn finish(self, panic_res: std::thread::Result<()>) -> Vec<DropLogItem> {3771let drop_log = self.drop_log.lock().unwrap();3772let expected_panic_flag = self.expected_panic_flag.load(Ordering::SeqCst);37733774if !expected_panic_flag {3775match panic_res {3776Ok(()) => panic!("Expected a panic but it didn't happen"),3777Err(e) => std::panic::resume_unwind(e),3778}3779}37803781drop_log.to_owned()3782}3783}37843785#[test]3786fn panic_while_overwriting_component() {3787let helper = DropTestHelper::new();37883789let res = std::panic::catch_unwind(|| {3790let mut world = World::new();3791world3792.spawn_empty()3793.insert(helper.make_component(true, 0))3794.insert(helper.make_component(false, 1));37953796println!("Done inserting! Dropping world...");3797});37983799let drop_log = helper.finish(res);38003801assert_eq!(3802&*drop_log,3803[3804DropLogItem::Create(0),3805DropLogItem::Create(1),3806DropLogItem::Drop(0),3807DropLogItem::Drop(1),3808]3809);3810}38113812#[derive(Resource)]3813struct TestResource(u32);38143815#[derive(Resource)]3816struct TestResource2(String);38173818#[derive(Resource)]3819struct TestResource3;38203821#[test]3822fn get_resource_by_id() {3823let mut world = World::new();3824world.insert_resource(TestResource(42));3825let component_id = world3826.components()3827.get_valid_resource_id(TypeId::of::<TestResource>())3828.unwrap();38293830let resource = world.get_resource_by_id(component_id).unwrap();3831// SAFETY: `TestResource` is the correct resource type3832let resource = unsafe { resource.deref::<TestResource>() };38333834assert_eq!(resource.0, 42);3835}38363837#[test]3838fn get_resource_mut_by_id() {3839let mut world = World::new();3840world.insert_resource(TestResource(42));3841let component_id = world3842.components()3843.get_valid_resource_id(TypeId::of::<TestResource>())3844.unwrap();38453846{3847let mut resource = world.get_resource_mut_by_id(component_id).unwrap();3848resource.set_changed();3849// SAFETY: `TestResource` is the correct resource type3850let resource = unsafe { resource.into_inner().deref_mut::<TestResource>() };3851resource.0 = 43;3852}38533854let resource = world.get_resource_by_id(component_id).unwrap();3855// SAFETY: `TestResource` is the correct resource type3856let resource = unsafe { resource.deref::<TestResource>() };38573858assert_eq!(resource.0, 43);3859}38603861#[test]3862fn iter_resources() {3863let mut world = World::new();3864// Remove DefaultQueryFilters so it doesn't show up in the iterator3865world.remove_resource::<DefaultQueryFilters>();3866world.insert_resource(TestResource(42));3867world.insert_resource(TestResource2("Hello, world!".to_string()));3868world.insert_resource(TestResource3);3869world.remove_resource::<TestResource3>();38703871let mut iter = world.iter_resources();38723873let (info, ptr) = iter.next().unwrap();3874assert_eq!(info.name(), DebugName::type_name::<TestResource>());3875// SAFETY: We know that the resource is of type `TestResource`3876assert_eq!(unsafe { ptr.deref::<TestResource>().0 }, 42);38773878let (info, ptr) = iter.next().unwrap();3879assert_eq!(info.name(), DebugName::type_name::<TestResource2>());3880assert_eq!(3881// SAFETY: We know that the resource is of type `TestResource2`3882unsafe { &ptr.deref::<TestResource2>().0 },3883&"Hello, world!".to_string()3884);38853886assert!(iter.next().is_none());3887}38883889#[test]3890fn iter_resources_mut() {3891let mut world = World::new();3892// Remove DefaultQueryFilters so it doesn't show up in the iterator3893world.remove_resource::<DefaultQueryFilters>();3894world.insert_resource(TestResource(42));3895world.insert_resource(TestResource2("Hello, world!".to_string()));3896world.insert_resource(TestResource3);3897world.remove_resource::<TestResource3>();38983899let mut iter = world.iter_resources_mut();39003901let (info, mut mut_untyped) = iter.next().unwrap();3902assert_eq!(info.name(), DebugName::type_name::<TestResource>());3903// SAFETY: We know that the resource is of type `TestResource`3904unsafe {3905mut_untyped.as_mut().deref_mut::<TestResource>().0 = 43;3906};39073908let (info, mut mut_untyped) = iter.next().unwrap();3909assert_eq!(info.name(), DebugName::type_name::<TestResource2>());3910// SAFETY: We know that the resource is of type `TestResource2`3911unsafe {3912mut_untyped.as_mut().deref_mut::<TestResource2>().0 = "Hello, world?".to_string();3913};39143915assert!(iter.next().is_none());3916drop(iter);39173918assert_eq!(world.resource::<TestResource>().0, 43);3919assert_eq!(3920world.resource::<TestResource2>().0,3921"Hello, world?".to_string()3922);3923}39243925#[test]3926fn dynamic_resource() {3927let mut world = World::new();39283929let descriptor = ComponentDescriptor::new_resource::<TestResource>();39303931let component_id = world.register_resource_with_descriptor(descriptor);39323933let value = 0;3934OwningPtr::make(value, |ptr| {3935// SAFETY: value is valid for the layout of `TestResource`3936unsafe {3937world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());3938}3939});39403941// SAFETY: We know that the resource is of type `TestResource`3942let resource = unsafe {3943world3944.get_resource_by_id(component_id)3945.unwrap()3946.deref::<TestResource>()3947};3948assert_eq!(resource.0, 0);39493950assert!(world.remove_resource_by_id(component_id).is_some());3951}39523953#[test]3954fn custom_resource_with_layout() {3955static DROP_COUNT: AtomicU32 = AtomicU32::new(0);39563957let mut world = World::new();39583959// SAFETY: the drop function is valid for the layout and the data will be safe to access from any thread3960let descriptor = unsafe {3961ComponentDescriptor::new_with_layout(3962"Custom Test Component".to_string(),3963StorageType::Table,3964core::alloc::Layout::new::<[u8; 8]>(),3965Some(|ptr| {3966let data = ptr.read::<[u8; 8]>();3967assert_eq!(data, [0, 1, 2, 3, 4, 5, 6, 7]);3968DROP_COUNT.fetch_add(1, Ordering::SeqCst);3969}),3970true,3971ComponentCloneBehavior::Default,3972)3973};39743975let component_id = world.register_resource_with_descriptor(descriptor);39763977let value: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];3978OwningPtr::make(value, |ptr| {3979// SAFETY: value is valid for the component layout3980unsafe {3981world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());3982}3983});39843985// SAFETY: [u8; 8] is the correct type for the resource3986let data = unsafe {3987world3988.get_resource_by_id(component_id)3989.unwrap()3990.deref::<[u8; 8]>()3991};3992assert_eq!(*data, [0, 1, 2, 3, 4, 5, 6, 7]);39933994assert!(world.remove_resource_by_id(component_id).is_some());39953996assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);3997}39983999#[derive(Resource)]4000struct TestFromWorld(u32);4001impl FromWorld for TestFromWorld {4002fn from_world(world: &mut World) -> Self {4003let b = world.resource::<TestResource>();4004Self(b.0)4005}4006}40074008#[test]4009fn init_resource_does_not_overwrite() {4010let mut world = World::new();4011world.insert_resource(TestResource(0));4012world.init_resource::<TestFromWorld>();4013world.insert_resource(TestResource(1));4014world.init_resource::<TestFromWorld>();40154016let resource = world.resource::<TestFromWorld>();40174018assert_eq!(resource.0, 0);4019}40204021#[test]4022fn init_non_send_resource_does_not_overwrite() {4023let mut world = World::new();4024world.insert_resource(TestResource(0));4025world.init_non_send_resource::<TestFromWorld>();4026world.insert_resource(TestResource(1));4027world.init_non_send_resource::<TestFromWorld>();40284029let resource = world.non_send_resource::<TestFromWorld>();40304031assert_eq!(resource.0, 0);4032}40334034#[derive(Component)]4035struct Foo;40364037#[derive(Component)]4038struct Bar;40394040#[derive(Component)]4041struct Baz;40424043#[test]4044fn inspect_entity_components() {4045let mut world = World::new();4046let ent0 = world.spawn((Foo, Bar, Baz)).id();4047let ent1 = world.spawn((Foo, Bar)).id();4048let ent2 = world.spawn((Bar, Baz)).id();4049let ent3 = world.spawn((Foo, Baz)).id();4050let ent4 = world.spawn(Foo).id();4051let ent5 = world.spawn(Bar).id();4052let ent6 = world.spawn(Baz).id();40534054fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {4055component_infos4056.into_iter()4057.map(ComponentInfo::type_id)4058.collect()4059}40604061let foo_id = TypeId::of::<Foo>();4062let bar_id = TypeId::of::<Bar>();4063let baz_id = TypeId::of::<Baz>();4064assert_eq!(4065to_type_ids(world.inspect_entity(ent0).unwrap().collect()),4066[Some(foo_id), Some(bar_id), Some(baz_id)]4067.into_iter()4068.collect::<HashSet<_>>()4069);4070assert_eq!(4071to_type_ids(world.inspect_entity(ent1).unwrap().collect()),4072[Some(foo_id), Some(bar_id)]4073.into_iter()4074.collect::<HashSet<_>>()4075);4076assert_eq!(4077to_type_ids(world.inspect_entity(ent2).unwrap().collect()),4078[Some(bar_id), Some(baz_id)]4079.into_iter()4080.collect::<HashSet<_>>()4081);4082assert_eq!(4083to_type_ids(world.inspect_entity(ent3).unwrap().collect()),4084[Some(foo_id), Some(baz_id)]4085.into_iter()4086.collect::<HashSet<_>>()4087);4088assert_eq!(4089to_type_ids(world.inspect_entity(ent4).unwrap().collect()),4090[Some(foo_id)].into_iter().collect::<HashSet<_>>()4091);4092assert_eq!(4093to_type_ids(world.inspect_entity(ent5).unwrap().collect()),4094[Some(bar_id)].into_iter().collect::<HashSet<_>>()4095);4096assert_eq!(4097to_type_ids(world.inspect_entity(ent6).unwrap().collect()),4098[Some(baz_id)].into_iter().collect::<HashSet<_>>()4099);4100}41014102#[test]4103fn iterate_entities() {4104let mut world = World::new();4105let mut entity_counters = <HashMap<_, _>>::default();41064107let iterate_and_count_entities = |world: &World, entity_counters: &mut HashMap<_, _>| {4108entity_counters.clear();4109#[expect(deprecated, reason = "remove this test in in 0.17.0")]4110for entity in world.iter_entities() {4111let counter = entity_counters.entry(entity.id()).or_insert(0);4112*counter += 1;4113}4114};41154116// Adding one entity and validating iteration4117let ent0 = world.spawn((Foo, Bar, Baz)).id();41184119iterate_and_count_entities(&world, &mut entity_counters);4120assert_eq!(entity_counters[&ent0], 1);4121assert_eq!(entity_counters.len(), 1);41224123// Spawning three more entities and then validating iteration4124let ent1 = world.spawn((Foo, Bar)).id();4125let ent2 = world.spawn((Bar, Baz)).id();4126let ent3 = world.spawn((Foo, Baz)).id();41274128iterate_and_count_entities(&world, &mut entity_counters);41294130assert_eq!(entity_counters[&ent0], 1);4131assert_eq!(entity_counters[&ent1], 1);4132assert_eq!(entity_counters[&ent2], 1);4133assert_eq!(entity_counters[&ent3], 1);4134assert_eq!(entity_counters.len(), 4);41354136// Despawning first entity and then validating the iteration4137assert!(world.despawn(ent0));41384139iterate_and_count_entities(&world, &mut entity_counters);41404141assert_eq!(entity_counters[&ent1], 1);4142assert_eq!(entity_counters[&ent2], 1);4143assert_eq!(entity_counters[&ent3], 1);4144assert_eq!(entity_counters.len(), 3);41454146// Spawning three more entities, despawning three and then validating the iteration4147let ent4 = world.spawn(Foo).id();4148let ent5 = world.spawn(Bar).id();4149let ent6 = world.spawn(Baz).id();41504151assert!(world.despawn(ent2));4152assert!(world.despawn(ent3));4153assert!(world.despawn(ent4));41544155iterate_and_count_entities(&world, &mut entity_counters);41564157assert_eq!(entity_counters[&ent1], 1);4158assert_eq!(entity_counters[&ent5], 1);4159assert_eq!(entity_counters[&ent6], 1);4160assert_eq!(entity_counters.len(), 3);41614162// Despawning remaining entities and then validating the iteration4163assert!(world.despawn(ent1));4164assert!(world.despawn(ent5));4165assert!(world.despawn(ent6));41664167iterate_and_count_entities(&world, &mut entity_counters);41684169assert_eq!(entity_counters.len(), 0);4170}41714172#[test]4173fn iterate_entities_mut() {4174#[derive(Component, PartialEq, Debug)]4175struct A(i32);41764177#[derive(Component, PartialEq, Debug)]4178struct B(i32);41794180let mut world = World::new();41814182let a1 = world.spawn(A(1)).id();4183let a2 = world.spawn(A(2)).id();4184let b1 = world.spawn(B(1)).id();4185let b2 = world.spawn(B(2)).id();41864187#[expect(deprecated, reason = "remove this test in 0.17.0")]4188for mut entity in world.iter_entities_mut() {4189if let Some(mut a) = entity.get_mut::<A>() {4190a.0 -= 1;4191}4192}4193assert_eq!(world.entity(a1).get(), Some(&A(0)));4194assert_eq!(world.entity(a2).get(), Some(&A(1)));4195assert_eq!(world.entity(b1).get(), Some(&B(1)));4196assert_eq!(world.entity(b2).get(), Some(&B(2)));41974198#[expect(deprecated, reason = "remove this test in in 0.17.0")]4199for mut entity in world.iter_entities_mut() {4200if let Some(mut b) = entity.get_mut::<B>() {4201b.0 *= 2;4202}4203}4204assert_eq!(world.entity(a1).get(), Some(&A(0)));4205assert_eq!(world.entity(a2).get(), Some(&A(1)));4206assert_eq!(world.entity(b1).get(), Some(&B(2)));4207assert_eq!(world.entity(b2).get(), Some(&B(4)));42084209#[expect(deprecated, reason = "remove this test in in 0.17.0")]4210let mut entities = world.iter_entities_mut().collect::<Vec<_>>();4211entities.sort_by_key(|e| e.get::<A>().map(|a| a.0).or(e.get::<B>().map(|b| b.0)));4212let (a, b) = entities.split_at_mut(2);4213core::mem::swap(4214&mut a[1].get_mut::<A>().unwrap().0,4215&mut b[0].get_mut::<B>().unwrap().0,4216);4217assert_eq!(world.entity(a1).get(), Some(&A(0)));4218assert_eq!(world.entity(a2).get(), Some(&A(2)));4219assert_eq!(world.entity(b1).get(), Some(&B(1)));4220assert_eq!(world.entity(b2).get(), Some(&B(4)));4221}42224223#[test]4224fn spawn_empty_bundle() {4225let mut world = World::new();4226world.spawn(());4227}42284229#[test]4230fn get_entity() {4231let mut world = World::new();42324233let e1 = world.spawn_empty().id();4234let e2 = world.spawn_empty().id();42354236assert!(world.get_entity(e1).is_ok());4237assert!(world.get_entity([e1, e2]).is_ok());4238assert!(world4239.get_entity(&[e1, e2] /* this is an array not a slice */)4240.is_ok());4241assert!(world.get_entity(&vec![e1, e2][..]).is_ok());4242assert!(world4243.get_entity(&EntityHashSet::from_iter([e1, e2]))4244.is_ok());42454246world.entity_mut(e1).despawn();42474248assert_eq!(4249Err(e1),4250world.get_entity(e1).map(|_| {}).map_err(|e| e.entity)4251);4252assert_eq!(4253Err(e1),4254world.get_entity([e1, e2]).map(|_| {}).map_err(|e| e.entity)4255);4256assert_eq!(4257Err(e1),4258world4259.get_entity(&[e1, e2] /* this is an array not a slice */)4260.map(|_| {})4261.map_err(|e| e.entity)4262);4263assert_eq!(4264Err(e1),4265world4266.get_entity(&vec![e1, e2][..])4267.map(|_| {})4268.map_err(|e| e.entity)4269);4270assert_eq!(4271Err(e1),4272world4273.get_entity(&EntityHashSet::from_iter([e1, e2]))4274.map(|_| {})4275.map_err(|e| e.entity)4276);4277}42784279#[test]4280fn get_entity_mut() {4281let mut world = World::new();42824283let e1 = world.spawn_empty().id();4284let e2 = world.spawn_empty().id();42854286assert!(world.get_entity_mut(e1).is_ok());4287assert!(world.get_entity_mut([e1, e2]).is_ok());4288assert!(world4289.get_entity_mut(&[e1, e2] /* this is an array not a slice */)4290.is_ok());4291assert!(world.get_entity_mut(&vec![e1, e2][..]).is_ok());4292assert!(world4293.get_entity_mut(&EntityHashSet::from_iter([e1, e2]))4294.is_ok());42954296assert_eq!(4297Err(EntityMutableFetchError::AliasedMutability(e1)),4298world.get_entity_mut([e1, e2, e1]).map(|_| {})4299);4300assert_eq!(4301Err(EntityMutableFetchError::AliasedMutability(e1)),4302world4303.get_entity_mut(&[e1, e2, e1] /* this is an array not a slice */)4304.map(|_| {})4305);4306assert_eq!(4307Err(EntityMutableFetchError::AliasedMutability(e1)),4308world.get_entity_mut(&vec![e1, e2, e1][..]).map(|_| {})4309);4310// Aliased mutability isn't allowed by HashSets4311assert!(world4312.get_entity_mut(&EntityHashSet::from_iter([e1, e2, e1]))4313.is_ok());43144315world.entity_mut(e1).despawn();43164317assert!(matches!(4318world.get_entity_mut(e1).map(|_| {}),4319Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e14320));4321assert!(matches!(4322world.get_entity_mut([e1, e2]).map(|_| {}),4323Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1));4324assert!(matches!(4325world4326.get_entity_mut(&[e1, e2] /* this is an array not a slice */)4327.map(|_| {}),4328Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1));4329assert!(matches!(4330world.get_entity_mut(&vec![e1, e2][..]).map(|_| {}),4331Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1,4332));4333assert!(matches!(4334world4335.get_entity_mut(&EntityHashSet::from_iter([e1, e2]))4336.map(|_| {}),4337Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1));4338}43394340#[test]4341#[track_caller]4342fn entity_spawn_despawn_tracking() {4343use core::panic::Location;43444345let mut world = World::new();4346let entity = world.spawn_empty().id();4347assert_eq!(4348world.entities.entity_get_spawned_or_despawned_by(entity),4349MaybeLocation::new(Some(Location::caller()))4350);4351assert_eq!(4352world.entities.entity_get_spawned_or_despawned_at(entity),4353Some(world.change_tick())4354);4355world.despawn(entity);4356assert_eq!(4357world.entities.entity_get_spawned_or_despawned_by(entity),4358MaybeLocation::new(Some(Location::caller()))4359);4360assert_eq!(4361world.entities.entity_get_spawned_or_despawned_at(entity),4362Some(world.change_tick())4363);4364let new = world.spawn_empty().id();4365assert_eq!(entity.index(), new.index());4366assert_eq!(4367world.entities.entity_get_spawned_or_despawned_by(entity),4368MaybeLocation::new(None)4369);4370assert_eq!(4371world.entities.entity_get_spawned_or_despawned_at(entity),4372None4373);4374world.despawn(new);4375assert_eq!(4376world.entities.entity_get_spawned_or_despawned_by(entity),4377MaybeLocation::new(None)4378);4379assert_eq!(4380world.entities.entity_get_spawned_or_despawned_at(entity),4381None4382);4383}43844385#[test]4386fn new_world_has_disabling() {4387let mut world = World::new();4388world.spawn(Foo);4389world.spawn((Foo, Disabled));4390assert_eq!(1, world.query::<&Foo>().iter(&world).count());43914392// If we explicitly remove the resource, no entities should be filtered anymore4393world.remove_resource::<DefaultQueryFilters>();4394assert_eq!(2, world.query::<&Foo>().iter(&world).count());4395}43964397#[test]4398fn entities_and_commands() {4399#[derive(Component, PartialEq, Debug)]4400struct Foo(u32);44014402let mut world = World::new();44034404let eid = world.spawn(Foo(35)).id();44054406let (mut fetcher, mut commands) = world.entities_and_commands();4407let emut = fetcher.get_mut(eid).unwrap();4408commands.entity(eid).despawn();4409assert_eq!(emut.get::<Foo>().unwrap(), &Foo(35));44104411world.flush();44124413assert!(world.get_entity(eid).is_err());4414}44154416#[test]4417fn entities_and_commands_deferred() {4418#[derive(Component, PartialEq, Debug)]4419struct Foo(u32);44204421let mut world = World::new();44224423let eid = world.spawn(Foo(1)).id();44244425let mut dworld = DeferredWorld::from(&mut world);44264427let (mut fetcher, mut commands) = dworld.entities_and_commands();4428let emut = fetcher.get_mut(eid).unwrap();4429commands.entity(eid).despawn();4430assert_eq!(emut.get::<Foo>().unwrap(), &Foo(1));44314432world.flush();44334434assert!(world.get_entity(eid).is_err());4435}4436}443744384439