//! 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, BundleId, BundleInfo, BundleInserter, BundleSpawner, Bundles, InsertMode,35NoBundleEffect,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},46lifecycle::{ComponentHooks, RemovedComponentMessages, ADD, DESPAWN, INSERT, REMOVE, REPLACE},47message::{Message, MessageId, Messages, WriteBatchIds},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::{move_as_ptr, MovingPtr, 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: RemovedComponentMessages,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 [`RemovedComponentMessages`] collection255#[inline]256pub fn removed_components(&self) -> &RemovedComponentMessages {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<'_> {1154move_as_ptr!(bundle);1155self.spawn_with_caller(bundle, MaybeLocation::caller())1156}11571158pub(crate) fn spawn_with_caller<B: Bundle>(1159&mut self,1160bundle: MovingPtr<'_, B>,1161caller: MaybeLocation,1162) -> EntityWorldMut<'_> {1163self.flush();1164let change_tick = self.change_tick();1165let entity = self.entities.alloc();1166let mut bundle_spawner = BundleSpawner::new::<B>(self, change_tick);1167let (bundle, entity_location) = bundle.partial_move(|bundle| {1168// SAFETY:1169// - `B` matches `bundle_spawner`'s type1170// - `entity` is allocated but non-existent1171// - `B::Effect` is unconstrained, and `B::apply_effect` is called exactly once on the bundle after this call.1172// - This function ensures that the value pointed to by `bundle` must not be accessed for anything afterwards by consuming1173// the `MovingPtr`. The value is otherwise only used to call `apply_effect` within this function, and the safety invariants1174// of `DynamicBundle` ensure that only the elements that have not been moved out of by this call are accessed.1175unsafe { bundle_spawner.spawn_non_existent::<B>(entity, bundle, caller) }1176});11771178let mut entity_location = Some(entity_location);11791180// SAFETY: command_queue is not referenced anywhere else1181if !unsafe { self.command_queue.is_empty() } {1182self.flush();1183entity_location = self.entities().get(entity);1184}11851186// SAFETY: entity and location are valid, as they were just created above1187let mut entity = unsafe { EntityWorldMut::new(self, entity, entity_location) };1188// SAFETY:1189// - This is called exactly once after `get_components` has been called in `spawn_non_existent`.1190// - `bundle` had it's `get_components` function called exactly once inside `spawn_non_existent`.1191unsafe { B::apply_effect(bundle, &mut entity) };1192entity1193}11941195/// # Safety1196/// must be called on an entity that was just allocated1197unsafe fn spawn_at_empty_internal(1198&mut self,1199entity: Entity,1200caller: MaybeLocation,1201) -> EntityWorldMut<'_> {1202let archetype = self.archetypes.empty_mut();1203// PERF: consider avoiding allocating entities in the empty archetype unless needed1204let table_row = self.storages.tables[archetype.table_id()].allocate(entity);1205// SAFETY: no components are allocated by archetype.allocate() because the archetype is1206// empty1207let location = unsafe { archetype.allocate(entity, table_row) };1208let change_tick = self.change_tick();1209self.entities.set(entity.index(), Some(location));1210self.entities1211.mark_spawn_despawn(entity.index(), caller, change_tick);12121213EntityWorldMut::new(self, entity, Some(location))1214}12151216/// Spawns a batch of entities with the same component [`Bundle`] type. Takes a given1217/// [`Bundle`] iterator and returns a corresponding [`Entity`] iterator.1218/// This is more efficient than spawning entities and adding components to them individually1219/// using [`World::spawn`], but it is limited to spawning entities with the same [`Bundle`]1220/// type, whereas spawning individually is more flexible.1221///1222/// ```1223/// use bevy_ecs::{component::Component, entity::Entity, world::World};1224///1225/// #[derive(Component)]1226/// struct Str(&'static str);1227/// #[derive(Component)]1228/// struct Num(u32);1229///1230/// let mut world = World::new();1231/// let entities = world.spawn_batch(vec![1232/// (Str("a"), Num(0)), // the first entity1233/// (Str("b"), Num(1)), // the second entity1234/// ]).collect::<Vec<Entity>>();1235///1236/// assert_eq!(entities.len(), 2);1237/// ```1238#[track_caller]1239pub fn spawn_batch<I>(&mut self, iter: I) -> SpawnBatchIter<'_, I::IntoIter>1240where1241I: IntoIterator,1242I::Item: Bundle<Effect: NoBundleEffect>,1243{1244SpawnBatchIter::new(self, iter.into_iter(), MaybeLocation::caller())1245}12461247/// Retrieves a reference to the given `entity`'s [`Component`] of the given type.1248/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1249/// ```1250/// use bevy_ecs::{component::Component, world::World};1251///1252/// #[derive(Component)]1253/// struct Position {1254/// x: f32,1255/// y: f32,1256/// }1257///1258/// let mut world = World::new();1259/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1260/// let position = world.get::<Position>(entity).unwrap();1261/// assert_eq!(position.x, 0.0);1262/// ```1263#[inline]1264pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {1265self.get_entity(entity).ok()?.get()1266}12671268/// Retrieves a mutable reference to the given `entity`'s [`Component`] of the given type.1269/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1270/// ```1271/// use bevy_ecs::{component::Component, world::World};1272///1273/// #[derive(Component)]1274/// struct Position {1275/// x: f32,1276/// y: f32,1277/// }1278///1279/// let mut world = World::new();1280/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1281/// let mut position = world.get_mut::<Position>(entity).unwrap();1282/// position.x = 1.0;1283/// ```1284#[inline]1285pub fn get_mut<T: Component<Mutability = Mutable>>(1286&mut self,1287entity: Entity,1288) -> Option<Mut<'_, T>> {1289self.get_entity_mut(entity).ok()?.into_mut()1290}12911292/// Temporarily removes a [`Component`] `T` from the provided [`Entity`] and1293/// runs the provided closure on it, returning the result if `T` was available.1294/// This will trigger the `Remove` and `Replace` component hooks without1295/// causing an archetype move.1296///1297/// This is most useful with immutable components, where removal and reinsertion1298/// is the only way to modify a value.1299///1300/// If you do not need to ensure the above hooks are triggered, and your component1301/// is mutable, prefer using [`get_mut`](World::get_mut).1302///1303/// # Examples1304///1305/// ```rust1306/// # use bevy_ecs::prelude::*;1307/// #1308/// #[derive(Component, PartialEq, Eq, Debug)]1309/// #[component(immutable)]1310/// struct Foo(bool);1311///1312/// # let mut world = World::default();1313/// # world.register_component::<Foo>();1314/// #1315/// # let entity = world.spawn(Foo(false)).id();1316/// #1317/// world.modify_component(entity, |foo: &mut Foo| {1318/// foo.0 = true;1319/// });1320/// #1321/// # assert_eq!(world.get::<Foo>(entity), Some(&Foo(true)));1322/// ```1323#[inline]1324#[track_caller]1325pub fn modify_component<T: Component, R>(1326&mut self,1327entity: Entity,1328f: impl FnOnce(&mut T) -> R,1329) -> Result<Option<R>, EntityMutableFetchError> {1330let mut world = DeferredWorld::from(&mut *self);13311332let result = world.modify_component_with_relationship_hook_mode(1333entity,1334RelationshipHookMode::Run,1335f,1336)?;13371338self.flush();1339Ok(result)1340}13411342/// Temporarily removes a [`Component`] identified by the provided1343/// [`ComponentId`] from the provided [`Entity`] and runs the provided1344/// closure on it, returning the result if the component was available.1345/// This will trigger the `Remove` and `Replace` component hooks without1346/// causing an archetype move.1347///1348/// This is most useful with immutable components, where removal and reinsertion1349/// is the only way to modify a value.1350///1351/// If you do not need to ensure the above hooks are triggered, and your component1352/// is mutable, prefer using [`get_mut_by_id`](World::get_mut_by_id).1353///1354/// You should prefer the typed [`modify_component`](World::modify_component)1355/// whenever possible.1356#[inline]1357#[track_caller]1358pub fn modify_component_by_id<R>(1359&mut self,1360entity: Entity,1361component_id: ComponentId,1362f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,1363) -> Result<Option<R>, EntityMutableFetchError> {1364let mut world = DeferredWorld::from(&mut *self);13651366let result = world.modify_component_by_id_with_relationship_hook_mode(1367entity,1368component_id,1369RelationshipHookMode::Run,1370f,1371)?;13721373self.flush();1374Ok(result)1375}13761377/// Despawns the given [`Entity`], if it exists. This will also remove all of the entity's1378/// [`Components`](Component).1379///1380/// Returns `true` if the entity is successfully despawned and `false` if1381/// the entity does not exist.1382///1383/// # Note1384///1385/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1386/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1387///1388/// ```1389/// use bevy_ecs::{component::Component, world::World};1390///1391/// #[derive(Component)]1392/// struct Position {1393/// x: f32,1394/// y: f32,1395/// }1396///1397/// let mut world = World::new();1398/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1399/// assert!(world.despawn(entity));1400/// assert!(world.get_entity(entity).is_err());1401/// assert!(world.get::<Position>(entity).is_none());1402/// ```1403#[track_caller]1404#[inline]1405pub fn despawn(&mut self, entity: Entity) -> bool {1406if let Err(error) = self.despawn_with_caller(entity, MaybeLocation::caller()) {1407warn!("{error}");1408false1409} else {1410true1411}1412}14131414/// Despawns the given `entity`, if it exists. This will also remove all of the entity's1415/// [`Components`](Component).1416///1417/// Returns an [`EntityDespawnError`] if the entity does not exist.1418///1419/// # Note1420///1421/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1422/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1423#[track_caller]1424#[inline]1425pub fn try_despawn(&mut self, entity: Entity) -> Result<(), EntityDespawnError> {1426self.despawn_with_caller(entity, MaybeLocation::caller())1427}14281429#[inline]1430pub(crate) fn despawn_with_caller(1431&mut self,1432entity: Entity,1433caller: MaybeLocation,1434) -> Result<(), EntityDespawnError> {1435self.flush();1436let entity = self.get_entity_mut(entity)?;1437entity.despawn_with_caller(caller);1438Ok(())1439}14401441/// Clears the internal component tracker state.1442///1443/// The world maintains some internal state about changed and removed components. This state1444/// is used by [`RemovedComponents`] to provide access to the entities that had a specific type1445/// of component removed since last tick.1446///1447/// The state is also used for change detection when accessing components and resources outside1448/// of a system, for example via [`World::get_mut()`] or [`World::get_resource_mut()`].1449///1450/// By clearing this internal state, the world "forgets" about those changes, allowing a new round1451/// of detection to be recorded.1452///1453/// When using `bevy_ecs` as part of the full Bevy engine, this method is called automatically1454/// by `bevy_app::App::update` and `bevy_app::SubApp::update`, so you don't need to call it manually.1455/// When using `bevy_ecs` as a separate standalone crate however, you do need to call this manually.1456///1457/// ```1458/// # use bevy_ecs::prelude::*;1459/// # #[derive(Component, Default)]1460/// # struct Transform;1461/// // a whole new world1462/// let mut world = World::new();1463///1464/// // you changed it1465/// let entity = world.spawn(Transform::default()).id();1466///1467/// // change is detected1468/// let transform = world.get_mut::<Transform>(entity).unwrap();1469/// assert!(transform.is_changed());1470///1471/// // update the last change tick1472/// world.clear_trackers();1473///1474/// // change is no longer detected1475/// let transform = world.get_mut::<Transform>(entity).unwrap();1476/// assert!(!transform.is_changed());1477/// ```1478///1479/// [`RemovedComponents`]: crate::lifecycle::RemovedComponents1480pub fn clear_trackers(&mut self) {1481self.removed_components.update();1482self.last_change_tick = self.increment_change_tick();1483}14841485/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1486/// run queries on the [`World`] by storing and reusing the [`QueryState`].1487/// ```1488/// use bevy_ecs::{component::Component, entity::Entity, world::World};1489///1490/// #[derive(Component, Debug, PartialEq)]1491/// struct Position {1492/// x: f32,1493/// y: f32,1494/// }1495///1496/// #[derive(Component)]1497/// struct Velocity {1498/// x: f32,1499/// y: f32,1500/// }1501///1502/// let mut world = World::new();1503/// let entities = world.spawn_batch(vec![1504/// (Position { x: 0.0, y: 0.0}, Velocity { x: 1.0, y: 0.0 }),1505/// (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }),1506/// ]).collect::<Vec<Entity>>();1507///1508/// let mut query = world.query::<(&mut Position, &Velocity)>();1509/// for (mut position, velocity) in query.iter_mut(&mut world) {1510/// position.x += velocity.x;1511/// position.y += velocity.y;1512/// }1513///1514/// assert_eq!(world.get::<Position>(entities[0]).unwrap(), &Position { x: 1.0, y: 0.0 });1515/// assert_eq!(world.get::<Position>(entities[1]).unwrap(), &Position { x: 0.0, y: 1.0 });1516/// ```1517///1518/// To iterate over entities in a deterministic order,1519/// sort the results of the query using the desired component as a key.1520/// Note that this requires fetching the whole result set from the query1521/// and allocation of a [`Vec`] to store it.1522///1523/// ```1524/// use bevy_ecs::{component::Component, entity::Entity, world::World};1525///1526/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Debug)]1527/// struct Order(i32);1528/// #[derive(Component, PartialEq, Debug)]1529/// struct Label(&'static str);1530///1531/// let mut world = World::new();1532/// let a = world.spawn((Order(2), Label("second"))).id();1533/// let b = world.spawn((Order(3), Label("third"))).id();1534/// let c = world.spawn((Order(1), Label("first"))).id();1535/// let mut entities = world.query::<(Entity, &Order, &Label)>()1536/// .iter(&world)1537/// .collect::<Vec<_>>();1538/// // Sort the query results by their `Order` component before comparing1539/// // to expected results. Query iteration order should not be relied on.1540/// entities.sort_by_key(|e| e.1);1541/// assert_eq!(entities, vec![1542/// (c, &Order(1), &Label("first")),1543/// (a, &Order(2), &Label("second")),1544/// (b, &Order(3), &Label("third")),1545/// ]);1546/// ```1547#[inline]1548pub fn query<D: QueryData>(&mut self) -> QueryState<D, ()> {1549self.query_filtered::<D, ()>()1550}15511552/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1553/// run queries on the [`World`] by storing and reusing the [`QueryState`].1554/// ```1555/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1556///1557/// #[derive(Component)]1558/// struct A;1559/// #[derive(Component)]1560/// struct B;1561///1562/// let mut world = World::new();1563/// let e1 = world.spawn(A).id();1564/// let e2 = world.spawn((A, B)).id();1565///1566/// let mut query = world.query_filtered::<Entity, With<B>>();1567/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1568///1569/// assert_eq!(matching_entities, vec![e2]);1570/// ```1571#[inline]1572pub fn query_filtered<D: QueryData, F: QueryFilter>(&mut self) -> QueryState<D, F> {1573QueryState::new(self)1574}15751576/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1577/// run queries on the [`World`] by storing and reusing the [`QueryState`].1578/// ```1579/// use bevy_ecs::{component::Component, entity::Entity, world::World};1580///1581/// #[derive(Component, Debug, PartialEq)]1582/// struct Position {1583/// x: f32,1584/// y: f32,1585/// }1586///1587/// let mut world = World::new();1588/// world.spawn_batch(vec![1589/// Position { x: 0.0, y: 0.0 },1590/// Position { x: 1.0, y: 1.0 },1591/// ]);1592///1593/// fn get_positions(world: &World) -> Vec<(Entity, &Position)> {1594/// let mut query = world.try_query::<(Entity, &Position)>().unwrap();1595/// query.iter(world).collect()1596/// }1597///1598/// let positions = get_positions(&world);1599///1600/// assert_eq!(world.get::<Position>(positions[0].0).unwrap(), positions[0].1);1601/// assert_eq!(world.get::<Position>(positions[1].0).unwrap(), positions[1].1);1602/// ```1603///1604/// Requires only an immutable world reference, but may fail if, for example,1605/// the components that make up this query have not been registered into the world.1606/// ```1607/// use bevy_ecs::{component::Component, entity::Entity, world::World};1608///1609/// #[derive(Component)]1610/// struct A;1611///1612/// let mut world = World::new();1613///1614/// let none_query = world.try_query::<&A>();1615/// assert!(none_query.is_none());1616///1617/// world.register_component::<A>();1618///1619/// let some_query = world.try_query::<&A>();1620/// assert!(some_query.is_some());1621/// ```1622#[inline]1623pub fn try_query<D: QueryData>(&self) -> Option<QueryState<D, ()>> {1624self.try_query_filtered::<D, ()>()1625}16261627/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1628/// run queries on the [`World`] by storing and reusing the [`QueryState`].1629/// ```1630/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1631///1632/// #[derive(Component)]1633/// struct A;1634/// #[derive(Component)]1635/// struct B;1636///1637/// let mut world = World::new();1638/// let e1 = world.spawn(A).id();1639/// let e2 = world.spawn((A, B)).id();1640///1641/// let mut query = world.try_query_filtered::<Entity, With<B>>().unwrap();1642/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1643///1644/// assert_eq!(matching_entities, vec![e2]);1645/// ```1646///1647/// Requires only an immutable world reference, but may fail if, for example,1648/// the components that make up this query have not been registered into the world.1649#[inline]1650pub fn try_query_filtered<D: QueryData, F: QueryFilter>(&self) -> Option<QueryState<D, F>> {1651QueryState::try_new(self)1652}16531654/// Returns an iterator of entities that had components of type `T` removed1655/// since the last call to [`World::clear_trackers`].1656pub fn removed<T: Component>(&self) -> impl Iterator<Item = Entity> + '_ {1657self.components1658.get_valid_id(TypeId::of::<T>())1659.map(|component_id| self.removed_with_id(component_id))1660.into_iter()1661.flatten()1662}16631664/// Returns an iterator of entities that had components with the given `component_id` removed1665/// since the last call to [`World::clear_trackers`].1666pub fn removed_with_id(&self, component_id: ComponentId) -> impl Iterator<Item = Entity> + '_ {1667self.removed_components1668.get(component_id)1669.map(|removed| removed.iter_current_update_messages().cloned())1670.into_iter()1671.flatten()1672.map(Into::into)1673}16741675/// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.1676///1677/// This enables the dynamic registration of new [`Resource`] definitions at runtime for1678/// advanced use cases.1679///1680/// # Note1681///1682/// Registering a [`Resource`] does not insert it into [`World`]. For insertion, you could use1683/// [`World::insert_resource_by_id`].1684pub fn register_resource_with_descriptor(1685&mut self,1686descriptor: ComponentDescriptor,1687) -> ComponentId {1688self.components_registrator()1689.register_resource_with_descriptor(descriptor)1690}16911692/// Initializes a new resource and returns the [`ComponentId`] created for it.1693///1694/// If the resource already exists, nothing happens.1695///1696/// The value given by the [`FromWorld::from_world`] method will be used.1697/// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],1698/// and those default values will be here instead.1699#[inline]1700#[track_caller]1701pub fn init_resource<R: Resource + FromWorld>(&mut self) -> ComponentId {1702let caller = MaybeLocation::caller();1703let component_id = self.components_registrator().register_resource::<R>();1704if self1705.storages1706.resources1707.get(component_id)1708.is_none_or(|data| !data.is_present())1709{1710let value = R::from_world(self);1711OwningPtr::make(value, |ptr| {1712// SAFETY: component_id was just initialized and corresponds to resource of type R.1713unsafe {1714self.insert_resource_by_id(component_id, ptr, caller);1715}1716});1717}1718component_id1719}17201721/// Inserts a new resource with the given `value`.1722///1723/// Resources are "unique" data of a given type.1724/// If you insert a resource of a type that already exists,1725/// you will overwrite any existing data.1726#[inline]1727#[track_caller]1728pub fn insert_resource<R: Resource>(&mut self, value: R) {1729self.insert_resource_with_caller(value, MaybeLocation::caller());1730}17311732/// Split into a new function so we can pass the calling location into the function when using1733/// as a command.1734#[inline]1735pub(crate) fn insert_resource_with_caller<R: Resource>(1736&mut self,1737value: R,1738caller: MaybeLocation,1739) {1740let component_id = self.components_registrator().register_resource::<R>();1741OwningPtr::make(value, |ptr| {1742// SAFETY: component_id was just initialized and corresponds to resource of type R.1743unsafe {1744self.insert_resource_by_id(component_id, ptr, caller);1745}1746});1747}17481749/// Initializes a new non-send resource and returns the [`ComponentId`] created for it.1750///1751/// If the resource already exists, nothing happens.1752///1753/// The value given by the [`FromWorld::from_world`] method will be used.1754/// Note that any resource with the `Default` trait automatically implements `FromWorld`,1755/// and those default values will be here instead.1756///1757/// # Panics1758///1759/// Panics if called from a thread other than the main thread.1760#[inline]1761#[track_caller]1762pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> ComponentId {1763let caller = MaybeLocation::caller();1764let component_id = self.components_registrator().register_non_send::<R>();1765if self1766.storages1767.non_send_resources1768.get(component_id)1769.is_none_or(|data| !data.is_present())1770{1771let value = R::from_world(self);1772OwningPtr::make(value, |ptr| {1773// SAFETY: component_id was just initialized and corresponds to resource of type R.1774unsafe {1775self.insert_non_send_by_id(component_id, ptr, caller);1776}1777});1778}1779component_id1780}17811782/// Inserts a new non-send resource with the given `value`.1783///1784/// `NonSend` resources cannot be sent across threads,1785/// and do not need the `Send + Sync` bounds.1786/// Systems with `NonSend` resources are always scheduled on the main thread.1787///1788/// # Panics1789/// If a value is already present, this function will panic if called1790/// from a different thread than where the original value was inserted from.1791#[inline]1792#[track_caller]1793pub fn insert_non_send_resource<R: 'static>(&mut self, value: R) {1794let caller = MaybeLocation::caller();1795let component_id = self.components_registrator().register_non_send::<R>();1796OwningPtr::make(value, |ptr| {1797// SAFETY: component_id was just initialized and corresponds to resource of type R.1798unsafe {1799self.insert_non_send_by_id(component_id, ptr, caller);1800}1801});1802}18031804/// Removes the resource of a given type and returns it, if it exists. Otherwise returns `None`.1805#[inline]1806pub fn remove_resource<R: Resource>(&mut self) -> Option<R> {1807let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;1808let (ptr, _, _) = self.storages.resources.get_mut(component_id)?.remove()?;1809// SAFETY: `component_id` was gotten via looking up the `R` type1810unsafe { Some(ptr.read::<R>()) }1811}18121813/// Removes a `!Send` resource from the world and returns it, if present.1814///1815/// `NonSend` resources cannot be sent across threads,1816/// and do not need the `Send + Sync` bounds.1817/// Systems with `NonSend` resources are always scheduled on the main thread.1818///1819/// Returns `None` if a value was not previously present.1820///1821/// # Panics1822/// If a value is present, this function will panic if called from a different1823/// thread than where the value was inserted from.1824#[inline]1825pub fn remove_non_send_resource<R: 'static>(&mut self) -> Option<R> {1826let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;1827let (ptr, _, _) = self1828.storages1829.non_send_resources1830.get_mut(component_id)?1831.remove()?;1832// SAFETY: `component_id` was gotten via looking up the `R` type1833unsafe { Some(ptr.read::<R>()) }1834}18351836/// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.1837#[inline]1838pub fn contains_resource<R: Resource>(&self) -> bool {1839self.components1840.get_valid_resource_id(TypeId::of::<R>())1841.and_then(|component_id| self.storages.resources.get(component_id))1842.is_some_and(ResourceData::is_present)1843}18441845/// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.1846#[inline]1847pub fn contains_resource_by_id(&self, component_id: ComponentId) -> bool {1848self.storages1849.resources1850.get(component_id)1851.is_some_and(ResourceData::is_present)1852}18531854/// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.1855#[inline]1856pub fn contains_non_send<R: 'static>(&self) -> bool {1857self.components1858.get_valid_resource_id(TypeId::of::<R>())1859.and_then(|component_id| self.storages.non_send_resources.get(component_id))1860.is_some_and(ResourceData::is_present)1861}18621863/// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.1864#[inline]1865pub fn contains_non_send_by_id(&self, component_id: ComponentId) -> bool {1866self.storages1867.non_send_resources1868.get(component_id)1869.is_some_and(ResourceData::is_present)1870}18711872/// Returns `true` if a resource of type `R` exists and was added since the world's1873/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1874///1875/// This means that:1876/// - When called from an exclusive system, this will check for additions since the system last ran.1877/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]1878/// was called.1879pub fn is_resource_added<R: Resource>(&self) -> bool {1880self.components1881.get_valid_resource_id(TypeId::of::<R>())1882.is_some_and(|component_id| self.is_resource_added_by_id(component_id))1883}18841885/// Returns `true` if a resource with id `component_id` exists and was added since the world's1886/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1887///1888/// This means that:1889/// - When called from an exclusive system, this will check for additions since the system last ran.1890/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]1891/// was called.1892pub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool {1893self.storages1894.resources1895.get(component_id)1896.is_some_and(|resource| {1897resource.get_ticks().is_some_and(|ticks| {1898ticks.is_added(self.last_change_tick(), self.read_change_tick())1899})1900})1901}19021903/// Returns `true` if a resource of type `R` exists and was modified since the world's1904/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1905///1906/// This means that:1907/// - When called from an exclusive system, this will check for changes since the system last ran.1908/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]1909/// was called.1910pub fn is_resource_changed<R: Resource>(&self) -> bool {1911self.components1912.get_valid_resource_id(TypeId::of::<R>())1913.is_some_and(|component_id| self.is_resource_changed_by_id(component_id))1914}19151916/// Returns `true` if a resource with id `component_id` exists and was modified since the world's1917/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.1918///1919/// This means that:1920/// - When called from an exclusive system, this will check for changes since the system last ran.1921/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]1922/// was called.1923pub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool {1924self.storages1925.resources1926.get(component_id)1927.is_some_and(|resource| {1928resource.get_ticks().is_some_and(|ticks| {1929ticks.is_changed(self.last_change_tick(), self.read_change_tick())1930})1931})1932}19331934/// Retrieves the change ticks for the given resource.1935pub fn get_resource_change_ticks<R: Resource>(&self) -> Option<ComponentTicks> {1936self.components1937.get_valid_resource_id(TypeId::of::<R>())1938.and_then(|component_id| self.get_resource_change_ticks_by_id(component_id))1939}19401941/// Retrieves the change ticks for the given [`ComponentId`].1942///1943/// **You should prefer to use the typed API [`World::get_resource_change_ticks`] where possible.**1944pub fn get_resource_change_ticks_by_id(1945&self,1946component_id: ComponentId,1947) -> Option<ComponentTicks> {1948self.storages1949.resources1950.get(component_id)1951.and_then(ResourceData::get_ticks)1952}19531954/// Gets a reference to the resource of the given type1955///1956/// # Panics1957///1958/// Panics if the resource does not exist.1959/// Use [`get_resource`](World::get_resource) instead if you want to handle this case.1960///1961/// If you want to instead insert a value if the resource does not exist,1962/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).1963#[inline]1964#[track_caller]1965pub fn resource<R: Resource>(&self) -> &R {1966match self.get_resource() {1967Some(x) => x,1968None => panic!(1969"Requested resource {} does not exist in the `World`.1970Did you forget to add it using `app.insert_resource` / `app.init_resource`?1971Resources are also implicitly added via `app.add_message`,1972and can be added by plugins.",1973DebugName::type_name::<R>()1974),1975}1976}19771978/// Gets a reference to the resource of the given type1979///1980/// # Panics1981///1982/// Panics if the resource does not exist.1983/// Use [`get_resource_ref`](World::get_resource_ref) instead if you want to handle this case.1984///1985/// If you want to instead insert a value if the resource does not exist,1986/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).1987#[inline]1988#[track_caller]1989pub fn resource_ref<R: Resource>(&self) -> Ref<'_, R> {1990match self.get_resource_ref() {1991Some(x) => x,1992None => panic!(1993"Requested resource {} does not exist in the `World`.1994Did you forget to add it using `app.insert_resource` / `app.init_resource`?1995Resources are also implicitly added via `app.add_message`,1996and can be added by plugins.",1997DebugName::type_name::<R>()1998),1999}2000}20012002/// Gets a mutable reference to the resource of the given type2003///2004/// # Panics2005///2006/// Panics if the resource does not exist.2007/// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.2008///2009/// If you want to instead insert a value if the resource does not exist,2010/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2011#[inline]2012#[track_caller]2013pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {2014match self.get_resource_mut() {2015Some(x) => x,2016None => panic!(2017"Requested resource {} does not exist in the `World`.2018Did you forget to add it using `app.insert_resource` / `app.init_resource`?2019Resources are also implicitly added via `app.add_message`,2020and can be added by plugins.",2021DebugName::type_name::<R>()2022),2023}2024}20252026/// Gets a reference to the resource of the given type if it exists2027#[inline]2028pub fn get_resource<R: Resource>(&self) -> Option<&R> {2029// SAFETY:2030// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2031// - `&self` ensures nothing in world is borrowed mutably2032unsafe { self.as_unsafe_world_cell_readonly().get_resource() }2033}20342035/// Gets a reference including change detection to the resource of the given type if it exists.2036#[inline]2037pub fn get_resource_ref<R: Resource>(&self) -> Option<Ref<'_, R>> {2038// SAFETY:2039// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2040// - `&self` ensures nothing in world is borrowed mutably2041unsafe { self.as_unsafe_world_cell_readonly().get_resource_ref() }2042}20432044/// Gets a mutable reference to the resource of the given type if it exists2045#[inline]2046pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {2047// SAFETY:2048// - `as_unsafe_world_cell` gives permission to access everything mutably2049// - `&mut self` ensures nothing in world is borrowed2050unsafe { self.as_unsafe_world_cell().get_resource_mut() }2051}20522053/// Gets a mutable reference to the resource of type `T` if it exists,2054/// otherwise inserts the resource using the result of calling `func`.2055///2056/// # Example2057///2058/// ```2059/// # use bevy_ecs::prelude::*;2060/// #2061/// #[derive(Resource)]2062/// struct MyResource(i32);2063///2064/// # let mut world = World::new();2065/// let my_res = world.get_resource_or_insert_with(|| MyResource(10));2066/// assert_eq!(my_res.0, 10);2067/// ```2068#[inline]2069#[track_caller]2070pub fn get_resource_or_insert_with<R: Resource>(2071&mut self,2072func: impl FnOnce() -> R,2073) -> Mut<'_, R> {2074let caller = MaybeLocation::caller();2075let change_tick = self.change_tick();2076let last_change_tick = self.last_change_tick();20772078let component_id = self.components_registrator().register_resource::<R>();2079let data = self.initialize_resource_internal(component_id);2080if !data.is_present() {2081OwningPtr::make(func(), |ptr| {2082// SAFETY: component_id was just initialized and corresponds to resource of type R.2083unsafe {2084data.insert(ptr, change_tick, caller);2085}2086});2087}20882089// SAFETY: The resource must be present, as we would have inserted it if it was empty.2090let data = unsafe {2091data.get_mut(last_change_tick, change_tick)2092.debug_checked_unwrap()2093};2094// SAFETY: The underlying type of the resource is `R`.2095unsafe { data.with_type::<R>() }2096}20972098/// Gets a mutable reference to the resource of type `T` if it exists,2099/// otherwise initializes the resource by calling its [`FromWorld`]2100/// implementation.2101///2102/// # Example2103///2104/// ```2105/// # use bevy_ecs::prelude::*;2106/// #2107/// #[derive(Resource)]2108/// struct Foo(i32);2109///2110/// impl Default for Foo {2111/// fn default() -> Self {2112/// Self(15)2113/// }2114/// }2115///2116/// #[derive(Resource)]2117/// struct MyResource(i32);2118///2119/// impl FromWorld for MyResource {2120/// fn from_world(world: &mut World) -> Self {2121/// let foo = world.get_resource_or_init::<Foo>();2122/// Self(foo.0 * 2)2123/// }2124/// }2125///2126/// # let mut world = World::new();2127/// let my_res = world.get_resource_or_init::<MyResource>();2128/// assert_eq!(my_res.0, 30);2129/// ```2130#[track_caller]2131pub fn get_resource_or_init<R: Resource + FromWorld>(&mut self) -> Mut<'_, R> {2132let caller = MaybeLocation::caller();2133let change_tick = self.change_tick();2134let last_change_tick = self.last_change_tick();21352136let component_id = self.components_registrator().register_resource::<R>();2137if self2138.storages2139.resources2140.get(component_id)2141.is_none_or(|data| !data.is_present())2142{2143let value = R::from_world(self);2144OwningPtr::make(value, |ptr| {2145// SAFETY: component_id was just initialized and corresponds to resource of type R.2146unsafe {2147self.insert_resource_by_id(component_id, ptr, caller);2148}2149});2150}21512152// SAFETY: The resource was just initialized if it was empty.2153let data = unsafe {2154self.storages2155.resources2156.get_mut(component_id)2157.debug_checked_unwrap()2158};2159// SAFETY: The resource must be present, as we would have inserted it if it was empty.2160let data = unsafe {2161data.get_mut(last_change_tick, change_tick)2162.debug_checked_unwrap()2163};2164// SAFETY: The underlying type of the resource is `R`.2165unsafe { data.with_type::<R>() }2166}21672168/// Gets an immutable reference to the non-send resource of the given type, if it exists.2169///2170/// # Panics2171///2172/// Panics if the resource does not exist.2173/// Use [`get_non_send_resource`](World::get_non_send_resource) instead if you want to handle this case.2174///2175/// This function will panic if it isn't called from the same thread that the resource was inserted from.2176#[inline]2177#[track_caller]2178pub fn non_send_resource<R: 'static>(&self) -> &R {2179match self.get_non_send_resource() {2180Some(x) => x,2181None => panic!(2182"Requested non-send resource {} does not exist in the `World`.2183Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?2184Non-send resources can also be added by plugins.",2185DebugName::type_name::<R>()2186),2187}2188}21892190/// Gets a mutable reference to the non-send resource of the given type, if it exists.2191///2192/// # Panics2193///2194/// Panics if the resource does not exist.2195/// Use [`get_non_send_resource_mut`](World::get_non_send_resource_mut) instead if you want to handle this case.2196///2197/// This function will panic if it isn't called from the same thread that the resource was inserted from.2198#[inline]2199#[track_caller]2200pub fn non_send_resource_mut<R: 'static>(&mut self) -> Mut<'_, R> {2201match self.get_non_send_resource_mut() {2202Some(x) => x,2203None => panic!(2204"Requested non-send resource {} does not exist in the `World`.2205Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?2206Non-send resources can also be added by plugins.",2207DebugName::type_name::<R>()2208),2209}2210}22112212/// Gets a reference to the non-send resource of the given type, if it exists.2213/// Otherwise returns `None`.2214///2215/// # Panics2216/// This function will panic if it isn't called from the same thread that the resource was inserted from.2217#[inline]2218pub fn get_non_send_resource<R: 'static>(&self) -> Option<&R> {2219// SAFETY:2220// - `as_unsafe_world_cell_readonly` gives permission to access the entire world immutably2221// - `&self` ensures that there are no mutable borrows of world data2222unsafe { self.as_unsafe_world_cell_readonly().get_non_send_resource() }2223}22242225/// Gets a mutable reference to the non-send resource of the given type, if it exists.2226/// Otherwise returns `None`.2227///2228/// # Panics2229/// This function will panic if it isn't called from the same thread that the resource was inserted from.2230#[inline]2231pub fn get_non_send_resource_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {2232// SAFETY:2233// - `as_unsafe_world_cell` gives permission to access the entire world mutably2234// - `&mut self` ensures that there are no borrows of world data2235unsafe { self.as_unsafe_world_cell().get_non_send_resource_mut() }2236}22372238/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2239/// adds the `Bundle` of components to each `Entity`.2240/// This is faster than doing equivalent operations one-by-one.2241///2242/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2243/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2244///2245/// This will overwrite any previous values of components shared by the `Bundle`.2246/// See [`World::insert_batch_if_new`] to keep the old values instead.2247///2248/// # Panics2249///2250/// This function will panic if any of the associated entities do not exist.2251///2252/// For the fallible version, see [`World::try_insert_batch`].2253#[track_caller]2254pub fn insert_batch<I, B>(&mut self, batch: I)2255where2256I: IntoIterator,2257I::IntoIter: Iterator<Item = (Entity, B)>,2258B: Bundle<Effect: NoBundleEffect>,2259{2260self.insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller());2261}22622263/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2264/// adds the `Bundle` of components to each `Entity` without overwriting.2265/// This is faster than doing equivalent operations one-by-one.2266///2267/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2268/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2269///2270/// This is the same as [`World::insert_batch`], but in case of duplicate2271/// components it will leave the old values instead of replacing them with new ones.2272///2273/// # Panics2274///2275/// This function will panic if any of the associated entities do not exist.2276///2277/// For the fallible version, see [`World::try_insert_batch_if_new`].2278#[track_caller]2279pub fn insert_batch_if_new<I, B>(&mut self, batch: I)2280where2281I: IntoIterator,2282I::IntoIter: Iterator<Item = (Entity, B)>,2283B: Bundle<Effect: NoBundleEffect>,2284{2285self.insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller());2286}22872288/// Split into a new function so we can differentiate the calling location.2289///2290/// This can be called by:2291/// - [`World::insert_batch`]2292/// - [`World::insert_batch_if_new`]2293#[inline]2294pub(crate) fn insert_batch_with_caller<I, B>(2295&mut self,2296batch: I,2297insert_mode: InsertMode,2298caller: MaybeLocation,2299) where2300I: IntoIterator,2301I::IntoIter: Iterator<Item = (Entity, B)>,2302B: Bundle<Effect: NoBundleEffect>,2303{2304struct InserterArchetypeCache<'w> {2305inserter: BundleInserter<'w>,2306archetype_id: ArchetypeId,2307}23082309self.flush();2310let change_tick = self.change_tick();2311let bundle_id = self.register_bundle_info::<B>();23122313let mut batch_iter = batch.into_iter();23142315if let Some((first_entity, first_bundle)) = batch_iter.next() {2316if let Some(first_location) = self.entities().get(first_entity) {2317let mut cache = InserterArchetypeCache {2318// SAFETY: we initialized this bundle_id in `register_info`2319inserter: unsafe {2320BundleInserter::new_with_id(2321self,2322first_location.archetype_id,2323bundle_id,2324change_tick,2325)2326},2327archetype_id: first_location.archetype_id,2328};23292330move_as_ptr!(first_bundle);2331// SAFETY:2332// - `entity` is valid, `location` matches entity, bundle matches inserter2333// - `apply_effect` is never called on this bundle.2334// - `first_bundle` is not be accessed or dropped after this.2335unsafe {2336cache.inserter.insert(2337first_entity,2338first_location,2339first_bundle,2340insert_mode,2341caller,2342RelationshipHookMode::Run,2343)2344};23452346for (entity, bundle) in batch_iter {2347if let Some(location) = cache.inserter.entities().get(entity) {2348if location.archetype_id != cache.archetype_id {2349cache = InserterArchetypeCache {2350// SAFETY: we initialized this bundle_id in `register_info`2351inserter: unsafe {2352BundleInserter::new_with_id(2353self,2354location.archetype_id,2355bundle_id,2356change_tick,2357)2358},2359archetype_id: location.archetype_id,2360}2361}23622363move_as_ptr!(bundle);2364// SAFETY:2365// - `entity` is valid, `location` matches entity, bundle matches inserter2366// - `apply_effect` is never called on this bundle.2367// - `bundle` is not be accessed or dropped after this.2368unsafe {2369cache.inserter.insert(2370entity,2371location,2372bundle,2373insert_mode,2374caller,2375RelationshipHookMode::Run,2376)2377};2378} else {2379panic!("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));2380}2381}2382} else {2383panic!("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));2384}2385}2386}23872388/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2389/// adds the `Bundle` of components to each `Entity`.2390/// This is faster than doing equivalent operations one-by-one.2391///2392/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2393/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2394///2395/// This will overwrite any previous values of components shared by the `Bundle`.2396/// See [`World::try_insert_batch_if_new`] to keep the old values instead.2397///2398/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2399///2400/// For the panicking version, see [`World::insert_batch`].2401#[track_caller]2402pub fn try_insert_batch<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2403where2404I: IntoIterator,2405I::IntoIter: Iterator<Item = (Entity, B)>,2406B: Bundle<Effect: NoBundleEffect>,2407{2408self.try_insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller())2409}2410/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2411/// adds the `Bundle` of components to each `Entity` without overwriting.2412/// This is faster than doing equivalent operations one-by-one.2413///2414/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2415/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2416///2417/// This is the same as [`World::try_insert_batch`], but in case of duplicate2418/// components it will leave the old values instead of replacing them with new ones.2419///2420/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2421///2422/// For the panicking version, see [`World::insert_batch_if_new`].2423#[track_caller]2424pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2425where2426I: IntoIterator,2427I::IntoIter: Iterator<Item = (Entity, B)>,2428B: Bundle<Effect: NoBundleEffect>,2429{2430self.try_insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller())2431}24322433/// Split into a new function so we can differentiate the calling location.2434///2435/// This can be called by:2436/// - [`World::try_insert_batch`]2437/// - [`World::try_insert_batch_if_new`]2438/// - [`Commands::insert_batch`]2439/// - [`Commands::insert_batch_if_new`]2440/// - [`Commands::try_insert_batch`]2441/// - [`Commands::try_insert_batch_if_new`]2442#[inline]2443pub(crate) fn try_insert_batch_with_caller<I, B>(2444&mut self,2445batch: I,2446insert_mode: InsertMode,2447caller: MaybeLocation,2448) -> Result<(), TryInsertBatchError>2449where2450I: IntoIterator,2451I::IntoIter: Iterator<Item = (Entity, B)>,2452B: Bundle<Effect: NoBundleEffect>,2453{2454struct InserterArchetypeCache<'w> {2455inserter: BundleInserter<'w>,2456archetype_id: ArchetypeId,2457}24582459self.flush();2460let change_tick = self.change_tick();2461let bundle_id = self.register_bundle_info::<B>();24622463let mut invalid_entities = Vec::<Entity>::new();2464let mut batch_iter = batch.into_iter();24652466// We need to find the first valid entity so we can initialize the bundle inserter.2467// This differs from `insert_batch_with_caller` because that method can just panic2468// if the first entity is invalid, whereas this method needs to keep going.2469let cache = loop {2470if let Some((first_entity, first_bundle)) = batch_iter.next() {2471if let Some(first_location) = self.entities().get(first_entity) {2472let mut cache = InserterArchetypeCache {2473// SAFETY: we initialized this bundle_id in `register_bundle_info`2474inserter: unsafe {2475BundleInserter::new_with_id(2476self,2477first_location.archetype_id,2478bundle_id,2479change_tick,2480)2481},2482archetype_id: first_location.archetype_id,2483};24842485move_as_ptr!(first_bundle);2486// SAFETY:2487// - `entity` is valid, `location` matches entity, bundle matches inserter2488// - `apply_effect` is never called on this bundle.2489// - `first_bundle` is not be accessed or dropped after this.2490unsafe {2491cache.inserter.insert(2492first_entity,2493first_location,2494first_bundle,2495insert_mode,2496caller,2497RelationshipHookMode::Run,2498)2499};2500break Some(cache);2501}2502invalid_entities.push(first_entity);2503} else {2504// We reached the end of the entities the caller provided and none were valid.2505break None;2506}2507};25082509if let Some(mut cache) = cache {2510for (entity, bundle) in batch_iter {2511if let Some(location) = cache.inserter.entities().get(entity) {2512if location.archetype_id != cache.archetype_id {2513cache = InserterArchetypeCache {2514// SAFETY: we initialized this bundle_id in `register_info`2515inserter: unsafe {2516BundleInserter::new_with_id(2517self,2518location.archetype_id,2519bundle_id,2520change_tick,2521)2522},2523archetype_id: location.archetype_id,2524}2525}25262527move_as_ptr!(bundle);2528// SAFETY:2529// - `entity` is valid, `location` matches entity, bundle matches inserter2530// - `apply_effect` is never called on this bundle.2531// - `bundle` is not be accessed or dropped after this.2532unsafe {2533cache.inserter.insert(2534entity,2535location,2536bundle,2537insert_mode,2538caller,2539RelationshipHookMode::Run,2540)2541};2542} else {2543invalid_entities.push(entity);2544}2545}2546}25472548if invalid_entities.is_empty() {2549Ok(())2550} else {2551Err(TryInsertBatchError {2552bundle_type: DebugName::type_name::<B>(),2553entities: invalid_entities,2554})2555}2556}25572558/// Temporarily removes the requested resource from this [`World`], runs custom user code,2559/// then re-adds the resource before returning.2560///2561/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2562/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2563///2564/// # Panics2565///2566/// Panics if the resource does not exist.2567/// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.2568///2569/// # Example2570/// ```2571/// use bevy_ecs::prelude::*;2572/// #[derive(Resource)]2573/// struct A(u32);2574/// #[derive(Component)]2575/// struct B(u32);2576/// let mut world = World::new();2577/// world.insert_resource(A(1));2578/// let entity = world.spawn(B(1)).id();2579///2580/// world.resource_scope(|world, mut a: Mut<A>| {2581/// let b = world.get_mut::<B>(entity).unwrap();2582/// a.0 += b.0;2583/// });2584/// assert_eq!(world.get_resource::<A>().unwrap().0, 2);2585/// ```2586#[track_caller]2587pub fn resource_scope<R: Resource, U>(&mut self, f: impl FnOnce(&mut World, Mut<R>) -> U) -> U {2588self.try_resource_scope(f)2589.unwrap_or_else(|| panic!("resource does not exist: {}", DebugName::type_name::<R>()))2590}25912592/// Temporarily removes the requested resource from this [`World`] if it exists, runs custom user code,2593/// then re-adds the resource before returning. Returns `None` if the resource does not exist in this [`World`].2594///2595/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2596/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2597///2598/// See also [`resource_scope`](Self::resource_scope).2599pub fn try_resource_scope<R: Resource, U>(2600&mut self,2601f: impl FnOnce(&mut World, Mut<R>) -> U,2602) -> Option<U> {2603let last_change_tick = self.last_change_tick();2604let change_tick = self.change_tick();26052606let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;2607let (ptr, mut ticks, mut caller) = self2608.storages2609.resources2610.get_mut(component_id)2611.and_then(ResourceData::remove)?;2612// Read the value onto the stack to avoid potential mut aliasing.2613// SAFETY: `ptr` was obtained from the TypeId of `R`.2614let mut value = unsafe { ptr.read::<R>() };2615let value_mut = Mut {2616value: &mut value,2617ticks: TicksMut {2618added: &mut ticks.added,2619changed: &mut ticks.changed,2620last_run: last_change_tick,2621this_run: change_tick,2622},2623changed_by: caller.as_mut(),2624};2625let result = f(self, value_mut);2626assert!(!self.contains_resource::<R>(),2627"Resource `{}` was inserted during a call to World::resource_scope.\n\2628This is not allowed as the original resource is reinserted to the world after the closure is invoked.",2629DebugName::type_name::<R>());26302631OwningPtr::make(value, |ptr| {2632// SAFETY: pointer is of type R2633unsafe {2634self.storages.resources.get_mut(component_id).map(|info| {2635info.insert_with_ticks(ptr, ticks, caller);2636})2637}2638})?;26392640Some(result)2641}26422643/// Writes a [`Message`].2644/// This method returns the [`MessageId`] of the written `message`,2645/// or [`None`] if the `message` could not be written.2646#[inline]2647pub fn write_message<M: Message>(&mut self, message: M) -> Option<MessageId<M>> {2648self.write_message_batch(core::iter::once(message))?.next()2649}26502651/// Writes a [`Message`].2652/// This method returns the [`MessageId`] of the written `event`,2653/// or [`None`] if the `event` could not be written.2654#[inline]2655#[deprecated(since = "0.17.0", note = "Use `World::write_message` instead.")]2656pub fn send_event<E: Message>(&mut self, event: E) -> Option<MessageId<E>> {2657self.write_message(event)2658}26592660/// Writes the default value of the [`Message`] of type `M`.2661/// This method returns the [`MessageId`] of the written message,2662/// or [`None`] if the `event` could not be written.2663#[inline]2664pub fn write_message_default<M: Message + Default>(&mut self) -> Option<MessageId<M>> {2665self.write_message(M::default())2666}26672668/// Writes the default value of the [`Message`] of type `E`.2669/// This method returns the [`MessageId`] of the written `event`,2670/// or [`None`] if the `event` could not be written.2671#[inline]2672#[deprecated(since = "0.17.0", note = "Use `World::write_message_default` instead.")]2673pub fn send_event_default<E: Message + Default>(&mut self) -> Option<MessageId<E>> {2674self.write_message_default::<E>()2675}26762677/// Writes a batch of [`Message`]s from an iterator.2678/// This method returns the [IDs](`MessageId`) of the written `messages`,2679/// or [`None`] if the `events` could not be written.2680#[inline]2681pub fn write_message_batch<M: Message>(2682&mut self,2683messages: impl IntoIterator<Item = M>,2684) -> Option<WriteBatchIds<M>> {2685let Some(mut events_resource) = self.get_resource_mut::<Messages<M>>() else {2686log::error!(2687"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_message ",2688DebugName::type_name::<M>()2689);2690return None;2691};2692Some(events_resource.write_batch(messages))2693}26942695/// Writes a batch of [`Message`]s from an iterator.2696/// This method returns the [IDs](`MessageId`) of the written `events`,2697/// or [`None`] if the `event` could not be written.2698#[inline]2699#[deprecated(since = "0.17.0", note = "Use `World::write_message_batch` instead.")]2700pub fn send_event_batch<E: Message>(2701&mut self,2702events: impl IntoIterator<Item = E>,2703) -> Option<WriteBatchIds<E>> {2704self.write_message_batch(events)2705}27062707/// Inserts a new resource with the given `value`. Will replace the value if it already existed.2708///2709/// **You should prefer to use the typed API [`World::insert_resource`] where possible and only2710/// use this in cases where the actual types are not known at compile time.**2711///2712/// # Safety2713/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.2714#[inline]2715#[track_caller]2716pub unsafe fn insert_resource_by_id(2717&mut self,2718component_id: ComponentId,2719value: OwningPtr<'_>,2720caller: MaybeLocation,2721) {2722let change_tick = self.change_tick();27232724let resource = self.initialize_resource_internal(component_id);2725// SAFETY: `value` is valid for `component_id`, ensured by caller2726unsafe {2727resource.insert(value, change_tick, caller);2728}2729}27302731/// Inserts a new `!Send` resource with the given `value`. Will replace the value if it already2732/// existed.2733///2734/// **You should prefer to use the typed API [`World::insert_non_send_resource`] where possible and only2735/// use this in cases where the actual types are not known at compile time.**2736///2737/// # Panics2738/// If a value is already present, this function will panic if not called from the same2739/// thread that the original value was inserted from.2740///2741/// # Safety2742/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.2743#[inline]2744#[track_caller]2745pub unsafe fn insert_non_send_by_id(2746&mut self,2747component_id: ComponentId,2748value: OwningPtr<'_>,2749caller: MaybeLocation,2750) {2751let change_tick = self.change_tick();27522753let resource = self.initialize_non_send_internal(component_id);2754// SAFETY: `value` is valid for `component_id`, ensured by caller2755unsafe {2756resource.insert(value, change_tick, caller);2757}2758}27592760/// # Panics2761/// Panics if `component_id` is not registered as a `Send` component type in this `World`2762#[inline]2763pub(crate) fn initialize_resource_internal(2764&mut self,2765component_id: ComponentId,2766) -> &mut ResourceData<true> {2767self.flush_components();2768self.storages2769.resources2770.initialize_with(component_id, &self.components)2771}27722773/// # Panics2774/// Panics if `component_id` is not registered in this world2775#[inline]2776pub(crate) fn initialize_non_send_internal(2777&mut self,2778component_id: ComponentId,2779) -> &mut ResourceData<false> {2780self.flush_components();2781self.storages2782.non_send_resources2783.initialize_with(component_id, &self.components)2784}27852786/// Empties queued entities and adds them to the empty [`Archetype`](crate::archetype::Archetype).2787/// This should be called before doing operations that might operate on queued entities,2788/// such as inserting a [`Component`].2789#[track_caller]2790pub(crate) fn flush_entities(&mut self) {2791let by = MaybeLocation::caller();2792let at = self.change_tick();2793let empty_archetype = self.archetypes.empty_mut();2794let table = &mut self.storages.tables[empty_archetype.table_id()];2795// PERF: consider pre-allocating space for flushed entities2796// SAFETY: entity is set to a valid location2797unsafe {2798self.entities.flush(2799|entity, location| {2800// SAFETY: no components are allocated by archetype.allocate() because the archetype2801// is empty2802*location = Some(empty_archetype.allocate(entity, table.allocate(entity)));2803},2804by,2805at,2806);2807}2808}28092810/// Applies any commands in the world's internal [`CommandQueue`].2811/// This does not apply commands from any systems, only those stored in the world.2812///2813/// # Panics2814/// This will panic if any of the queued commands are [`spawn`](Commands::spawn).2815/// If this is possible, you should instead use [`flush`](Self::flush).2816pub(crate) fn flush_commands(&mut self) {2817// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`2818if !unsafe { self.command_queue.is_empty() } {2819// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`2820unsafe {2821self.command_queue2822.clone()2823.apply_or_drop_queued(Some(self.into()));2824};2825}2826}28272828/// Applies any queued component registration.2829/// For spawning vanilla rust component types and resources, this is not strictly necessary.2830/// However, flushing components can make information available more quickly, and can have performance benefits.2831/// Additionally, for components and resources registered dynamically through a raw descriptor or similar,2832/// this is the only way to complete their registration.2833pub(crate) fn flush_components(&mut self) {2834self.components_registrator().apply_queued_registrations();2835}28362837/// Flushes queued entities and commands.2838///2839/// Queued entities will be spawned, and then commands will be applied.2840#[inline]2841#[track_caller]2842pub fn flush(&mut self) {2843self.flush_entities();2844self.flush_components();2845self.flush_commands();2846}28472848/// Increments the world's current change tick and returns the old value.2849///2850/// If you need to call this method, but do not have `&mut` access to the world,2851/// consider using [`as_unsafe_world_cell_readonly`](Self::as_unsafe_world_cell_readonly)2852/// to obtain an [`UnsafeWorldCell`] and calling [`increment_change_tick`](UnsafeWorldCell::increment_change_tick) on that.2853/// Note that this *can* be done in safe code, despite the name of the type.2854#[inline]2855pub fn increment_change_tick(&mut self) -> Tick {2856let change_tick = self.change_tick.get_mut();2857let prev_tick = *change_tick;2858*change_tick = change_tick.wrapping_add(1);2859Tick::new(prev_tick)2860}28612862/// Reads the current change tick of this world.2863///2864/// If you have exclusive (`&mut`) access to the world, consider using [`change_tick()`](Self::change_tick),2865/// which is more efficient since it does not require atomic synchronization.2866#[inline]2867pub fn read_change_tick(&self) -> Tick {2868let tick = self.change_tick.load(Ordering::Acquire);2869Tick::new(tick)2870}28712872/// Reads the current change tick of this world.2873///2874/// This does the same thing as [`read_change_tick()`](Self::read_change_tick), only this method2875/// is more efficient since it does not require atomic synchronization.2876#[inline]2877pub fn change_tick(&mut self) -> Tick {2878let tick = *self.change_tick.get_mut();2879Tick::new(tick)2880}28812882/// When called from within an exclusive system (a [`System`] that takes `&mut World` as its first2883/// parameter), this method returns the [`Tick`] indicating the last time the exclusive system was run.2884///2885/// Otherwise, this returns the `Tick` indicating the last time that [`World::clear_trackers`] was called.2886///2887/// [`System`]: crate::system::System2888#[inline]2889pub fn last_change_tick(&self) -> Tick {2890self.last_change_tick2891}28922893/// Returns the id of the last ECS event that was fired.2894/// Used internally to ensure observers don't trigger multiple times for the same event.2895#[inline]2896pub(crate) fn last_trigger_id(&self) -> u32 {2897self.last_trigger_id2898}28992900/// Sets [`World::last_change_tick()`] to the specified value during a scope.2901/// When the scope terminates, it will return to its old value.2902///2903/// This is useful if you need a region of code to be able to react to earlier changes made in the same system.2904///2905/// # Examples2906///2907/// ```2908/// # use bevy_ecs::prelude::*;2909/// // This function runs an update loop repeatedly, allowing each iteration of the loop2910/// // to react to changes made in the previous loop iteration.2911/// fn update_loop(2912/// world: &mut World,2913/// mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,2914/// ) {2915/// let mut last_change_tick = world.last_change_tick();2916///2917/// // Repeatedly run the update function until it requests a break.2918/// loop {2919/// let control_flow = world.last_change_tick_scope(last_change_tick, |world| {2920/// // Increment the change tick so we can detect changes from the previous update.2921/// last_change_tick = world.change_tick();2922/// world.increment_change_tick();2923///2924/// // Update once.2925/// update_fn(world)2926/// });2927///2928/// // End the loop when the closure returns `ControlFlow::Break`.2929/// if control_flow.is_break() {2930/// break;2931/// }2932/// }2933/// }2934/// #2935/// # #[derive(Resource)] struct Count(u32);2936/// # let mut world = World::new();2937/// # world.insert_resource(Count(0));2938/// # let saved_last_tick = world.last_change_tick();2939/// # let mut num_updates = 0;2940/// # update_loop(&mut world, |world| {2941/// # let mut c = world.resource_mut::<Count>();2942/// # match c.0 {2943/// # 0 => {2944/// # assert_eq!(num_updates, 0);2945/// # assert!(c.is_added());2946/// # c.0 = 1;2947/// # }2948/// # 1 => {2949/// # assert_eq!(num_updates, 1);2950/// # assert!(!c.is_added());2951/// # assert!(c.is_changed());2952/// # c.0 = 2;2953/// # }2954/// # 2 if c.is_changed() => {2955/// # assert_eq!(num_updates, 2);2956/// # assert!(!c.is_added());2957/// # }2958/// # 2 => {2959/// # assert_eq!(num_updates, 3);2960/// # assert!(!c.is_changed());2961/// # world.remove_resource::<Count>();2962/// # world.insert_resource(Count(3));2963/// # }2964/// # 3 if c.is_changed() => {2965/// # assert_eq!(num_updates, 4);2966/// # assert!(c.is_added());2967/// # }2968/// # 3 => {2969/// # assert_eq!(num_updates, 5);2970/// # assert!(!c.is_added());2971/// # c.0 = 4;2972/// # return std::ops::ControlFlow::Break(());2973/// # }2974/// # _ => unreachable!(),2975/// # }2976/// # num_updates += 1;2977/// # std::ops::ControlFlow::Continue(())2978/// # });2979/// # assert_eq!(num_updates, 5);2980/// # assert_eq!(world.resource::<Count>().0, 4);2981/// # assert_eq!(world.last_change_tick(), saved_last_tick);2982/// ```2983pub fn last_change_tick_scope<T>(2984&mut self,2985last_change_tick: Tick,2986f: impl FnOnce(&mut World) -> T,2987) -> T {2988struct LastTickGuard<'a> {2989world: &'a mut World,2990last_tick: Tick,2991}29922993// By setting the change tick in the drop impl, we ensure that2994// the change tick gets reset even if a panic occurs during the scope.2995impl Drop for LastTickGuard<'_> {2996fn drop(&mut self) {2997self.world.last_change_tick = self.last_tick;2998}2999}30003001let guard = LastTickGuard {3002last_tick: self.last_change_tick,3003world: self,3004};30053006guard.world.last_change_tick = last_change_tick;30073008f(guard.world)3009}30103011/// Iterates all component change ticks and clamps any older than [`MAX_CHANGE_AGE`](crate::change_detection::MAX_CHANGE_AGE).3012/// This also triggers [`CheckChangeTicks`] observers and returns the same event here.3013///3014/// Calling this method prevents [`Tick`]s overflowing and thus prevents false positives when comparing them.3015///3016/// **Note:** Does nothing and returns `None` if the [`World`] counter has not been incremented at least [`CHECK_TICK_THRESHOLD`]3017/// times since the previous pass.3018// TODO: benchmark and optimize3019pub fn check_change_ticks(&mut self) -> Option<CheckChangeTicks> {3020let change_tick = self.change_tick();3021if change_tick.relative_to(self.last_check_tick).get() < CHECK_TICK_THRESHOLD {3022return None;3023}30243025let check = CheckChangeTicks(change_tick);30263027let Storages {3028ref mut tables,3029ref mut sparse_sets,3030ref mut resources,3031ref mut non_send_resources,3032} = self.storages;30333034#[cfg(feature = "trace")]3035let _span = tracing::info_span!("check component ticks").entered();3036tables.check_change_ticks(check);3037sparse_sets.check_change_ticks(check);3038resources.check_change_ticks(check);3039non_send_resources.check_change_ticks(check);3040self.entities.check_change_ticks(check);30413042if let Some(mut schedules) = self.get_resource_mut::<Schedules>() {3043schedules.check_change_ticks(check);3044}30453046self.trigger(check);3047self.flush();30483049self.last_check_tick = change_tick;30503051Some(check)3052}30533054/// Runs both [`clear_entities`](Self::clear_entities) and [`clear_resources`](Self::clear_resources),3055/// invalidating all [`Entity`] and resource fetches such as [`Res`](crate::system::Res), [`ResMut`](crate::system::ResMut)3056pub fn clear_all(&mut self) {3057self.clear_entities();3058self.clear_resources();3059}30603061/// Despawns all entities in this [`World`].3062pub fn clear_entities(&mut self) {3063self.storages.tables.clear();3064self.storages.sparse_sets.clear_entities();3065self.archetypes.clear_entities();3066self.entities.clear();3067}30683069/// Clears all resources in this [`World`].3070///3071/// **Note:** Any resource fetch to this [`World`] will fail unless they are re-initialized,3072/// including engine-internal resources that are only initialized on app/world construction.3073///3074/// This can easily cause systems expecting certain resources to immediately start panicking.3075/// Use with caution.3076pub fn clear_resources(&mut self) {3077self.storages.resources.clear();3078self.storages.non_send_resources.clear();3079}30803081/// Registers all of the components in the given [`Bundle`] and returns both the component3082/// ids and the bundle id.3083///3084/// This is largely equivalent to calling [`register_component`](Self::register_component) on each3085/// component in the bundle.3086#[inline]3087pub fn register_bundle<B: Bundle>(&mut self) -> &BundleInfo {3088let id = self.register_bundle_info::<B>();30893090// SAFETY: We just initialized the bundle so its id should definitely be valid.3091unsafe { self.bundles.get(id).debug_checked_unwrap() }3092}30933094pub(crate) fn register_bundle_info<B: Bundle>(&mut self) -> BundleId {3095// SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.3096let mut registrator =3097unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };30983099// SAFETY: `registrator`, `self.storages` and `self.bundles` all come from this world.3100unsafe {3101self.bundles3102.register_info::<B>(&mut registrator, &mut self.storages)3103}3104}31053106pub(crate) fn register_contributed_bundle_info<B: Bundle>(&mut self) -> BundleId {3107// SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.3108let mut registrator =3109unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };31103111// SAFETY: `registrator`, `self.bundles` and `self.storages` are all from this world.3112unsafe {3113self.bundles3114.register_contributed_bundle_info::<B>(&mut registrator, &mut self.storages)3115}3116}31173118/// Registers the given [`ComponentId`]s as a dynamic bundle and returns both the required component ids and the bundle id.3119///3120/// Note that the components need to be registered first, this function only creates a bundle combining them. Components3121/// can be registered with [`World::register_component`]/[`_with_descriptor`](World::register_component_with_descriptor).3122///3123/// **You should prefer to use the typed API [`World::register_bundle`] where possible and only use this in cases where3124/// not all of the actual types are known at compile time.**3125///3126/// # Panics3127/// This function will panic if any of the provided component ids do not belong to a component known to this [`World`].3128#[inline]3129pub fn register_dynamic_bundle(&mut self, component_ids: &[ComponentId]) -> &BundleInfo {3130let id =3131self.bundles3132.init_dynamic_info(&mut self.storages, &self.components, component_ids);3133// SAFETY: We just initialized the bundle so its id should definitely be valid.3134unsafe { self.bundles.get(id).debug_checked_unwrap() }3135}31363137/// Convenience method for accessing the world's default error handler,3138/// which can be overwritten with [`DefaultErrorHandler`].3139#[inline]3140pub fn default_error_handler(&self) -> ErrorHandler {3141self.get_resource::<DefaultErrorHandler>()3142.copied()3143.unwrap_or_default()3144.03145}3146}31473148impl World {3149/// Gets a pointer to the resource with the id [`ComponentId`] if it exists.3150/// The returned pointer must not be used to modify the resource, and must not be3151/// dereferenced after the immutable borrow of the [`World`] ends.3152///3153/// **You should prefer to use the typed API [`World::get_resource`] where possible and only3154/// use this in cases where the actual types are not known at compile time.**3155#[inline]3156pub fn get_resource_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {3157// SAFETY:3158// - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably3159// - `&self` ensures there are no mutable borrows on world data3160unsafe {3161self.as_unsafe_world_cell_readonly()3162.get_resource_by_id(component_id)3163}3164}31653166/// Gets a pointer to the resource with the id [`ComponentId`] if it exists.3167/// The returned pointer may be used to modify the resource, as long as the mutable borrow3168/// of the [`World`] is still valid.3169///3170/// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only3171/// use this in cases where the actual types are not known at compile time.**3172#[inline]3173pub fn get_resource_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {3174// SAFETY:3175// - `&mut self` ensures that all accessed data is unaliased3176// - `as_unsafe_world_cell` provides mutable permission to the whole world3177unsafe {3178self.as_unsafe_world_cell()3179.get_resource_mut_by_id(component_id)3180}3181}31823183/// Iterates over all resources in the world.3184///3185/// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading the contents3186/// of each resource will require the use of unsafe code.3187///3188/// # Examples3189///3190/// ## Printing the size of all resources3191///3192/// ```3193/// # use bevy_ecs::prelude::*;3194/// # #[derive(Resource)]3195/// # struct A(u32);3196/// # #[derive(Resource)]3197/// # struct B(u32);3198/// #3199/// # let mut world = World::new();3200/// # world.remove_resource::<bevy_ecs::entity_disabling::DefaultQueryFilters>();3201/// # world.insert_resource(A(1));3202/// # world.insert_resource(B(2));3203/// let mut total = 0;3204/// for (info, _) in world.iter_resources() {3205/// println!("Resource: {}", info.name());3206/// println!("Size: {} bytes", info.layout().size());3207/// total += info.layout().size();3208/// }3209/// println!("Total size: {} bytes", total);3210/// # assert_eq!(total, size_of::<A>() + size_of::<B>());3211/// ```3212///3213/// ## Dynamically running closures for resources matching specific `TypeId`s3214///3215/// ```3216/// # use bevy_ecs::prelude::*;3217/// # use std::collections::HashMap;3218/// # use std::any::TypeId;3219/// # use bevy_ptr::Ptr;3220/// # #[derive(Resource)]3221/// # struct A(u32);3222/// # #[derive(Resource)]3223/// # struct B(u32);3224/// #3225/// # let mut world = World::new();3226/// # world.insert_resource(A(1));3227/// # world.insert_resource(B(2));3228/// #3229/// // In this example, `A` and `B` are resources. We deliberately do not use the3230/// // `bevy_reflect` crate here to showcase the low-level [`Ptr`] usage. You should3231/// // probably use something like `ReflectFromPtr` in a real-world scenario.3232///3233/// // Create the hash map that will store the closures for each resource type3234/// let mut closures: HashMap<TypeId, Box<dyn Fn(&Ptr<'_>)>> = HashMap::default();3235///3236/// // Add closure for `A`3237/// closures.insert(TypeId::of::<A>(), Box::new(|ptr| {3238/// // SAFETY: We assert ptr is the same type of A with TypeId of A3239/// let a = unsafe { &ptr.deref::<A>() };3240/// # assert_eq!(a.0, 1);3241/// // ... do something with `a` here3242/// }));3243///3244/// // Add closure for `B`3245/// closures.insert(TypeId::of::<B>(), Box::new(|ptr| {3246/// // SAFETY: We assert ptr is the same type of B with TypeId of B3247/// let b = unsafe { &ptr.deref::<B>() };3248/// # assert_eq!(b.0, 2);3249/// // ... do something with `b` here3250/// }));3251///3252/// // Iterate all resources, in order to run the closures for each matching resource type3253/// for (info, ptr) in world.iter_resources() {3254/// let Some(type_id) = info.type_id() else {3255/// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources3256/// // dynamically inserted via a scripting language) in which case we can't match them.3257/// continue;3258/// };3259///3260/// let Some(closure) = closures.get(&type_id) else {3261/// // No closure for this resource type, skip it.3262/// continue;3263/// };3264///3265/// // Run the closure for the resource3266/// closure(&ptr);3267/// }3268/// ```3269#[inline]3270pub fn iter_resources(&self) -> impl Iterator<Item = (&ComponentInfo, Ptr<'_>)> {3271self.storages3272.resources3273.iter()3274.filter_map(|(component_id, data)| {3275// SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.3276let component_info = unsafe {3277self.components3278.get_info(component_id)3279.debug_checked_unwrap()3280};3281Some((component_info, data.get_data()?))3282})3283}32843285/// Mutably iterates over all resources in the world.3286///3287/// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading from or writing3288/// to the contents of each resource will require the use of unsafe code.3289///3290/// # Example3291///3292/// ```3293/// # use bevy_ecs::prelude::*;3294/// # use bevy_ecs::change_detection::MutUntyped;3295/// # use std::collections::HashMap;3296/// # use std::any::TypeId;3297/// # #[derive(Resource)]3298/// # struct A(u32);3299/// # #[derive(Resource)]3300/// # struct B(u32);3301/// #3302/// # let mut world = World::new();3303/// # world.insert_resource(A(1));3304/// # world.insert_resource(B(2));3305/// #3306/// // In this example, `A` and `B` are resources. We deliberately do not use the3307/// // `bevy_reflect` crate here to showcase the low-level `MutUntyped` usage. You should3308/// // probably use something like `ReflectFromPtr` in a real-world scenario.3309///3310/// // Create the hash map that will store the mutator closures for each resource type3311/// let mut mutators: HashMap<TypeId, Box<dyn Fn(&mut MutUntyped<'_>)>> = HashMap::default();3312///3313/// // Add mutator closure for `A`3314/// mutators.insert(TypeId::of::<A>(), Box::new(|mut_untyped| {3315/// // Note: `MutUntyped::as_mut()` automatically marks the resource as changed3316/// // for ECS change detection, and gives us a `PtrMut` we can use to mutate the resource.3317/// // SAFETY: We assert ptr is the same type of A with TypeId of A3318/// let a = unsafe { &mut mut_untyped.as_mut().deref_mut::<A>() };3319/// # a.0 += 1;3320/// // ... mutate `a` here3321/// }));3322///3323/// // Add mutator closure for `B`3324/// mutators.insert(TypeId::of::<B>(), Box::new(|mut_untyped| {3325/// // SAFETY: We assert ptr is the same type of B with TypeId of B3326/// let b = unsafe { &mut mut_untyped.as_mut().deref_mut::<B>() };3327/// # b.0 += 1;3328/// // ... mutate `b` here3329/// }));3330///3331/// // Iterate all resources, in order to run the mutator closures for each matching resource type3332/// for (info, mut mut_untyped) in world.iter_resources_mut() {3333/// let Some(type_id) = info.type_id() else {3334/// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources3335/// // dynamically inserted via a scripting language) in which case we can't match them.3336/// continue;3337/// };3338///3339/// let Some(mutator) = mutators.get(&type_id) else {3340/// // No mutator closure for this resource type, skip it.3341/// continue;3342/// };3343///3344/// // Run the mutator closure for the resource3345/// mutator(&mut mut_untyped);3346/// }3347/// # assert_eq!(world.resource::<A>().0, 2);3348/// # assert_eq!(world.resource::<B>().0, 3);3349/// ```3350#[inline]3351pub fn iter_resources_mut(&mut self) -> impl Iterator<Item = (&ComponentInfo, MutUntyped<'_>)> {3352self.storages3353.resources3354.iter()3355.filter_map(|(component_id, data)| {3356// SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.3357let component_info = unsafe {3358self.components3359.get_info(component_id)3360.debug_checked_unwrap()3361};3362let (ptr, ticks, caller) = data.get_with_ticks()?;33633364// SAFETY:3365// - We have exclusive access to the world, so no other code can be aliasing the `TickCells`3366// - We only hold one `TicksMut` at a time, and we let go of it before getting the next one3367let ticks = unsafe {3368TicksMut::from_tick_cells(3369ticks,3370self.last_change_tick(),3371self.read_change_tick(),3372)3373};33743375let mut_untyped = MutUntyped {3376// SAFETY:3377// - We have exclusive access to the world, so no other code can be aliasing the `Ptr`3378// - We iterate one resource at a time, and we let go of each `PtrMut` before getting the next one3379value: unsafe { ptr.assert_unique() },3380ticks,3381// SAFETY:3382// - We have exclusive access to the world, so no other code can be aliasing the `Ptr`3383// - We iterate one resource at a time, and we let go of each `PtrMut` before getting the next one3384changed_by: unsafe { caller.map(|caller| caller.deref_mut()) },3385};33863387Some((component_info, mut_untyped))3388})3389}33903391/// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.3392/// The returned pointer must not be used to modify the resource, and must not be3393/// dereferenced after the immutable borrow of the [`World`] ends.3394///3395/// **You should prefer to use the typed API [`World::get_resource`] where possible and only3396/// use this in cases where the actual types are not known at compile time.**3397///3398/// # Panics3399/// This function will panic if it isn't called from the same thread that the resource was inserted from.3400#[inline]3401pub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {3402// SAFETY:3403// - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably3404// - `&self` ensures there are no mutable borrows on world data3405unsafe {3406self.as_unsafe_world_cell_readonly()3407.get_non_send_resource_by_id(component_id)3408}3409}34103411/// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.3412/// The returned pointer may be used to modify the resource, as long as the mutable borrow3413/// of the [`World`] is still valid.3414///3415/// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only3416/// use this in cases where the actual types are not known at compile time.**3417///3418/// # Panics3419/// This function will panic if it isn't called from the same thread that the resource was inserted from.3420#[inline]3421pub fn get_non_send_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {3422// SAFETY:3423// - `&mut self` ensures that all accessed data is unaliased3424// - `as_unsafe_world_cell` provides mutable permission to the whole world3425unsafe {3426self.as_unsafe_world_cell()3427.get_non_send_resource_mut_by_id(component_id)3428}3429}34303431/// Removes the resource of a given type, if it exists. Otherwise returns `None`.3432///3433/// **You should prefer to use the typed API [`World::remove_resource`] where possible and only3434/// use this in cases where the actual types are not known at compile time.**3435pub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> Option<()> {3436self.storages3437.resources3438.get_mut(component_id)?3439.remove_and_drop();3440Some(())3441}34423443/// Removes the resource of a given type, if it exists. Otherwise returns `None`.3444///3445/// **You should prefer to use the typed API [`World::remove_resource`] where possible and only3446/// use this in cases where the actual types are not known at compile time.**3447///3448/// # Panics3449/// This function will panic if it isn't called from the same thread that the resource was inserted from.3450pub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()> {3451self.storages3452.non_send_resources3453.get_mut(component_id)?3454.remove_and_drop();3455Some(())3456}34573458/// Retrieves an immutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].3459/// Returns `None` if the `entity` does not have a [`Component`] of the given type.3460///3461/// **You should prefer to use the typed API [`World::get_mut`] where possible and only3462/// use this in cases where the actual types are not known at compile time.**3463///3464/// # Panics3465/// This function will panic if it isn't called from the same thread that the resource was inserted from.3466#[inline]3467pub fn get_by_id(&self, entity: Entity, component_id: ComponentId) -> Option<Ptr<'_>> {3468self.get_entity(entity).ok()?.get_by_id(component_id).ok()3469}34703471/// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].3472/// Returns `None` if the `entity` does not have a [`Component`] of the given type.3473///3474/// **You should prefer to use the typed API [`World::get_mut`] where possible and only3475/// use this in cases where the actual types are not known at compile time.**3476#[inline]3477pub fn get_mut_by_id(3478&mut self,3479entity: Entity,3480component_id: ComponentId,3481) -> Option<MutUntyped<'_>> {3482self.get_entity_mut(entity)3483.ok()?3484.into_mut_by_id(component_id)3485.ok()3486}3487}34883489// Schedule-related methods3490impl World {3491/// Adds the specified [`Schedule`] to the world.3492/// If a schedule already exists with the same [label](Schedule::label), it will be replaced.3493///3494/// The schedule can later be run3495/// by calling [`.run_schedule(label)`](Self::run_schedule) or by directly3496/// accessing the [`Schedules`] resource.3497///3498/// The `Schedules` resource will be initialized if it does not already exist.3499///3500/// An alternative to this is to call [`Schedules::add_systems()`] with some3501/// [`ScheduleLabel`] and let the schedule for that label be created if it3502/// does not already exist.3503pub fn add_schedule(&mut self, schedule: Schedule) {3504let mut schedules = self.get_resource_or_init::<Schedules>();3505schedules.insert(schedule);3506}35073508/// Temporarily removes the schedule associated with `label` from the world,3509/// runs user code, and finally re-adds the schedule.3510/// This returns a [`TryRunScheduleError`] if there is no schedule3511/// associated with `label`.3512///3513/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3514/// and system state is cached.3515///3516/// For simple cases where you just need to call the schedule once,3517/// consider using [`World::try_run_schedule`] instead.3518/// For other use cases, see the example on [`World::schedule_scope`].3519pub fn try_schedule_scope<R>(3520&mut self,3521label: impl ScheduleLabel,3522f: impl FnOnce(&mut World, &mut Schedule) -> R,3523) -> Result<R, TryRunScheduleError> {3524let label = label.intern();3525let Some(mut schedule) = self3526.get_resource_mut::<Schedules>()3527.and_then(|mut s| s.remove(label))3528else {3529return Err(TryRunScheduleError(label));3530};35313532let value = f(self, &mut schedule);35333534let old = self.resource_mut::<Schedules>().insert(schedule);3535if old.is_some() {3536warn!("Schedule `{label:?}` was inserted during a call to `World::schedule_scope`: its value has been overwritten");3537}35383539Ok(value)3540}35413542/// Temporarily removes the schedule associated with `label` from the world,3543/// runs user code, and finally re-adds the schedule.3544///3545/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3546/// and system state is cached.3547///3548/// # Examples3549///3550/// ```3551/// # use bevy_ecs::{prelude::*, schedule::ScheduleLabel};3552/// # #[derive(ScheduleLabel, Debug, Clone, Copy, PartialEq, Eq, Hash)]3553/// # pub struct MySchedule;3554/// # #[derive(Resource)]3555/// # struct Counter(usize);3556/// #3557/// # let mut world = World::new();3558/// # world.insert_resource(Counter(0));3559/// # let mut schedule = Schedule::new(MySchedule);3560/// # schedule.add_systems(tick_counter);3561/// # world.init_resource::<Schedules>();3562/// # world.add_schedule(schedule);3563/// # fn tick_counter(mut counter: ResMut<Counter>) { counter.0 += 1; }3564/// // Run the schedule five times.3565/// world.schedule_scope(MySchedule, |world, schedule| {3566/// for _ in 0..5 {3567/// schedule.run(world);3568/// }3569/// });3570/// # assert_eq!(world.resource::<Counter>().0, 5);3571/// ```3572///3573/// For simple cases where you just need to call the schedule once,3574/// consider using [`World::run_schedule`] instead.3575///3576/// # Panics3577///3578/// If the requested schedule does not exist.3579pub fn schedule_scope<R>(3580&mut self,3581label: impl ScheduleLabel,3582f: impl FnOnce(&mut World, &mut Schedule) -> R,3583) -> R {3584self.try_schedule_scope(label, f)3585.unwrap_or_else(|e| panic!("{e}"))3586}35873588/// Attempts to run the [`Schedule`] associated with the `label` a single time,3589/// and returns a [`TryRunScheduleError`] if the schedule does not exist.3590///3591/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3592/// and system state is cached.3593///3594/// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.3595pub fn try_run_schedule(3596&mut self,3597label: impl ScheduleLabel,3598) -> Result<(), TryRunScheduleError> {3599self.try_schedule_scope(label, |world, sched| sched.run(world))3600}36013602/// Runs the [`Schedule`] associated with the `label` a single time.3603///3604/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3605/// and system state is cached.3606///3607/// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.3608/// This avoids the need to create a unique [`ScheduleLabel`].3609///3610/// # Panics3611///3612/// If the requested schedule does not exist.3613pub fn run_schedule(&mut self, label: impl ScheduleLabel) {3614self.schedule_scope(label, |world, sched| sched.run(world));3615}36163617/// Ignore system order ambiguities caused by conflicts on [`Component`]s of type `T`.3618pub fn allow_ambiguous_component<T: Component>(&mut self) {3619let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();3620schedules.allow_ambiguous_component::<T>(self);3621self.insert_resource(schedules);3622}36233624/// Ignore system order ambiguities caused by conflicts on [`Resource`]s of type `T`.3625pub fn allow_ambiguous_resource<T: Resource>(&mut self) {3626let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();3627schedules.allow_ambiguous_resource::<T>(self);3628self.insert_resource(schedules);3629}3630}36313632impl fmt::Debug for World {3633fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {3634// SAFETY: `UnsafeWorldCell` requires that this must only access metadata.3635// Accessing any data stored in the world would be unsound.3636f.debug_struct("World")3637.field("id", &self.id)3638.field("entity_count", &self.entities.len())3639.field("archetype_count", &self.archetypes.len())3640.field("component_count", &self.components.len())3641.field("resource_count", &self.storages.resources.len())3642.finish()3643}3644}36453646// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread3647unsafe impl Send for World {}3648// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread3649unsafe impl Sync for World {}36503651/// Creates an instance of the type this trait is implemented for3652/// using data from the supplied [`World`].3653///3654/// This can be helpful for complex initialization or context-aware defaults.3655///3656/// [`FromWorld`] is automatically implemented for any type implementing [`Default`]3657/// and may also be derived for:3658/// - any struct whose fields all implement `FromWorld`3659/// - any enum where one variant has the attribute `#[from_world]`3660///3661/// ```rs3662///3663/// #[derive(Default)]3664/// struct A;3665///3666/// #[derive(Default)]3667/// struct B(Option<u32>)3668///3669/// struct C;3670///3671/// impl FromWorld for C {3672/// fn from_world(_world: &mut World) -> Self {3673/// Self3674/// }3675/// }3676///3677/// #[derive(FromWorld)]3678/// struct D(A, B, C);3679///3680/// #[derive(FromWorld)]3681/// enum E {3682/// #[from_world]3683/// F,3684/// G3685/// }3686/// ```3687pub trait FromWorld {3688/// Creates `Self` using data from the given [`World`].3689fn from_world(world: &mut World) -> Self;3690}36913692impl<T: Default> FromWorld for T {3693/// Creates `Self` using [`default()`](`Default::default`).3694fn from_world(_world: &mut World) -> Self {3695T::default()3696}3697}36983699#[cfg(test)]3700#[expect(clippy::print_stdout, reason = "Allowed in tests.")]3701mod tests {3702use super::{FromWorld, World};3703use crate::{3704change_detection::{DetectChangesMut, MaybeLocation},3705component::{ComponentCloneBehavior, ComponentDescriptor, ComponentInfo, StorageType},3706entity::EntityHashSet,3707entity_disabling::{DefaultQueryFilters, Disabled},3708ptr::OwningPtr,3709resource::Resource,3710world::{error::EntityMutableFetchError, DeferredWorld},3711};3712use alloc::{3713borrow::ToOwned,3714string::{String, ToString},3715sync::Arc,3716vec,3717vec::Vec,3718};3719use bevy_ecs_macros::Component;3720use bevy_platform::collections::{HashMap, HashSet};3721use bevy_utils::prelude::DebugName;3722use core::{3723any::TypeId,3724panic,3725sync::atomic::{AtomicBool, AtomicU32, Ordering},3726};3727use std::{println, sync::Mutex};37283729type ID = u8;37303731#[derive(Clone, Copy, Debug, PartialEq, Eq)]3732enum DropLogItem {3733Create(ID),3734Drop(ID),3735}37363737#[derive(Resource, Component)]3738struct MayPanicInDrop {3739drop_log: Arc<Mutex<Vec<DropLogItem>>>,3740expected_panic_flag: Arc<AtomicBool>,3741should_panic: bool,3742id: u8,3743}37443745impl MayPanicInDrop {3746fn new(3747drop_log: &Arc<Mutex<Vec<DropLogItem>>>,3748expected_panic_flag: &Arc<AtomicBool>,3749should_panic: bool,3750id: u8,3751) -> Self {3752println!("creating component with id {id}");3753drop_log.lock().unwrap().push(DropLogItem::Create(id));37543755Self {3756drop_log: Arc::clone(drop_log),3757expected_panic_flag: Arc::clone(expected_panic_flag),3758should_panic,3759id,3760}3761}3762}37633764impl Drop for MayPanicInDrop {3765fn drop(&mut self) {3766println!("dropping component with id {}", self.id);37673768{3769let mut drop_log = self.drop_log.lock().unwrap();3770drop_log.push(DropLogItem::Drop(self.id));3771// Don't keep the mutex while panicking, or we'll poison it.3772drop(drop_log);3773}37743775if self.should_panic {3776self.expected_panic_flag.store(true, Ordering::SeqCst);3777panic!("testing what happens on panic inside drop");3778}3779}3780}37813782struct DropTestHelper {3783drop_log: Arc<Mutex<Vec<DropLogItem>>>,3784/// Set to `true` right before we intentionally panic, so that if we get3785/// a panic, we know if it was intended or not.3786expected_panic_flag: Arc<AtomicBool>,3787}37883789impl DropTestHelper {3790pub fn new() -> Self {3791Self {3792drop_log: Arc::new(Mutex::new(Vec::<DropLogItem>::new())),3793expected_panic_flag: Arc::new(AtomicBool::new(false)),3794}3795}37963797pub fn make_component(&self, should_panic: bool, id: ID) -> MayPanicInDrop {3798MayPanicInDrop::new(&self.drop_log, &self.expected_panic_flag, should_panic, id)3799}38003801pub fn finish(self, panic_res: std::thread::Result<()>) -> Vec<DropLogItem> {3802let drop_log = self.drop_log.lock().unwrap();3803let expected_panic_flag = self.expected_panic_flag.load(Ordering::SeqCst);38043805if !expected_panic_flag {3806match panic_res {3807Ok(()) => panic!("Expected a panic but it didn't happen"),3808Err(e) => std::panic::resume_unwind(e),3809}3810}38113812drop_log.to_owned()3813}3814}38153816#[test]3817fn panic_while_overwriting_component() {3818let helper = DropTestHelper::new();38193820let res = std::panic::catch_unwind(|| {3821let mut world = World::new();3822world3823.spawn_empty()3824.insert(helper.make_component(true, 0))3825.insert(helper.make_component(false, 1));38263827println!("Done inserting! Dropping world...");3828});38293830let drop_log = helper.finish(res);38313832assert_eq!(3833&*drop_log,3834[3835DropLogItem::Create(0),3836DropLogItem::Create(1),3837DropLogItem::Drop(0),3838DropLogItem::Drop(1),3839]3840);3841}38423843#[derive(Resource)]3844struct TestResource(u32);38453846#[derive(Resource)]3847struct TestResource2(String);38483849#[derive(Resource)]3850struct TestResource3;38513852#[test]3853fn get_resource_by_id() {3854let mut world = World::new();3855world.insert_resource(TestResource(42));3856let component_id = world3857.components()3858.get_valid_resource_id(TypeId::of::<TestResource>())3859.unwrap();38603861let resource = world.get_resource_by_id(component_id).unwrap();3862// SAFETY: `TestResource` is the correct resource type3863let resource = unsafe { resource.deref::<TestResource>() };38643865assert_eq!(resource.0, 42);3866}38673868#[test]3869fn get_resource_mut_by_id() {3870let mut world = World::new();3871world.insert_resource(TestResource(42));3872let component_id = world3873.components()3874.get_valid_resource_id(TypeId::of::<TestResource>())3875.unwrap();38763877{3878let mut resource = world.get_resource_mut_by_id(component_id).unwrap();3879resource.set_changed();3880// SAFETY: `TestResource` is the correct resource type3881let resource = unsafe { resource.into_inner().deref_mut::<TestResource>() };3882resource.0 = 43;3883}38843885let resource = world.get_resource_by_id(component_id).unwrap();3886// SAFETY: `TestResource` is the correct resource type3887let resource = unsafe { resource.deref::<TestResource>() };38883889assert_eq!(resource.0, 43);3890}38913892#[test]3893fn iter_resources() {3894let mut world = World::new();3895// Remove DefaultQueryFilters so it doesn't show up in the iterator3896world.remove_resource::<DefaultQueryFilters>();3897world.insert_resource(TestResource(42));3898world.insert_resource(TestResource2("Hello, world!".to_string()));3899world.insert_resource(TestResource3);3900world.remove_resource::<TestResource3>();39013902let mut iter = world.iter_resources();39033904let (info, ptr) = iter.next().unwrap();3905assert_eq!(info.name(), DebugName::type_name::<TestResource>());3906// SAFETY: We know that the resource is of type `TestResource`3907assert_eq!(unsafe { ptr.deref::<TestResource>().0 }, 42);39083909let (info, ptr) = iter.next().unwrap();3910assert_eq!(info.name(), DebugName::type_name::<TestResource2>());3911assert_eq!(3912// SAFETY: We know that the resource is of type `TestResource2`3913unsafe { &ptr.deref::<TestResource2>().0 },3914&"Hello, world!".to_string()3915);39163917assert!(iter.next().is_none());3918}39193920#[test]3921fn iter_resources_mut() {3922let mut world = World::new();3923// Remove DefaultQueryFilters so it doesn't show up in the iterator3924world.remove_resource::<DefaultQueryFilters>();3925world.insert_resource(TestResource(42));3926world.insert_resource(TestResource2("Hello, world!".to_string()));3927world.insert_resource(TestResource3);3928world.remove_resource::<TestResource3>();39293930let mut iter = world.iter_resources_mut();39313932let (info, mut mut_untyped) = iter.next().unwrap();3933assert_eq!(info.name(), DebugName::type_name::<TestResource>());3934// SAFETY: We know that the resource is of type `TestResource`3935unsafe {3936mut_untyped.as_mut().deref_mut::<TestResource>().0 = 43;3937};39383939let (info, mut mut_untyped) = iter.next().unwrap();3940assert_eq!(info.name(), DebugName::type_name::<TestResource2>());3941// SAFETY: We know that the resource is of type `TestResource2`3942unsafe {3943mut_untyped.as_mut().deref_mut::<TestResource2>().0 = "Hello, world?".to_string();3944};39453946assert!(iter.next().is_none());3947drop(iter);39483949assert_eq!(world.resource::<TestResource>().0, 43);3950assert_eq!(3951world.resource::<TestResource2>().0,3952"Hello, world?".to_string()3953);3954}39553956#[test]3957fn dynamic_resource() {3958let mut world = World::new();39593960let descriptor = ComponentDescriptor::new_resource::<TestResource>();39613962let component_id = world.register_resource_with_descriptor(descriptor);39633964let value = 0;3965OwningPtr::make(value, |ptr| {3966// SAFETY: value is valid for the layout of `TestResource`3967unsafe {3968world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());3969}3970});39713972// SAFETY: We know that the resource is of type `TestResource`3973let resource = unsafe {3974world3975.get_resource_by_id(component_id)3976.unwrap()3977.deref::<TestResource>()3978};3979assert_eq!(resource.0, 0);39803981assert!(world.remove_resource_by_id(component_id).is_some());3982}39833984#[test]3985fn custom_resource_with_layout() {3986static DROP_COUNT: AtomicU32 = AtomicU32::new(0);39873988let mut world = World::new();39893990// SAFETY: the drop function is valid for the layout and the data will be safe to access from any thread3991let descriptor = unsafe {3992ComponentDescriptor::new_with_layout(3993"Custom Test Component".to_string(),3994StorageType::Table,3995core::alloc::Layout::new::<[u8; 8]>(),3996Some(|ptr| {3997let data = ptr.read::<[u8; 8]>();3998assert_eq!(data, [0, 1, 2, 3, 4, 5, 6, 7]);3999DROP_COUNT.fetch_add(1, Ordering::SeqCst);4000}),4001true,4002ComponentCloneBehavior::Default,4003)4004};40054006let component_id = world.register_resource_with_descriptor(descriptor);40074008let value: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];4009OwningPtr::make(value, |ptr| {4010// SAFETY: value is valid for the component layout4011unsafe {4012world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());4013}4014});40154016// SAFETY: [u8; 8] is the correct type for the resource4017let data = unsafe {4018world4019.get_resource_by_id(component_id)4020.unwrap()4021.deref::<[u8; 8]>()4022};4023assert_eq!(*data, [0, 1, 2, 3, 4, 5, 6, 7]);40244025assert!(world.remove_resource_by_id(component_id).is_some());40264027assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);4028}40294030#[derive(Resource)]4031struct TestFromWorld(u32);4032impl FromWorld for TestFromWorld {4033fn from_world(world: &mut World) -> Self {4034let b = world.resource::<TestResource>();4035Self(b.0)4036}4037}40384039#[test]4040fn init_resource_does_not_overwrite() {4041let mut world = World::new();4042world.insert_resource(TestResource(0));4043world.init_resource::<TestFromWorld>();4044world.insert_resource(TestResource(1));4045world.init_resource::<TestFromWorld>();40464047let resource = world.resource::<TestFromWorld>();40484049assert_eq!(resource.0, 0);4050}40514052#[test]4053fn init_non_send_resource_does_not_overwrite() {4054let mut world = World::new();4055world.insert_resource(TestResource(0));4056world.init_non_send_resource::<TestFromWorld>();4057world.insert_resource(TestResource(1));4058world.init_non_send_resource::<TestFromWorld>();40594060let resource = world.non_send_resource::<TestFromWorld>();40614062assert_eq!(resource.0, 0);4063}40644065#[derive(Component)]4066struct Foo;40674068#[derive(Component)]4069struct Bar;40704071#[derive(Component)]4072struct Baz;40734074#[test]4075fn inspect_entity_components() {4076let mut world = World::new();4077let ent0 = world.spawn((Foo, Bar, Baz)).id();4078let ent1 = world.spawn((Foo, Bar)).id();4079let ent2 = world.spawn((Bar, Baz)).id();4080let ent3 = world.spawn((Foo, Baz)).id();4081let ent4 = world.spawn(Foo).id();4082let ent5 = world.spawn(Bar).id();4083let ent6 = world.spawn(Baz).id();40844085fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {4086component_infos4087.into_iter()4088.map(ComponentInfo::type_id)4089.collect()4090}40914092let foo_id = TypeId::of::<Foo>();4093let bar_id = TypeId::of::<Bar>();4094let baz_id = TypeId::of::<Baz>();4095assert_eq!(4096to_type_ids(world.inspect_entity(ent0).unwrap().collect()),4097[Some(foo_id), Some(bar_id), Some(baz_id)]4098.into_iter()4099.collect::<HashSet<_>>()4100);4101assert_eq!(4102to_type_ids(world.inspect_entity(ent1).unwrap().collect()),4103[Some(foo_id), Some(bar_id)]4104.into_iter()4105.collect::<HashSet<_>>()4106);4107assert_eq!(4108to_type_ids(world.inspect_entity(ent2).unwrap().collect()),4109[Some(bar_id), Some(baz_id)]4110.into_iter()4111.collect::<HashSet<_>>()4112);4113assert_eq!(4114to_type_ids(world.inspect_entity(ent3).unwrap().collect()),4115[Some(foo_id), Some(baz_id)]4116.into_iter()4117.collect::<HashSet<_>>()4118);4119assert_eq!(4120to_type_ids(world.inspect_entity(ent4).unwrap().collect()),4121[Some(foo_id)].into_iter().collect::<HashSet<_>>()4122);4123assert_eq!(4124to_type_ids(world.inspect_entity(ent5).unwrap().collect()),4125[Some(bar_id)].into_iter().collect::<HashSet<_>>()4126);4127assert_eq!(4128to_type_ids(world.inspect_entity(ent6).unwrap().collect()),4129[Some(baz_id)].into_iter().collect::<HashSet<_>>()4130);4131}41324133#[test]4134fn iterate_entities() {4135let mut world = World::new();4136let mut entity_counters = <HashMap<_, _>>::default();41374138let iterate_and_count_entities = |world: &World, entity_counters: &mut HashMap<_, _>| {4139entity_counters.clear();4140#[expect(deprecated, reason = "remove this test in in 0.17.0")]4141for entity in world.iter_entities() {4142let counter = entity_counters.entry(entity.id()).or_insert(0);4143*counter += 1;4144}4145};41464147// Adding one entity and validating iteration4148let ent0 = world.spawn((Foo, Bar, Baz)).id();41494150iterate_and_count_entities(&world, &mut entity_counters);4151assert_eq!(entity_counters[&ent0], 1);4152assert_eq!(entity_counters.len(), 1);41534154// Spawning three more entities and then validating iteration4155let ent1 = world.spawn((Foo, Bar)).id();4156let ent2 = world.spawn((Bar, Baz)).id();4157let ent3 = world.spawn((Foo, Baz)).id();41584159iterate_and_count_entities(&world, &mut entity_counters);41604161assert_eq!(entity_counters[&ent0], 1);4162assert_eq!(entity_counters[&ent1], 1);4163assert_eq!(entity_counters[&ent2], 1);4164assert_eq!(entity_counters[&ent3], 1);4165assert_eq!(entity_counters.len(), 4);41664167// Despawning first entity and then validating the iteration4168assert!(world.despawn(ent0));41694170iterate_and_count_entities(&world, &mut entity_counters);41714172assert_eq!(entity_counters[&ent1], 1);4173assert_eq!(entity_counters[&ent2], 1);4174assert_eq!(entity_counters[&ent3], 1);4175assert_eq!(entity_counters.len(), 3);41764177// Spawning three more entities, despawning three and then validating the iteration4178let ent4 = world.spawn(Foo).id();4179let ent5 = world.spawn(Bar).id();4180let ent6 = world.spawn(Baz).id();41814182assert!(world.despawn(ent2));4183assert!(world.despawn(ent3));4184assert!(world.despawn(ent4));41854186iterate_and_count_entities(&world, &mut entity_counters);41874188assert_eq!(entity_counters[&ent1], 1);4189assert_eq!(entity_counters[&ent5], 1);4190assert_eq!(entity_counters[&ent6], 1);4191assert_eq!(entity_counters.len(), 3);41924193// Despawning remaining entities and then validating the iteration4194assert!(world.despawn(ent1));4195assert!(world.despawn(ent5));4196assert!(world.despawn(ent6));41974198iterate_and_count_entities(&world, &mut entity_counters);41994200assert_eq!(entity_counters.len(), 0);4201}42024203#[test]4204fn iterate_entities_mut() {4205#[derive(Component, PartialEq, Debug)]4206struct A(i32);42074208#[derive(Component, PartialEq, Debug)]4209struct B(i32);42104211let mut world = World::new();42124213let a1 = world.spawn(A(1)).id();4214let a2 = world.spawn(A(2)).id();4215let b1 = world.spawn(B(1)).id();4216let b2 = world.spawn(B(2)).id();42174218#[expect(deprecated, reason = "remove this test in 0.17.0")]4219for mut entity in world.iter_entities_mut() {4220if let Some(mut a) = entity.get_mut::<A>() {4221a.0 -= 1;4222}4223}4224assert_eq!(world.entity(a1).get(), Some(&A(0)));4225assert_eq!(world.entity(a2).get(), Some(&A(1)));4226assert_eq!(world.entity(b1).get(), Some(&B(1)));4227assert_eq!(world.entity(b2).get(), Some(&B(2)));42284229#[expect(deprecated, reason = "remove this test in in 0.17.0")]4230for mut entity in world.iter_entities_mut() {4231if let Some(mut b) = entity.get_mut::<B>() {4232b.0 *= 2;4233}4234}4235assert_eq!(world.entity(a1).get(), Some(&A(0)));4236assert_eq!(world.entity(a2).get(), Some(&A(1)));4237assert_eq!(world.entity(b1).get(), Some(&B(2)));4238assert_eq!(world.entity(b2).get(), Some(&B(4)));42394240#[expect(deprecated, reason = "remove this test in in 0.17.0")]4241let mut entities = world.iter_entities_mut().collect::<Vec<_>>();4242entities.sort_by_key(|e| e.get::<A>().map(|a| a.0).or(e.get::<B>().map(|b| b.0)));4243let (a, b) = entities.split_at_mut(2);4244core::mem::swap(4245&mut a[1].get_mut::<A>().unwrap().0,4246&mut b[0].get_mut::<B>().unwrap().0,4247);4248assert_eq!(world.entity(a1).get(), Some(&A(0)));4249assert_eq!(world.entity(a2).get(), Some(&A(2)));4250assert_eq!(world.entity(b1).get(), Some(&B(1)));4251assert_eq!(world.entity(b2).get(), Some(&B(4)));4252}42534254#[test]4255fn spawn_empty_bundle() {4256let mut world = World::new();4257world.spawn(());4258}42594260#[test]4261fn get_entity() {4262let mut world = World::new();42634264let e1 = world.spawn_empty().id();4265let e2 = world.spawn_empty().id();42664267assert!(world.get_entity(e1).is_ok());4268assert!(world.get_entity([e1, e2]).is_ok());4269assert!(world4270.get_entity(&[e1, e2] /* this is an array not a slice */)4271.is_ok());4272assert!(world.get_entity(&vec![e1, e2][..]).is_ok());4273assert!(world4274.get_entity(&EntityHashSet::from_iter([e1, e2]))4275.is_ok());42764277world.entity_mut(e1).despawn();42784279assert_eq!(4280Err(e1),4281world.get_entity(e1).map(|_| {}).map_err(|e| e.entity)4282);4283assert_eq!(4284Err(e1),4285world.get_entity([e1, e2]).map(|_| {}).map_err(|e| e.entity)4286);4287assert_eq!(4288Err(e1),4289world4290.get_entity(&[e1, e2] /* this is an array not a slice */)4291.map(|_| {})4292.map_err(|e| e.entity)4293);4294assert_eq!(4295Err(e1),4296world4297.get_entity(&vec![e1, e2][..])4298.map(|_| {})4299.map_err(|e| e.entity)4300);4301assert_eq!(4302Err(e1),4303world4304.get_entity(&EntityHashSet::from_iter([e1, e2]))4305.map(|_| {})4306.map_err(|e| e.entity)4307);4308}43094310#[test]4311fn get_entity_mut() {4312let mut world = World::new();43134314let e1 = world.spawn_empty().id();4315let e2 = world.spawn_empty().id();43164317assert!(world.get_entity_mut(e1).is_ok());4318assert!(world.get_entity_mut([e1, e2]).is_ok());4319assert!(world4320.get_entity_mut(&[e1, e2] /* this is an array not a slice */)4321.is_ok());4322assert!(world.get_entity_mut(&vec![e1, e2][..]).is_ok());4323assert!(world4324.get_entity_mut(&EntityHashSet::from_iter([e1, e2]))4325.is_ok());43264327assert_eq!(4328Err(EntityMutableFetchError::AliasedMutability(e1)),4329world.get_entity_mut([e1, e2, e1]).map(|_| {})4330);4331assert_eq!(4332Err(EntityMutableFetchError::AliasedMutability(e1)),4333world4334.get_entity_mut(&[e1, e2, e1] /* this is an array not a slice */)4335.map(|_| {})4336);4337assert_eq!(4338Err(EntityMutableFetchError::AliasedMutability(e1)),4339world.get_entity_mut(&vec![e1, e2, e1][..]).map(|_| {})4340);4341// Aliased mutability isn't allowed by HashSets4342assert!(world4343.get_entity_mut(&EntityHashSet::from_iter([e1, e2, e1]))4344.is_ok());43454346world.entity_mut(e1).despawn();43474348assert!(matches!(4349world.get_entity_mut(e1).map(|_| {}),4350Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e14351));4352assert!(matches!(4353world.get_entity_mut([e1, e2]).map(|_| {}),4354Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1));4355assert!(matches!(4356world4357.get_entity_mut(&[e1, e2] /* this is an array not a slice */)4358.map(|_| {}),4359Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1));4360assert!(matches!(4361world.get_entity_mut(&vec![e1, e2][..]).map(|_| {}),4362Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1,4363));4364assert!(matches!(4365world4366.get_entity_mut(&EntityHashSet::from_iter([e1, e2]))4367.map(|_| {}),4368Err(EntityMutableFetchError::EntityDoesNotExist(e)) if e.entity == e1));4369}43704371#[test]4372#[track_caller]4373fn entity_spawn_despawn_tracking() {4374use core::panic::Location;43754376let mut world = World::new();4377let entity = world.spawn_empty().id();4378assert_eq!(4379world.entities.entity_get_spawned_or_despawned_by(entity),4380MaybeLocation::new(Some(Location::caller()))4381);4382assert_eq!(4383world.entities.entity_get_spawn_or_despawn_tick(entity),4384Some(world.change_tick())4385);4386world.despawn(entity);4387assert_eq!(4388world.entities.entity_get_spawned_or_despawned_by(entity),4389MaybeLocation::new(Some(Location::caller()))4390);4391assert_eq!(4392world.entities.entity_get_spawn_or_despawn_tick(entity),4393Some(world.change_tick())4394);4395let new = world.spawn_empty().id();4396assert_eq!(entity.index(), new.index());4397assert_eq!(4398world.entities.entity_get_spawned_or_despawned_by(entity),4399MaybeLocation::new(None)4400);4401assert_eq!(4402world.entities.entity_get_spawn_or_despawn_tick(entity),4403None4404);4405world.despawn(new);4406assert_eq!(4407world.entities.entity_get_spawned_or_despawned_by(entity),4408MaybeLocation::new(None)4409);4410assert_eq!(4411world.entities.entity_get_spawn_or_despawn_tick(entity),4412None4413);4414}44154416#[test]4417fn new_world_has_disabling() {4418let mut world = World::new();4419world.spawn(Foo);4420world.spawn((Foo, Disabled));4421assert_eq!(1, world.query::<&Foo>().iter(&world).count());44224423// If we explicitly remove the resource, no entities should be filtered anymore4424world.remove_resource::<DefaultQueryFilters>();4425assert_eq!(2, world.query::<&Foo>().iter(&world).count());4426}44274428#[test]4429fn entities_and_commands() {4430#[derive(Component, PartialEq, Debug)]4431struct Foo(u32);44324433let mut world = World::new();44344435let eid = world.spawn(Foo(35)).id();44364437let (mut fetcher, mut commands) = world.entities_and_commands();4438let emut = fetcher.get_mut(eid).unwrap();4439commands.entity(eid).despawn();4440assert_eq!(emut.get::<Foo>().unwrap(), &Foo(35));44414442world.flush();44434444assert!(world.get_entity(eid).is_err());4445}44464447#[test]4448fn entities_and_commands_deferred() {4449#[derive(Component, PartialEq, Debug)]4450struct Foo(u32);44514452let mut world = World::new();44534454let eid = world.spawn(Foo(1)).id();44554456let mut dworld = DeferredWorld::from(&mut world);44574458let (mut fetcher, mut commands) = dworld.entities_and_commands();4459let emut = fetcher.get_mut(eid).unwrap();4460commands.entity(eid).despawn();4461assert_eq!(emut.get::<Foo>().unwrap(), &Foo(1));44624463world.flush();44644465assert!(world.get_entity(eid).is_err());4466}4467}446844694470