#![expect(1unsafe_op_in_unsafe_fn,2reason = "See #11590. To be removed once all applicable unsafe code has an unsafe block with a safety comment."3)]45//! Defines the [`World`] and APIs for accessing it directly.67pub(crate) mod command_queue;8mod deferred_world;9mod entity_access;10mod entity_fetch;11mod filtered_resource;12mod identifier;13mod spawn_batch;1415pub mod error;16#[cfg(feature = "bevy_reflect")]17pub mod reflect;18pub mod unsafe_world_cell;1920pub use crate::{21change_detection::{Mut, Ref, CHECK_TICK_THRESHOLD},22world::command_queue::CommandQueue,23};24pub use bevy_ecs_macros::FromWorld;25pub use deferred_world::DeferredWorld;26pub use entity_access::{27ComponentEntry, DynamicComponentFetch, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,28EntityWorldMut, FilteredEntityMut, FilteredEntityRef, OccupiedComponentEntry,29TryFromFilteredError, UnsafeFilteredEntityMut, VacantComponentEntry,30};31pub use entity_fetch::{EntityFetcher, WorldEntityFetch};32pub use filtered_resource::*;33pub use identifier::WorldId;34pub use spawn_batch::*;3536use crate::{37archetype::{ArchetypeId, Archetypes},38bundle::{39Bundle, BundleId, BundleInfo, BundleInserter, BundleSpawner, Bundles, DynamicBundle,40InsertMode, NoBundleEffect,41},42change_detection::{43CheckChangeTicks, ComponentTicks, ComponentTicksMut, MaybeLocation, MutUntyped, Tick,44},45component::{46Component, ComponentDescriptor, ComponentId, ComponentIds, ComponentInfo, Components,47ComponentsQueuedRegistrator, ComponentsRegistrator, Mutable, RequiredComponents,48RequiredComponentsError,49},50entity::{Entities, Entity, EntityAllocator, EntityNotSpawnedError, SpawnError},51entity_disabling::DefaultQueryFilters,52error::{DefaultErrorHandler, ErrorHandler},53lifecycle::{ComponentHooks, RemovedComponentMessages, ADD, DESPAWN, INSERT, REMOVE, REPLACE},54message::{Message, MessageId, Messages, WriteBatchIds},55observer::Observers,56prelude::{Add, Despawn, DetectChangesMut, Insert, Remove, Replace},57query::{DebugCheckedUnwrap, QueryData, QueryFilter, QueryState},58relationship::RelationshipHookMode,59resource::{IsResource, Resource, ResourceEntities, IS_RESOURCE},60schedule::{Schedule, ScheduleLabel, Schedules},61storage::{NonSendData, Storages},62system::Commands,63world::{64command_queue::RawCommandQueue,65error::{66EntityDespawnError, EntityMutableFetchError, TryInsertBatchError, TryRunScheduleError,67},68},69};70use alloc::{boxed::Box, vec::Vec};71use bevy_platform::sync::atomic::{AtomicU32, Ordering};72use bevy_ptr::{move_as_ptr, MovingPtr, OwningPtr, Ptr};73use bevy_utils::prelude::DebugName;74use core::{any::TypeId, fmt, mem::ManuallyDrop};75use log::warn;76use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell};7778/// Stores and exposes operations on [entities](Entity), [components](Component), resources,79/// and their associated metadata.80///81/// Each [`Entity`] has a set of unique components, based on their type.82/// Entity components can be created, updated, removed, and queried using a given [`World`].83///84/// For complex access patterns involving [`SystemParam`](crate::system::SystemParam),85/// consider using [`SystemState`](crate::system::SystemState).86///87/// To mutate different parts of the world simultaneously,88/// use [`World::resource_scope`] or [`SystemState`](crate::system::SystemState).89///90/// ## Resources91///92/// Worlds can also store [`Resource`]s,93/// which are unique instances of a given type that belong to a specific unique Entity.94/// There are also *non send resources*, which can only be accessed on the main thread.95/// These are stored outside of the ECS.96/// See [`Resource`] for usage.97pub struct World {98id: WorldId,99pub(crate) entities: Entities,100pub(crate) entity_allocator: EntityAllocator,101pub(crate) components: Components,102pub(crate) component_ids: ComponentIds,103pub(crate) resource_entities: ResourceEntities,104pub(crate) archetypes: Archetypes,105pub(crate) storages: Storages,106pub(crate) bundles: Bundles,107pub(crate) observers: Observers,108pub(crate) removed_components: RemovedComponentMessages,109pub(crate) change_tick: AtomicU32,110pub(crate) last_change_tick: Tick,111pub(crate) last_check_tick: Tick,112pub(crate) last_trigger_id: u32,113pub(crate) command_queue: RawCommandQueue,114}115116impl Default for World {117fn default() -> Self {118let mut world = Self {119id: WorldId::new().expect("More `bevy` `World`s have been created than is supported"),120entities: Entities::new(),121entity_allocator: EntityAllocator::default(),122components: Default::default(),123resource_entities: Default::default(),124archetypes: Archetypes::new(),125storages: Default::default(),126bundles: Default::default(),127observers: Observers::default(),128removed_components: Default::default(),129// Default value is `1`, and `last_change_tick`s default to `0`, such that changes130// are detected on first system runs and for direct world queries.131change_tick: AtomicU32::new(1),132last_change_tick: Tick::new(0),133last_check_tick: Tick::new(0),134last_trigger_id: 0,135command_queue: RawCommandQueue::new(),136component_ids: ComponentIds::default(),137};138world.bootstrap();139world140}141}142143impl Drop for World {144fn drop(&mut self) {145// SAFETY: Not passing a pointer so the argument is always valid146unsafe { self.command_queue.apply_or_drop_queued(None) };147// SAFETY: Pointers in internal command queue are only invalidated here148drop(unsafe { Box::from_raw(self.command_queue.bytes.as_ptr()) });149// SAFETY: Pointers in internal command queue are only invalidated here150drop(unsafe { Box::from_raw(self.command_queue.cursor.as_ptr()) });151// SAFETY: Pointers in internal command queue are only invalidated here152drop(unsafe { Box::from_raw(self.command_queue.panic_recovery.as_ptr()) });153}154}155156impl World {157/// This performs initialization that _must_ happen for every [`World`] immediately upon creation (such as claiming specific component ids).158/// This _must_ be run as part of constructing a [`World`], before it is returned to the caller.159#[inline]160fn bootstrap(&mut self) {161// The order that we register these events is vital to ensure that the constants are correct!162let on_add = self.register_event_key::<Add>();163assert_eq!(ADD, on_add);164165let on_insert = self.register_event_key::<Insert>();166assert_eq!(INSERT, on_insert);167168let on_replace = self.register_event_key::<Replace>();169assert_eq!(REPLACE, on_replace);170171let on_remove = self.register_event_key::<Remove>();172assert_eq!(REMOVE, on_remove);173174let on_despawn = self.register_event_key::<Despawn>();175assert_eq!(DESPAWN, on_despawn);176177let is_resource = self.register_component::<IsResource>();178assert_eq!(IS_RESOURCE, is_resource);179180// This sets up `Disabled` as a disabling component, via the FromWorld impl181self.init_resource::<DefaultQueryFilters>();182}183/// Creates a new empty [`World`].184///185/// # Panics186///187/// If [`usize::MAX`] [`World`]s have been created.188/// This guarantee allows System Parameters to safely uniquely identify a [`World`],189/// since its [`WorldId`] is unique190#[inline]191pub fn new() -> World {192World::default()193}194195/// Retrieves this [`World`]'s unique ID196#[inline]197pub fn id(&self) -> WorldId {198self.id199}200201/// Creates a new [`UnsafeWorldCell`] view with complete read+write access.202#[inline]203pub fn as_unsafe_world_cell(&mut self) -> UnsafeWorldCell<'_> {204UnsafeWorldCell::new_mutable(self)205}206207/// Creates a new [`UnsafeWorldCell`] view with only read access to everything.208#[inline]209pub fn as_unsafe_world_cell_readonly(&self) -> UnsafeWorldCell<'_> {210UnsafeWorldCell::new_readonly(self)211}212213/// Retrieves this world's [`Entities`] collection.214#[inline]215pub fn entities(&self) -> &Entities {216&self.entities217}218219/// Retrieves this world's [`EntityAllocator`] collection.220#[inline]221pub fn entity_allocator(&self) -> &EntityAllocator {222&self.entity_allocator223}224225/// Retrieves this world's [`EntityAllocator`] collection mutably.226#[inline]227pub fn entity_allocator_mut(&mut self) -> &mut EntityAllocator {228&mut self.entity_allocator229}230231/// Retrieves this world's [`Entities`] collection mutably.232///233/// # Safety234/// Mutable reference must not be used to put the [`Entities`] data235/// in an invalid state for this [`World`]236#[inline]237pub unsafe fn entities_mut(&mut self) -> &mut Entities {238&mut self.entities239}240241/// Retrieves the number of [`Entities`] in the world.242///243/// This is helpful as a diagnostic, but it can also be used effectively in tests.244#[inline]245pub fn entity_count(&self) -> u32 {246self.entities.count_spawned()247}248249/// Retrieves this world's [`Archetypes`] collection.250#[inline]251pub fn archetypes(&self) -> &Archetypes {252&self.archetypes253}254255/// Retrieves this world's [`Components`] collection.256#[inline]257pub fn components(&self) -> &Components {258&self.components259}260261/// Retrieves this world's [`ResourceEntities`].262#[inline]263pub fn resource_entities(&self) -> &ResourceEntities {264&self.resource_entities265}266267/// Prepares a [`ComponentsQueuedRegistrator`] for the world.268/// **NOTE:** [`ComponentsQueuedRegistrator`] is easily misused.269/// See its docs for important notes on when and how it should be used.270#[inline]271pub fn components_queue(&self) -> ComponentsQueuedRegistrator<'_> {272// SAFETY: These are from the same world.273unsafe { ComponentsQueuedRegistrator::new(&self.components, &self.component_ids) }274}275276/// Prepares a [`ComponentsRegistrator`] for the world.277#[inline]278pub fn components_registrator(&mut self) -> ComponentsRegistrator<'_> {279// SAFETY: These are from the same world.280unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) }281}282283/// Retrieves this world's [`Storages`] collection.284#[inline]285pub fn storages(&self) -> &Storages {286&self.storages287}288289/// Retrieves this world's [`Bundles`] collection.290#[inline]291pub fn bundles(&self) -> &Bundles {292&self.bundles293}294295/// Retrieves this world's [`RemovedComponentMessages`] collection296#[inline]297pub fn removed_components(&self) -> &RemovedComponentMessages {298&self.removed_components299}300301/// Retrieves this world's [`Observers`] list302#[inline]303pub fn observers(&self) -> &Observers {304&self.observers305}306307/// Creates a new [`Commands`] instance that writes to the world's command queue308/// Use [`World::flush`] to apply all queued commands309#[inline]310pub fn commands(&mut self) -> Commands<'_, '_> {311// SAFETY: command_queue is stored on world and always valid while the world exists312unsafe {313Commands::new_raw_from_entities(314self.command_queue.clone(),315&self.entity_allocator,316&self.entities,317)318}319}320321/// Registers a new [`Component`] type and returns the [`ComponentId`] created for it.322///323/// # Usage Notes324/// In most cases, you don't need to call this method directly since component registration325/// happens automatically during system initialization.326pub fn register_component<T: Component>(&mut self) -> ComponentId {327self.components_registrator().register_component::<T>()328}329330/// Registers a component type as "disabling",331/// using [default query filters](DefaultQueryFilters) to exclude entities with the component from queries.332pub fn register_disabling_component<C: Component>(&mut self) {333let component_id = self.register_component::<C>();334let mut dqf = self.resource_mut::<DefaultQueryFilters>();335dqf.register_disabling_component(component_id);336}337338/// Returns a mutable reference to the [`ComponentHooks`] for a [`Component`] type.339///340/// Will panic if `T` exists in any archetypes.341#[must_use]342pub fn register_component_hooks<T: Component>(&mut self) -> &mut ComponentHooks {343let index = self.register_component::<T>();344assert!(!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>());345// SAFETY: We just created this component346unsafe { self.components.get_hooks_mut(index).debug_checked_unwrap() }347}348349/// Returns a mutable reference to the [`ComponentHooks`] for a [`Component`] with the given id if it exists.350///351/// Will panic if `id` exists in any archetypes.352pub fn register_component_hooks_by_id(353&mut self,354id: ComponentId,355) -> Option<&mut ComponentHooks> {356assert!(!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");357self.components.get_hooks_mut(id)358}359360/// Registers the given component `R` as a [required component] for `T`.361///362/// When `T` is added to an entity, `R` and its own required components will also be added363/// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.364/// If a custom constructor is desired, use [`World::register_required_components_with`] instead.365///366/// For the non-panicking version, see [`World::try_register_required_components`].367///368/// Note that requirements must currently be registered before `T` is inserted into the world369/// for the first time. This limitation may be fixed in the future.370///371/// [required component]: Component#required-components372///373/// # Panics374///375/// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added376/// on an entity before the registration.377///378/// Indirect requirements through other components are allowed. In those cases, any existing requirements379/// will only be overwritten if the new requirement is more specific.380///381/// # Example382///383/// ```384/// # use bevy_ecs::prelude::*;385/// #[derive(Component)]386/// struct A;387///388/// #[derive(Component, Default, PartialEq, Eq, Debug)]389/// struct B(usize);390///391/// #[derive(Component, Default, PartialEq, Eq, Debug)]392/// struct C(u32);393///394/// # let mut world = World::default();395/// // Register B as required by A and C as required by B.396/// world.register_required_components::<A, B>();397/// world.register_required_components::<B, C>();398///399/// // This will implicitly also insert B and C with their Default constructors.400/// let id = world.spawn(A).id();401/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());402/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());403/// ```404pub fn register_required_components<T: Component, R: Component + Default>(&mut self) {405self.try_register_required_components::<T, R>().unwrap();406}407408/// Registers the given component `R` as a [required component] for `T`.409///410/// When `T` is added to an entity, `R` and its own required components will also be added411/// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.412/// If a [`Default`] constructor is desired, use [`World::register_required_components`] instead.413///414/// For the non-panicking version, see [`World::try_register_required_components_with`].415///416/// Note that requirements must currently be registered before `T` is inserted into the world417/// for the first time. This limitation may be fixed in the future.418///419/// [required component]: Component#required-components420///421/// # Panics422///423/// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added424/// on an entity before the registration.425///426/// Indirect requirements through other components are allowed. In those cases, any existing requirements427/// will only be overwritten if the new requirement is more specific.428///429/// # Example430///431/// ```432/// # use bevy_ecs::prelude::*;433/// #[derive(Component)]434/// struct A;435///436/// #[derive(Component, Default, PartialEq, Eq, Debug)]437/// struct B(usize);438///439/// #[derive(Component, PartialEq, Eq, Debug)]440/// struct C(u32);441///442/// # let mut world = World::default();443/// // Register B and C as required by A and C as required by B.444/// // A requiring C directly will overwrite the indirect requirement through B.445/// world.register_required_components::<A, B>();446/// world.register_required_components_with::<B, C>(|| C(1));447/// world.register_required_components_with::<A, C>(|| C(2));448///449/// // This will implicitly also insert B with its Default constructor and C450/// // with the custom constructor defined by A.451/// let id = world.spawn(A).id();452/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());453/// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());454/// ```455pub fn register_required_components_with<T: Component, R: Component>(456&mut self,457constructor: fn() -> R,458) {459self.try_register_required_components_with::<T, R>(constructor)460.unwrap();461}462463/// Tries to register the given component `R` as a [required component] for `T`.464///465/// When `T` is added to an entity, `R` and its own required components will also be added466/// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.467/// If a custom constructor is desired, use [`World::register_required_components_with`] instead.468///469/// For the panicking version, see [`World::register_required_components`].470///471/// Note that requirements must currently be registered before `T` is inserted into the world472/// for the first time. This limitation may be fixed in the future.473///474/// [required component]: Component#required-components475///476/// # Errors477///478/// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added479/// on an entity before the registration.480///481/// Indirect requirements through other components are allowed. In those cases, any existing requirements482/// will only be overwritten if the new requirement is more specific.483///484/// # Example485///486/// ```487/// # use bevy_ecs::prelude::*;488/// #[derive(Component)]489/// struct A;490///491/// #[derive(Component, Default, PartialEq, Eq, Debug)]492/// struct B(usize);493///494/// #[derive(Component, Default, PartialEq, Eq, Debug)]495/// struct C(u32);496///497/// # let mut world = World::default();498/// // Register B as required by A and C as required by B.499/// world.register_required_components::<A, B>();500/// world.register_required_components::<B, C>();501///502/// // Duplicate registration! This will fail.503/// assert!(world.try_register_required_components::<A, B>().is_err());504///505/// // This will implicitly also insert B and C with their Default constructors.506/// let id = world.spawn(A).id();507/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());508/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());509/// ```510pub fn try_register_required_components<T: Component, R: Component + Default>(511&mut self,512) -> Result<(), RequiredComponentsError> {513self.try_register_required_components_with::<T, R>(R::default)514}515516/// Tries to register the given component `R` as a [required component] for `T`.517///518/// When `T` is added to an entity, `R` and its own required components will also be added519/// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.520/// If a [`Default`] constructor is desired, use [`World::register_required_components`] instead.521///522/// For the panicking version, see [`World::register_required_components_with`].523///524/// Note that requirements must currently be registered before `T` is inserted into the world525/// for the first time. This limitation may be fixed in the future.526///527/// [required component]: Component#required-components528///529/// # Errors530///531/// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added532/// on an entity before the registration.533///534/// Indirect requirements through other components are allowed. In those cases, any existing requirements535/// will only be overwritten if the new requirement is more specific.536///537/// # Example538///539/// ```540/// # use bevy_ecs::prelude::*;541/// #[derive(Component)]542/// struct A;543///544/// #[derive(Component, Default, PartialEq, Eq, Debug)]545/// struct B(usize);546///547/// #[derive(Component, PartialEq, Eq, Debug)]548/// struct C(u32);549///550/// # let mut world = World::default();551/// // Register B and C as required by A and C as required by B.552/// // A requiring C directly will overwrite the indirect requirement through B.553/// world.register_required_components::<A, B>();554/// world.register_required_components_with::<B, C>(|| C(1));555/// world.register_required_components_with::<A, C>(|| C(2));556///557/// // Duplicate registration! Even if the constructors were different, this would fail.558/// assert!(world.try_register_required_components_with::<B, C>(|| C(1)).is_err());559///560/// // This will implicitly also insert B with its Default constructor and C561/// // with the custom constructor defined by A.562/// let id = world.spawn(A).id();563/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());564/// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());565/// ```566pub fn try_register_required_components_with<T: Component, R: Component>(567&mut self,568constructor: fn() -> R,569) -> Result<(), RequiredComponentsError> {570let requiree = self.register_component::<T>();571572// TODO: Remove this panic and update archetype edges accordingly when required components are added573if self.archetypes().component_index().contains_key(&requiree) {574return Err(RequiredComponentsError::ArchetypeExists(requiree));575}576577let required = self.register_component::<R>();578579// SAFETY: We just created the `required` and `requiree` components.580unsafe {581self.components582.register_required_components::<R>(requiree, required, constructor)583}584}585586/// Retrieves the [required components](RequiredComponents) for the given component type, if it exists.587pub fn get_required_components<C: Component>(&self) -> Option<&RequiredComponents> {588let id = self.components().valid_component_id::<C>()?;589let component_info = self.components().get_info(id)?;590Some(component_info.required_components())591}592593/// Retrieves the [required components](RequiredComponents) for the component of the given [`ComponentId`], if it exists.594pub fn get_required_components_by_id(&self, id: ComponentId) -> Option<&RequiredComponents> {595let component_info = self.components().get_info(id)?;596Some(component_info.required_components())597}598599/// Registers a new [`Component`] type and returns the [`ComponentId`] created for it.600///601/// This method differs from [`World::register_component`] in that it uses a [`ComponentDescriptor`]602/// to register the new component type instead of statically available type information. This603/// enables the dynamic registration of new component definitions at runtime for advanced use cases.604///605/// While the option to register a component from a descriptor is useful in type-erased606/// contexts, the standard [`World::register_component`] function should always be used instead607/// when type information is available at compile time.608pub fn register_component_with_descriptor(609&mut self,610descriptor: ComponentDescriptor,611) -> ComponentId {612self.components_registrator()613.register_component_with_descriptor(descriptor)614}615616/// Returns the [`ComponentId`] of the given [`Component`] type `T`.617///618/// The returned `ComponentId` is specific to the `World` instance619/// it was retrieved from and should not be used with another `World` instance.620///621/// Returns [`None`] if the `Component` type has not yet been initialized within622/// the `World` using [`World::register_component`].623///624/// ```625/// use bevy_ecs::prelude::*;626///627/// let mut world = World::new();628///629/// #[derive(Component)]630/// struct ComponentA;631///632/// let component_a_id = world.register_component::<ComponentA>();633///634/// assert_eq!(component_a_id, world.component_id::<ComponentA>().unwrap())635/// ```636///637/// # See also638///639/// * [`ComponentIdFor`](crate::component::ComponentIdFor)640/// * [`Components::component_id()`]641/// * [`Components::get_id()`]642#[inline]643pub fn component_id<T: Component>(&self) -> Option<ComponentId> {644self.components.component_id::<T>()645}646647/// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.648///649/// The [`Resource`] doesn't have a value in the [`World`], it's only registered. If you want650/// to insert the [`Resource`] in the [`World`], use [`World::init_resource`] or651/// [`World::insert_resource`] instead.652pub fn register_resource<R: Resource>(&mut self) -> ComponentId {653self.components_registrator().register_component::<R>()654}655656/// Returns the [`ComponentId`] of the given [`Resource`] type `T`.657///658/// The returned [`ComponentId`] is specific to the [`World`] instance it was retrieved from659/// and should not be used with another [`World`] instance.660///661/// Returns [`None`] if the [`Resource`] type has not yet been initialized within the662/// [`World`] using [`World::register_resource`], [`World::init_resource`] or [`World::insert_resource`].663pub fn resource_id<T: Resource>(&self) -> Option<ComponentId> {664self.components.get_resource_id(TypeId::of::<T>())665}666667/// Returns [`EntityRef`]s that expose read-only operations for the given668/// `entities`. This will panic if any of the given entities do not exist. Use669/// [`World::get_entity`] if you want to check for entity existence instead670/// of implicitly panicking.671///672/// This function supports fetching a single entity or multiple entities:673/// - Pass an [`Entity`] to receive a single [`EntityRef`].674/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].675/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.676///677/// # Panics678///679/// If any of the given `entities` do not exist in the world.680///681/// # Examples682///683/// ## Single [`Entity`]684///685/// ```686/// # use bevy_ecs::prelude::*;687/// #[derive(Component)]688/// struct Position {689/// x: f32,690/// y: f32,691/// }692///693/// let mut world = World::new();694/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();695///696/// let position = world.entity(entity).get::<Position>().unwrap();697/// assert_eq!(position.x, 0.0);698/// ```699///700/// ## Array of [`Entity`]s701///702/// ```703/// # use bevy_ecs::prelude::*;704/// #[derive(Component)]705/// struct Position {706/// x: f32,707/// y: f32,708/// }709///710/// let mut world = World::new();711/// let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();712/// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();713///714/// let [e1_ref, e2_ref] = world.entity([e1, e2]);715/// let e1_position = e1_ref.get::<Position>().unwrap();716/// assert_eq!(e1_position.x, 0.0);717/// let e2_position = e2_ref.get::<Position>().unwrap();718/// assert_eq!(e2_position.x, 1.0);719/// ```720///721/// ## Slice of [`Entity`]s722///723/// ```724/// # use bevy_ecs::prelude::*;725/// #[derive(Component)]726/// struct Position {727/// x: f32,728/// y: f32,729/// }730///731/// let mut world = World::new();732/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();733/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();734/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();735///736/// let ids = vec![e1, e2, e3];737/// for eref in world.entity(&ids[..]) {738/// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);739/// }740/// ```741///742/// ## [`EntityHashSet`](crate::entity::EntityHashSet)743///744/// ```745/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};746/// #[derive(Component)]747/// struct Position {748/// x: f32,749/// y: f32,750/// }751///752/// let mut world = World::new();753/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();754/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();755/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();756///757/// let ids = EntityHashSet::from_iter([e1, e2, e3]);758/// for (_id, eref) in world.entity(&ids) {759/// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);760/// }761/// ```762///763/// [`EntityHashSet`]: crate::entity::EntityHashSet764#[inline]765#[track_caller]766pub fn entity<F: WorldEntityFetch>(&self, entities: F) -> F::Ref<'_> {767match self.get_entity(entities) {768Ok(res) => res,769Err(err) => panic!("{err}"),770}771}772773/// Returns [`EntityMut`]s that expose read and write operations for the774/// given `entities`. This will panic if any of the given entities do not775/// exist. Use [`World::get_entity_mut`] if you want to check for entity776/// existence instead of implicitly panicking.777///778/// This function supports fetching a single entity or multiple entities:779/// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].780/// - This reference type allows for structural changes to the entity,781/// such as adding or removing components, or despawning the entity.782/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].783/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.784/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an785/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).786///787/// In order to perform structural changes on the returned entity reference,788/// such as adding or removing components, or despawning the entity, only a789/// single [`Entity`] can be passed to this function. Allowing multiple790/// entities at the same time with structural access would lead to undefined791/// behavior, so [`EntityMut`] is returned when requesting multiple entities.792///793/// # Panics794///795/// If any of the given `entities` do not exist in the world.796///797/// # Examples798///799/// ## Single [`Entity`]800///801/// ```802/// # use bevy_ecs::prelude::*;803/// #[derive(Component)]804/// struct Position {805/// x: f32,806/// y: f32,807/// }808///809/// let mut world = World::new();810/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();811///812/// let mut entity_mut = world.entity_mut(entity);813/// let mut position = entity_mut.get_mut::<Position>().unwrap();814/// position.y = 1.0;815/// assert_eq!(position.x, 0.0);816/// entity_mut.despawn();817/// # assert!(world.get_entity_mut(entity).is_err());818/// ```819///820/// ## Array of [`Entity`]s821///822/// ```823/// # use bevy_ecs::prelude::*;824/// #[derive(Component)]825/// struct Position {826/// x: f32,827/// y: f32,828/// }829///830/// let mut world = World::new();831/// let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();832/// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();833///834/// let [mut e1_ref, mut e2_ref] = world.entity_mut([e1, e2]);835/// let mut e1_position = e1_ref.get_mut::<Position>().unwrap();836/// e1_position.x = 1.0;837/// assert_eq!(e1_position.x, 1.0);838/// let mut e2_position = e2_ref.get_mut::<Position>().unwrap();839/// e2_position.x = 2.0;840/// assert_eq!(e2_position.x, 2.0);841/// ```842///843/// ## Slice of [`Entity`]s844///845/// ```846/// # use bevy_ecs::prelude::*;847/// #[derive(Component)]848/// struct Position {849/// x: f32,850/// y: f32,851/// }852///853/// let mut world = World::new();854/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();855/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();856/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();857///858/// let ids = vec![e1, e2, e3];859/// for mut eref in world.entity_mut(&ids[..]) {860/// let mut pos = eref.get_mut::<Position>().unwrap();861/// pos.y = 2.0;862/// assert_eq!(pos.y, 2.0);863/// }864/// ```865///866/// ## [`EntityHashSet`](crate::entity::EntityHashSet)867///868/// ```869/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};870/// #[derive(Component)]871/// struct Position {872/// x: f32,873/// y: f32,874/// }875///876/// let mut world = World::new();877/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();878/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();879/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();880///881/// let ids = EntityHashSet::from_iter([e1, e2, e3]);882/// for (_id, mut eref) in world.entity_mut(&ids) {883/// let mut pos = eref.get_mut::<Position>().unwrap();884/// pos.y = 2.0;885/// assert_eq!(pos.y, 2.0);886/// }887/// ```888///889/// [`EntityHashSet`]: crate::entity::EntityHashSet890#[inline]891#[track_caller]892pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::Mut<'_> {893#[inline(never)]894#[cold]895#[track_caller]896fn panic_on_err(e: EntityMutableFetchError) -> ! {897panic!("{e}");898}899900match self.get_entity_mut(entities) {901Ok(fetched) => fetched,902Err(e) => panic_on_err(e),903}904}905906/// Returns the components of an [`Entity`] through [`ComponentInfo`].907#[inline]908pub fn inspect_entity(909&self,910entity: Entity,911) -> Result<impl Iterator<Item = &ComponentInfo>, EntityNotSpawnedError> {912let entity_location = self.entities().get_spawned(entity)?;913914let archetype = self915.archetypes()916.get(entity_location.archetype_id)917.expect("ArchetypeId was retrieved from an EntityLocation and should correspond to an Archetype");918919Ok(archetype920.iter_components()921.filter_map(|id| self.components().get_info(id)))922}923924/// Returns [`EntityRef`]s that expose read-only operations for the given925/// `entities`, returning [`Err`] if any of the given entities do not exist.926/// Instead of immediately unwrapping the value returned from this function,927/// prefer [`World::entity`].928///929/// This function supports fetching a single entity or multiple entities:930/// - Pass an [`Entity`] to receive a single [`EntityRef`].931/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].932/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.933/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an934/// [`EntityHashMap<EntityRef>`](crate::entity::EntityHashMap).935///936/// # Errors937///938/// If any of the given `entities` do not exist in the world, the first939/// [`Entity`] found to be missing will return an [`EntityNotSpawnedError`].940///941/// # Examples942///943/// For examples, see [`World::entity`].944///945/// [`EntityHashSet`]: crate::entity::EntityHashSet946#[inline]947pub fn get_entity<F: WorldEntityFetch>(948&self,949entities: F,950) -> Result<F::Ref<'_>, EntityNotSpawnedError> {951let cell = self.as_unsafe_world_cell_readonly();952// SAFETY: `&self` gives read access to the entire world, and prevents mutable access.953unsafe { entities.fetch_ref(cell) }954}955956/// Returns [`EntityMut`]s that expose read and write operations for the957/// given `entities`, returning [`Err`] if any of the given entities do not958/// exist. Instead of immediately unwrapping the value returned from this959/// function, prefer [`World::entity_mut`].960///961/// This function supports fetching a single entity or multiple entities:962/// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].963/// - This reference type allows for structural changes to the entity,964/// such as adding or removing components, or despawning the entity.965/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].966/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.967/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an968/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).969///970/// In order to perform structural changes on the returned entity reference,971/// such as adding or removing components, or despawning the entity, only a972/// single [`Entity`] can be passed to this function. Allowing multiple973/// entities at the same time with structural access would lead to undefined974/// behavior, so [`EntityMut`] is returned when requesting multiple entities.975///976/// # Errors977///978/// - Returns [`EntityMutableFetchError::NotSpawned`] if any of the given `entities` do not exist in the world.979/// - Only the first entity found to be missing will be returned.980/// - Returns [`EntityMutableFetchError::AliasedMutability`] if the same entity is requested multiple times.981///982/// # Examples983///984/// For examples, see [`World::entity_mut`].985///986/// [`EntityHashSet`]: crate::entity::EntityHashSet987#[inline]988pub fn get_entity_mut<F: WorldEntityFetch>(989&mut self,990entities: F,991) -> Result<F::Mut<'_>, EntityMutableFetchError> {992let cell = self.as_unsafe_world_cell();993// SAFETY: `&mut self` gives mutable access to the entire world,994// and prevents any other access to the world.995unsafe { entities.fetch_mut(cell) }996}997998/// Returns an [`Entity`] iterator of current entities.999///1000/// This is useful in contexts where you only have immutable access to the [`World`].1001/// If you have mutable access to the [`World`], use1002/// [`query()::<EntityRef>().iter(&world)`](World::query()) instead.1003///1004/// Note that this does iterate through *all* entities, including resource entities.1005#[inline]1006pub fn iter_entities(&self) -> impl Iterator<Item = EntityRef<'_>> + '_ {1007self.archetypes.iter().flat_map(|archetype| {1008archetype1009.entities_with_location()1010.map(|(entity, location)| {1011// SAFETY: entity exists and location accurately specifies the archetype where the entity is stored.1012let cell = UnsafeEntityCell::new(1013self.as_unsafe_world_cell_readonly(),1014entity,1015location,1016self.last_change_tick,1017self.read_change_tick(),1018);1019// SAFETY: `&self` gives read access to the entire world.1020unsafe { EntityRef::new(cell) }1021})1022})1023}10241025/// Simultaneously provides access to entity data and a command queue, which1026/// will be applied when the world is next flushed.1027///1028/// This allows using borrowed entity data to construct commands where the1029/// borrow checker would otherwise prevent it.1030///1031/// See [`DeferredWorld::entities_and_commands`] for the deferred version.1032///1033/// # Example1034///1035/// ```rust1036/// # use bevy_ecs::{prelude::*, world::DeferredWorld};1037/// #[derive(Component)]1038/// struct Targets(Vec<Entity>);1039/// #[derive(Component)]1040/// struct TargetedBy(Entity);1041///1042/// let mut world: World = // ...1043/// # World::new();1044/// # let e1 = world.spawn_empty().id();1045/// # let e2 = world.spawn_empty().id();1046/// # let eid = world.spawn(Targets(vec![e1, e2])).id();1047/// let (entities, mut commands) = world.entities_and_commands();1048///1049/// let entity = entities.get(eid).unwrap();1050/// for &target in entity.get::<Targets>().unwrap().0.iter() {1051/// commands.entity(target).insert(TargetedBy(eid));1052/// }1053/// # world.flush();1054/// # assert_eq!(world.get::<TargetedBy>(e1).unwrap().0, eid);1055/// # assert_eq!(world.get::<TargetedBy>(e2).unwrap().0, eid);1056/// ```1057pub fn entities_and_commands(&mut self) -> (EntityFetcher<'_>, Commands<'_, '_>) {1058let cell = self.as_unsafe_world_cell();1059// SAFETY: `&mut self` gives mutable access to the entire world, and prevents simultaneous access.1060let fetcher = unsafe { EntityFetcher::new(cell) };1061// SAFETY:1062// - `&mut self` gives mutable access to the entire world, and prevents simultaneous access.1063// - Command queue access does not conflict with entity access.1064let raw_queue = unsafe { cell.get_raw_command_queue() };1065// SAFETY: `&mut self` ensures the commands does not outlive the world.1066let commands = unsafe {1067Commands::new_raw_from_entities(raw_queue, cell.entity_allocator(), cell.entities())1068};10691070(fetcher, commands)1071}10721073/// Spawns the bundle on the valid but not spawned entity.1074/// If the entity can not be spawned for any reason, returns an error.1075///1076/// If it succeeds, this declares the entity to have this bundle.1077///1078/// In general, you should prefer [`spawn`](Self::spawn).1079/// Spawn internally calls this method, but it takes care of finding a suitable [`Entity`] for you.1080/// This is made available for advanced use, which you can see at [`EntityAllocator::alloc`].1081///1082/// # Risk1083///1084/// It is possible to spawn an `entity` that has not been allocated yet;1085/// however, doing so is currently a bad idea as the allocator may hand out this entity index in the future, assuming it to be not spawned.1086/// This would cause a panic.1087///1088/// Manual spawning is a powerful tool, but must be used carefully.1089///1090/// # Example1091///1092/// Currently, this is primarily used to spawn entities that come from [`EntityAllocator::alloc`].1093/// See that for an example.1094#[track_caller]1095pub fn spawn_at<B: Bundle>(1096&mut self,1097entity: Entity,1098bundle: B,1099) -> Result<EntityWorldMut<'_>, SpawnError> {1100move_as_ptr!(bundle);1101self.spawn_at_with_caller(entity, bundle, MaybeLocation::caller())1102}11031104pub(crate) fn spawn_at_with_caller<B: Bundle>(1105&mut self,1106entity: Entity,1107bundle: MovingPtr<'_, B>,1108caller: MaybeLocation,1109) -> Result<EntityWorldMut<'_>, SpawnError> {1110self.entities.check_can_spawn_at(entity)?;1111Ok(self.spawn_at_unchecked(entity, bundle, caller))1112}11131114/// Spawns `bundle` on `entity`.1115///1116/// # Panics1117///1118/// Panics if the entity index is already constructed1119pub(crate) fn spawn_at_unchecked<B: Bundle>(1120&mut self,1121entity: Entity,1122bundle: MovingPtr<'_, B>,1123caller: MaybeLocation,1124) -> EntityWorldMut<'_> {1125let change_tick = self.change_tick();1126let mut bundle_spawner = BundleSpawner::new::<B>(self, change_tick);1127let (bundle, entity_location) = bundle.partial_move(|bundle| {1128// SAFETY:1129// - `B` matches `bundle_spawner`'s type1130// - `entity` is allocated but non-existent1131// - `B::Effect` is unconstrained, and `B::apply_effect` is called exactly once on the bundle after this call.1132// - This function ensures that the value pointed to by `bundle` must not be accessed for anything afterwards by consuming1133// the `MovingPtr`. The value is otherwise only used to call `apply_effect` within this function, and the safety invariants1134// of `DynamicBundle` ensure that only the elements that have not been moved out of by this call are accessed.1135unsafe { bundle_spawner.spawn_at::<B>(entity, bundle, caller) }1136});11371138let mut entity_location = Some(entity_location);11391140// SAFETY: command_queue is not referenced anywhere else1141if !unsafe { self.command_queue.is_empty() } {1142self.flush();1143entity_location = self.entities().get_spawned(entity).ok();1144}11451146// SAFETY: The entity and location started as valid.1147// If they were changed by commands, the location was updated to match.1148let mut entity = unsafe { EntityWorldMut::new(self, entity, entity_location) };1149// SAFETY:1150// - This is called exactly once after `get_components` has been called in `spawn_non_existent`.1151// - `bundle` had it's `get_components` function called exactly once inside `spawn_non_existent`.1152unsafe { B::apply_effect(bundle, &mut entity) };1153entity1154}11551156/// A faster version of [`spawn_at`](Self::spawn_at) for the empty bundle.1157#[track_caller]1158pub fn spawn_empty_at(&mut self, entity: Entity) -> Result<EntityWorldMut<'_>, SpawnError> {1159self.spawn_empty_at_with_caller(entity, MaybeLocation::caller())1160}11611162pub(crate) fn spawn_empty_at_with_caller(1163&mut self,1164entity: Entity,1165caller: MaybeLocation,1166) -> Result<EntityWorldMut<'_>, SpawnError> {1167self.entities.check_can_spawn_at(entity)?;1168Ok(self.spawn_empty_at_unchecked(entity, caller))1169}11701171/// A faster version of [`spawn_at_unchecked`](Self::spawn_at_unchecked) for the empty bundle.1172///1173/// # Panics1174///1175/// Panics if the entity index is already spawned1176pub(crate) fn spawn_empty_at_unchecked(1177&mut self,1178entity: Entity,1179caller: MaybeLocation,1180) -> EntityWorldMut<'_> {1181// SAFETY: Locations are immediately made valid1182unsafe {1183let archetype = self.archetypes.empty_mut();1184// PERF: consider avoiding allocating entities in the empty archetype unless needed1185let table_row = self.storages.tables[archetype.table_id()].allocate(entity);1186// SAFETY: no components are allocated by archetype.allocate() because the archetype is1187// empty1188let location = archetype.allocate(entity, table_row);1189let change_tick = self.change_tick();1190let was_at = self.entities.set_location(entity.index(), Some(location));1191assert!(1192was_at.is_none(),1193"Attempting to construct an empty entity, but it was already constructed."1194);1195self.entities1196.mark_spawned_or_despawned(entity.index(), caller, change_tick);11971198EntityWorldMut::new(self, entity, Some(location))1199}1200}12011202/// Spawns a new [`Entity`] with a given [`Bundle`] of [components](`Component`) and returns1203/// a corresponding [`EntityWorldMut`], which can be used to add components to the entity or1204/// retrieve its id. In case large batches of entities need to be spawned, consider using1205/// [`World::spawn_batch`] instead.1206///1207/// ```1208/// use bevy_ecs::{bundle::Bundle, component::Component, world::World};1209///1210/// #[derive(Component)]1211/// struct Position {1212/// x: f32,1213/// y: f32,1214/// }1215///1216/// #[derive(Component)]1217/// struct Velocity {1218/// x: f32,1219/// y: f32,1220/// };1221///1222/// #[derive(Component)]1223/// struct Name(&'static str);1224///1225/// #[derive(Bundle)]1226/// struct PhysicsBundle {1227/// position: Position,1228/// velocity: Velocity,1229/// }1230///1231/// let mut world = World::new();1232///1233/// // `spawn` can accept a single component:1234/// world.spawn(Position { x: 0.0, y: 0.0 });1235///1236/// // It can also accept a tuple of components:1237/// world.spawn((1238/// Position { x: 0.0, y: 0.0 },1239/// Velocity { x: 1.0, y: 1.0 },1240/// ));1241///1242/// // Or it can accept a pre-defined Bundle of components:1243/// world.spawn(PhysicsBundle {1244/// position: Position { x: 2.0, y: 2.0 },1245/// velocity: Velocity { x: 0.0, y: 4.0 },1246/// });1247///1248/// let entity = world1249/// // Tuples can also mix Bundles and Components1250/// .spawn((1251/// PhysicsBundle {1252/// position: Position { x: 2.0, y: 2.0 },1253/// velocity: Velocity { x: 0.0, y: 4.0 },1254/// },1255/// Name("Elaina Proctor"),1256/// ))1257/// // Calling id() will return the unique identifier for the spawned entity1258/// .id();1259/// let position = world.entity(entity).get::<Position>().unwrap();1260/// assert_eq!(position.x, 2.0);1261/// ```1262#[track_caller]1263pub fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityWorldMut<'_> {1264move_as_ptr!(bundle);1265self.spawn_with_caller(bundle, MaybeLocation::caller())1266}12671268pub(crate) fn spawn_with_caller<B: Bundle>(1269&mut self,1270bundle: MovingPtr<'_, B>,1271caller: MaybeLocation,1272) -> EntityWorldMut<'_> {1273let entity = self.entity_allocator.alloc();1274// This was just spawned from null, so it shouldn't panic.1275self.spawn_at_unchecked(entity, bundle, caller)1276}12771278/// Spawns a new [`Entity`] and returns a corresponding [`EntityWorldMut`], which can be used1279/// to add components to the entity or retrieve its id.1280///1281/// ```1282/// use bevy_ecs::{component::Component, world::World};1283///1284/// #[derive(Component)]1285/// struct Position {1286/// x: f32,1287/// y: f32,1288/// }1289/// #[derive(Component)]1290/// struct Label(&'static str);1291/// #[derive(Component)]1292/// struct Num(u32);1293///1294/// let mut world = World::new();1295/// let entity = world.spawn_empty()1296/// .insert(Position { x: 0.0, y: 0.0 }) // add a single component1297/// .insert((Num(1), Label("hello"))) // add a bundle of components1298/// .id();1299///1300/// let position = world.entity(entity).get::<Position>().unwrap();1301/// assert_eq!(position.x, 0.0);1302/// ```1303#[track_caller]1304pub fn spawn_empty(&mut self) -> EntityWorldMut<'_> {1305self.spawn_empty_with_caller(MaybeLocation::caller())1306}13071308pub(crate) fn spawn_empty_with_caller(&mut self, caller: MaybeLocation) -> EntityWorldMut<'_> {1309let entity = self.entity_allocator.alloc();1310// This was just spawned from null, so it shouldn't panic.1311self.spawn_empty_at_unchecked(entity, caller)1312}13131314/// Spawns a batch of entities with the same component [`Bundle`] type. Takes a given1315/// [`Bundle`] iterator and returns a corresponding [`Entity`] iterator.1316/// This is more efficient than spawning entities and adding components to them individually1317/// using [`World::spawn`], but it is limited to spawning entities with the same [`Bundle`]1318/// type, whereas spawning individually is more flexible.1319///1320/// ```1321/// use bevy_ecs::{component::Component, entity::Entity, world::World};1322///1323/// #[derive(Component)]1324/// struct Str(&'static str);1325/// #[derive(Component)]1326/// struct Num(u32);1327///1328/// let mut world = World::new();1329/// let entities = world.spawn_batch(vec![1330/// (Str("a"), Num(0)), // the first entity1331/// (Str("b"), Num(1)), // the second entity1332/// ]).collect::<Vec<Entity>>();1333///1334/// assert_eq!(entities.len(), 2);1335/// ```1336#[track_caller]1337pub fn spawn_batch<I>(&mut self, iter: I) -> SpawnBatchIter<'_, I::IntoIter>1338where1339I: IntoIterator,1340I::Item: Bundle<Effect: NoBundleEffect>,1341{1342SpawnBatchIter::new(self, iter.into_iter(), MaybeLocation::caller())1343}13441345/// Retrieves a reference to the given `entity`'s [`Component`] of the given type.1346/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1347/// ```1348/// use bevy_ecs::{component::Component, world::World};1349///1350/// #[derive(Component)]1351/// struct Position {1352/// x: f32,1353/// y: f32,1354/// }1355///1356/// let mut world = World::new();1357/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1358/// let position = world.get::<Position>(entity).unwrap();1359/// assert_eq!(position.x, 0.0);1360/// ```1361#[inline]1362pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {1363self.get_entity(entity).ok()?.get()1364}13651366/// Retrieves a mutable reference to the given `entity`'s [`Component`] of the given type.1367/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1368/// ```1369/// use bevy_ecs::{component::Component, world::World};1370///1371/// #[derive(Component)]1372/// struct Position {1373/// x: f32,1374/// y: f32,1375/// }1376///1377/// let mut world = World::new();1378/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1379/// let mut position = world.get_mut::<Position>(entity).unwrap();1380/// position.x = 1.0;1381/// ```1382#[inline]1383pub fn get_mut<T: Component<Mutability = Mutable>>(1384&mut self,1385entity: Entity,1386) -> Option<Mut<'_, T>> {1387self.get_entity_mut(entity).ok()?.into_mut()1388}13891390/// Temporarily removes a [`Component`] `T` from the provided [`Entity`] and1391/// runs the provided closure on it, returning the result if `T` was available.1392/// This will trigger the `Remove` and `Replace` component hooks without1393/// causing an archetype move.1394///1395/// This is most useful with immutable components, where removal and reinsertion1396/// is the only way to modify a value.1397///1398/// If you do not need to ensure the above hooks are triggered, and your component1399/// is mutable, prefer using [`get_mut`](World::get_mut).1400///1401/// # Examples1402///1403/// ```rust1404/// # use bevy_ecs::prelude::*;1405/// #1406/// #[derive(Component, PartialEq, Eq, Debug)]1407/// #[component(immutable)]1408/// struct Foo(bool);1409///1410/// # let mut world = World::default();1411/// # world.register_component::<Foo>();1412/// #1413/// # let entity = world.spawn(Foo(false)).id();1414/// #1415/// world.modify_component(entity, |foo: &mut Foo| {1416/// foo.0 = true;1417/// });1418/// #1419/// # assert_eq!(world.get::<Foo>(entity), Some(&Foo(true)));1420/// ```1421#[inline]1422#[track_caller]1423pub fn modify_component<T: Component, R>(1424&mut self,1425entity: Entity,1426f: impl FnOnce(&mut T) -> R,1427) -> Result<Option<R>, EntityMutableFetchError> {1428let mut world = DeferredWorld::from(&mut *self);14291430let result = world.modify_component_with_relationship_hook_mode(1431entity,1432RelationshipHookMode::Run,1433f,1434)?;14351436self.flush();1437Ok(result)1438}14391440/// Temporarily removes a [`Component`] identified by the provided1441/// [`ComponentId`] from the provided [`Entity`] and runs the provided1442/// closure on it, returning the result if the component was available.1443/// This will trigger the `Remove` and `Replace` component hooks without1444/// causing an archetype move.1445///1446/// This is most useful with immutable components, where removal and reinsertion1447/// is the only way to modify a value.1448///1449/// If you do not need to ensure the above hooks are triggered, and your component1450/// is mutable, prefer using [`get_mut_by_id`](World::get_mut_by_id).1451///1452/// You should prefer the typed [`modify_component`](World::modify_component)1453/// whenever possible.1454#[inline]1455#[track_caller]1456pub fn modify_component_by_id<R>(1457&mut self,1458entity: Entity,1459component_id: ComponentId,1460f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,1461) -> Result<Option<R>, EntityMutableFetchError> {1462let mut world = DeferredWorld::from(&mut *self);14631464let result = world.modify_component_by_id_with_relationship_hook_mode(1465entity,1466component_id,1467RelationshipHookMode::Run,1468f,1469)?;14701471self.flush();1472Ok(result)1473}14741475/// Despawns the given [`Entity`], if it exists.1476/// This will also remove all of the entity's [`Components`](Component).1477///1478/// Returns `true` if the entity is successfully despawned and `false` if1479/// the entity does not exist.1480/// This counts despawning a not constructed entity as a success, and frees it to the allocator.1481/// See [entity](crate::entity) module docs for more about construction.1482///1483/// # Note1484///1485/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1486/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1487///1488/// ```1489/// use bevy_ecs::{component::Component, world::World};1490///1491/// #[derive(Component)]1492/// struct Position {1493/// x: f32,1494/// y: f32,1495/// }1496///1497/// let mut world = World::new();1498/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1499/// assert!(world.despawn(entity));1500/// assert!(world.get_entity(entity).is_err());1501/// assert!(world.get::<Position>(entity).is_none());1502/// ```1503#[track_caller]1504#[inline]1505pub fn despawn(&mut self, entity: Entity) -> bool {1506if let Err(error) = self.despawn_with_caller(entity, MaybeLocation::caller()) {1507warn!("{error}");1508false1509} else {1510true1511}1512}15131514/// Despawns the given `entity`, if it exists. This will also remove all of the entity's1515/// [`Components`](Component).1516///1517/// Returns an [`EntityDespawnError`] if the entity is not spawned to be despawned.1518///1519/// # Note1520///1521/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1522/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1523#[track_caller]1524#[inline]1525pub fn try_despawn(&mut self, entity: Entity) -> Result<(), EntityDespawnError> {1526self.despawn_with_caller(entity, MaybeLocation::caller())1527}15281529#[inline]1530pub(crate) fn despawn_with_caller(1531&mut self,1532entity: Entity,1533caller: MaybeLocation,1534) -> Result<(), EntityDespawnError> {1535match self.get_entity_mut(entity) {1536Ok(entity) => {1537entity.despawn_with_caller(caller);1538Ok(())1539}1540// Only one entity.1541Err(EntityMutableFetchError::AliasedMutability(_)) => unreachable!(),1542Err(EntityMutableFetchError::NotSpawned(err)) => Err(EntityDespawnError(err)),1543}1544}15451546/// Performs [`try_despawn_no_free`](Self::try_despawn_no_free), warning on errors.1547/// See that method for more information.1548#[track_caller]1549#[inline]1550pub fn despawn_no_free(&mut self, entity: Entity) -> Option<Entity> {1551match self.despawn_no_free_with_caller(entity, MaybeLocation::caller()) {1552Ok(entity) => Some(entity),1553Err(error) => {1554warn!("{error}");1555None1556}1557}1558}15591560/// Despawns the given `entity`, if it exists.1561/// This will also remove all of the entity's [`Component`]s.1562///1563/// The *only* difference between this and [despawning](Self::despawn) an entity is that this does not release the `entity` to be reused.1564/// It is up to the caller to either re-spawn or free the `entity`; otherwise, the [`EntityIndex`](crate::entity::EntityIndex) will not be able to be reused.1565/// In general, [`despawn`](Self::despawn) should be used instead, which automatically allows the row to be reused.1566///1567/// Returns the new [`Entity`] if of the despawned [`EntityIndex`](crate::entity::EntityIndex), which should eventually either be re-spawned or freed to the allocator.1568/// Returns an [`EntityDespawnError`] if the entity is not spawned.1569///1570/// # Note1571///1572/// This will also *despawn* the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1573/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1574///1575/// # Example1576///1577/// There is no simple example in which this would be practical, but one use for this is a custom entity allocator.1578/// Despawning internally calls this and frees the entity id to Bevy's default entity allocator.1579/// The same principal can be used to create custom allocators with additional properties.1580/// For example, this could be used to make an allocator that yields groups of consecutive [`EntityIndex`](crate::entity::EntityIndex)s, etc.1581/// See [`EntityAllocator::alloc`] for more on this.1582#[track_caller]1583#[inline]1584pub fn try_despawn_no_free(&mut self, entity: Entity) -> Result<Entity, EntityDespawnError> {1585self.despawn_no_free_with_caller(entity, MaybeLocation::caller())1586}15871588#[inline]1589pub(crate) fn despawn_no_free_with_caller(1590&mut self,1591entity: Entity,1592caller: MaybeLocation,1593) -> Result<Entity, EntityDespawnError> {1594let mut entity = self.get_entity_mut(entity).map_err(|err| match err {1595EntityMutableFetchError::NotSpawned(err) => err,1596// Only one entity.1597EntityMutableFetchError::AliasedMutability(_) => unreachable!(),1598})?;1599entity.despawn_no_free_with_caller(caller);1600Ok(entity.id())1601}16021603/// Clears the internal component tracker state.1604///1605/// The world maintains some internal state about changed and removed components. This state1606/// is used by [`RemovedComponents`] to provide access to the entities that had a specific type1607/// of component removed since last tick.1608///1609/// The state is also used for change detection when accessing components and resources outside1610/// of a system, for example via [`World::get_mut()`] or [`World::get_resource_mut()`].1611///1612/// By clearing this internal state, the world "forgets" about those changes, allowing a new round1613/// of detection to be recorded.1614///1615/// When using `bevy_ecs` as part of the full Bevy engine, this method is called automatically1616/// by `bevy_app::App::update` and `bevy_app::SubApp::update`, so you don't need to call it manually.1617/// When using `bevy_ecs` as a separate standalone crate however, you do need to call this manually.1618///1619/// ```1620/// # use bevy_ecs::prelude::*;1621/// # #[derive(Component, Default)]1622/// # struct Transform;1623/// // a whole new world1624/// let mut world = World::new();1625///1626/// // you changed it1627/// let entity = world.spawn(Transform::default()).id();1628///1629/// // change is detected1630/// let transform = world.get_mut::<Transform>(entity).unwrap();1631/// assert!(transform.is_changed());1632///1633/// // update the last change tick1634/// world.clear_trackers();1635///1636/// // change is no longer detected1637/// let transform = world.get_mut::<Transform>(entity).unwrap();1638/// assert!(!transform.is_changed());1639/// ```1640///1641/// [`RemovedComponents`]: crate::lifecycle::RemovedComponents1642pub fn clear_trackers(&mut self) {1643self.removed_components.update();1644self.last_change_tick = self.increment_change_tick();1645}16461647/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1648/// run queries on the [`World`] by storing and reusing the [`QueryState`].1649/// ```1650/// use bevy_ecs::{component::Component, entity::Entity, world::World};1651///1652/// #[derive(Component, Debug, PartialEq)]1653/// struct Position {1654/// x: f32,1655/// y: f32,1656/// }1657///1658/// #[derive(Component)]1659/// struct Velocity {1660/// x: f32,1661/// y: f32,1662/// }1663///1664/// let mut world = World::new();1665/// let entities = world.spawn_batch(vec![1666/// (Position { x: 0.0, y: 0.0}, Velocity { x: 1.0, y: 0.0 }),1667/// (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }),1668/// ]).collect::<Vec<Entity>>();1669///1670/// let mut query = world.query::<(&mut Position, &Velocity)>();1671/// for (mut position, velocity) in query.iter_mut(&mut world) {1672/// position.x += velocity.x;1673/// position.y += velocity.y;1674/// }1675///1676/// assert_eq!(world.get::<Position>(entities[0]).unwrap(), &Position { x: 1.0, y: 0.0 });1677/// assert_eq!(world.get::<Position>(entities[1]).unwrap(), &Position { x: 0.0, y: 1.0 });1678/// ```1679///1680/// To iterate over entities in a deterministic order,1681/// sort the results of the query using the desired component as a key.1682/// Note that this requires fetching the whole result set from the query1683/// and allocation of a [`Vec`] to store it.1684///1685/// ```1686/// use bevy_ecs::{component::Component, entity::Entity, world::World};1687///1688/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Debug)]1689/// struct Order(i32);1690/// #[derive(Component, PartialEq, Debug)]1691/// struct Label(&'static str);1692///1693/// let mut world = World::new();1694/// let a = world.spawn((Order(2), Label("second"))).id();1695/// let b = world.spawn((Order(3), Label("third"))).id();1696/// let c = world.spawn((Order(1), Label("first"))).id();1697/// let mut entities = world.query::<(Entity, &Order, &Label)>()1698/// .iter(&world)1699/// .collect::<Vec<_>>();1700/// // Sort the query results by their `Order` component before comparing1701/// // to expected results. Query iteration order should not be relied on.1702/// entities.sort_by_key(|e| e.1);1703/// assert_eq!(entities, vec![1704/// (c, &Order(1), &Label("first")),1705/// (a, &Order(2), &Label("second")),1706/// (b, &Order(3), &Label("third")),1707/// ]);1708/// ```1709#[inline]1710pub fn query<D: QueryData>(&mut self) -> QueryState<D, ()> {1711self.query_filtered::<D, ()>()1712}17131714/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1715/// run queries on the [`World`] by storing and reusing the [`QueryState`].1716/// ```1717/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1718///1719/// #[derive(Component)]1720/// struct A;1721/// #[derive(Component)]1722/// struct B;1723///1724/// let mut world = World::new();1725/// let e1 = world.spawn(A).id();1726/// let e2 = world.spawn((A, B)).id();1727///1728/// let mut query = world.query_filtered::<Entity, With<B>>();1729/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1730///1731/// assert_eq!(matching_entities, vec![e2]);1732/// ```1733#[inline]1734pub fn query_filtered<D: QueryData, F: QueryFilter>(&mut self) -> QueryState<D, F> {1735QueryState::new(self)1736}17371738/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1739/// run queries on the [`World`] by storing and reusing the [`QueryState`].1740/// ```1741/// use bevy_ecs::{component::Component, entity::Entity, world::World};1742///1743/// #[derive(Component, Debug, PartialEq)]1744/// struct Position {1745/// x: f32,1746/// y: f32,1747/// }1748///1749/// let mut world = World::new();1750/// world.spawn_batch(vec![1751/// Position { x: 0.0, y: 0.0 },1752/// Position { x: 1.0, y: 1.0 },1753/// ]);1754///1755/// fn get_positions(world: &World) -> Vec<(Entity, &Position)> {1756/// let mut query = world.try_query::<(Entity, &Position)>().unwrap();1757/// query.iter(world).collect()1758/// }1759///1760/// let positions = get_positions(&world);1761///1762/// assert_eq!(world.get::<Position>(positions[0].0).unwrap(), positions[0].1);1763/// assert_eq!(world.get::<Position>(positions[1].0).unwrap(), positions[1].1);1764/// ```1765///1766/// Requires only an immutable world reference, but may fail if, for example,1767/// the components that make up this query have not been registered into the world.1768/// ```1769/// use bevy_ecs::{component::Component, entity::Entity, world::World};1770///1771/// #[derive(Component)]1772/// struct A;1773///1774/// let mut world = World::new();1775///1776/// let none_query = world.try_query::<&A>();1777/// assert!(none_query.is_none());1778///1779/// world.register_component::<A>();1780///1781/// let some_query = world.try_query::<&A>();1782/// assert!(some_query.is_some());1783/// ```1784#[inline]1785pub fn try_query<D: QueryData>(&self) -> Option<QueryState<D, ()>> {1786self.try_query_filtered::<D, ()>()1787}17881789/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1790/// run queries on the [`World`] by storing and reusing the [`QueryState`].1791/// ```1792/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1793///1794/// #[derive(Component)]1795/// struct A;1796/// #[derive(Component)]1797/// struct B;1798///1799/// let mut world = World::new();1800/// let e1 = world.spawn(A).id();1801/// let e2 = world.spawn((A, B)).id();1802///1803/// let mut query = world.try_query_filtered::<Entity, With<B>>().unwrap();1804/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1805///1806/// assert_eq!(matching_entities, vec![e2]);1807/// ```1808///1809/// Requires only an immutable world reference, but may fail if, for example,1810/// the components that make up this query have not been registered into the world.1811#[inline]1812pub fn try_query_filtered<D: QueryData, F: QueryFilter>(&self) -> Option<QueryState<D, F>> {1813QueryState::try_new(self)1814}18151816/// Returns an iterator of entities that had components of type `T` removed1817/// since the last call to [`World::clear_trackers`].1818pub fn removed<T: Component>(&self) -> impl Iterator<Item = Entity> + '_ {1819self.components1820.get_valid_id(TypeId::of::<T>())1821.map(|component_id| self.removed_with_id(component_id))1822.into_iter()1823.flatten()1824}18251826/// Returns an iterator of entities that had components with the given `component_id` removed1827/// since the last call to [`World::clear_trackers`].1828pub fn removed_with_id(&self, component_id: ComponentId) -> impl Iterator<Item = Entity> + '_ {1829self.removed_components1830.get(component_id)1831.map(|removed| removed.iter_current_update_messages().cloned())1832.into_iter()1833.flatten()1834.map(Into::into)1835}18361837/// Registers a new non-send resource type and returns the [`ComponentId`] created for it.1838///1839/// This enables the dynamic registration of new non-send resources definitions at runtime for1840/// advanced use cases.1841///1842/// # Note1843///1844/// Registering a non-send resource does not insert it into [`World`]. For insertion, you could use1845/// [`World::insert_non_send_by_id`].1846pub fn register_non_send_with_descriptor(1847&mut self,1848descriptor: ComponentDescriptor,1849) -> ComponentId {1850self.components_registrator()1851.register_component_with_descriptor(descriptor)1852}18531854fn insert_resource_if_not_exists_with_caller<R: Resource>(1855&mut self,1856func: impl FnOnce(&mut World) -> R,1857caller: MaybeLocation,1858) -> (ComponentId, EntityWorldMut<'_>) {1859let resource_id = self.register_resource::<R>();18601861if let Some(&entity) = self.resource_entities.get(resource_id) {1862let entity_ref = self.get_entity(entity).expect("ResourceCache is in sync");1863if !entity_ref.contains_id(resource_id) {1864let resource = func(self);1865move_as_ptr!(resource);1866self.entity_mut(entity).insert_with_caller(1867resource,1868InsertMode::Replace,1869caller,1870RelationshipHookMode::Run,1871);1872}1873return (resource_id, self.entity_mut(entity));1874}18751876let resource = func(self);1877move_as_ptr!(resource);1878let entity_mut = self.spawn_with_caller(resource, caller); // ResourceCache is updated automatically1879(resource_id, entity_mut)1880}18811882/// Initializes a new resource and returns the [`ComponentId`] created for it.1883///1884/// If the resource already exists, nothing happens.1885///1886/// The value given by the [`FromWorld::from_world`] method will be used.1887/// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],1888/// and those default values will be here instead.1889#[inline]1890#[track_caller]1891pub fn init_resource<R: Resource + FromWorld>(&mut self) -> ComponentId {1892let caller = MaybeLocation::caller();1893self.insert_resource_if_not_exists_with_caller(R::from_world, caller)1894.01895}18961897/// Inserts a new resource with the given `value`.1898///1899/// Resources are "unique" data of a given type.1900/// If you insert a resource of a type that already exists,1901/// you will overwrite any existing data.1902#[inline]1903#[track_caller]1904pub fn insert_resource<R: Resource>(&mut self, value: R) {1905self.insert_resource_with_caller(value, MaybeLocation::caller());1906}19071908/// Split into a new function so we can pass the calling location into the function when using1909/// as a command.1910#[inline]1911pub(crate) fn insert_resource_with_caller<R: Resource>(1912&mut self,1913value: R,1914caller: MaybeLocation,1915) {1916let component_id = self.components_registrator().register_component::<R>();1917OwningPtr::make(value, |ptr| {1918// SAFETY: component_id was just initialized and corresponds to resource of type R.1919unsafe {1920self.insert_resource_by_id(component_id, ptr, caller);1921}1922});1923}19241925/// Initializes a new non-send resource and returns the [`ComponentId`] created for it.1926#[deprecated(since = "0.19.0", note = "use World::init_non_send")]1927pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> ComponentId {1928self.init_non_send::<R>()1929}19301931/// Initializes new non-send data and returns the [`ComponentId`] created for it.1932///1933/// If the data already exists, nothing happens.1934///1935/// The value given by the [`FromWorld::from_world`] method will be used.1936/// Note that any non-send data with the `Default` trait automatically implements1937/// `FromWorld`, and those default values will be here instead.1938///1939/// # Panics1940///1941/// Panics if called from a thread other than the main thread.1942#[inline]1943#[track_caller]1944pub fn init_non_send<R: 'static + FromWorld>(&mut self) -> ComponentId {1945let caller = MaybeLocation::caller();1946let component_id = self.components_registrator().register_non_send::<R>();1947if self1948.storages1949.non_sends1950.get(component_id)1951.is_none_or(|data| !data.is_present())1952{1953let value = R::from_world(self);1954OwningPtr::make(value, |ptr| {1955// SAFETY: component_id was just initialized and corresponds to resource of type R.1956unsafe {1957self.insert_non_send_by_id(component_id, ptr, caller);1958}1959});1960}1961component_id1962}19631964/// Inserts a new non-send resource with the given `value`.1965#[deprecated(since = "0.19.0", note = "use World::insert_non_send")]1966pub fn insert_non_send_resource<R: 'static>(&mut self, value: R) {1967self.insert_non_send(value);1968}19691970/// Inserts new non-send data with the given `value`.1971///1972/// `NonSend` data cannot be sent across threads,1973/// and do not need the `Send + Sync` bounds.1974/// Systems with `NonSend` resources are always scheduled on the main thread.1975///1976/// # Panics1977/// If a value is already present, this function will panic if called1978/// from a different thread than where the original value was inserted from.1979#[inline]1980#[track_caller]1981pub fn insert_non_send<R: 'static>(&mut self, value: R) {1982let caller = MaybeLocation::caller();1983let component_id = self.components_registrator().register_non_send::<R>();1984OwningPtr::make(value, |ptr| {1985// SAFETY: component_id was just initialized and corresponds to the data of type R.1986unsafe {1987self.insert_non_send_by_id(component_id, ptr, caller);1988}1989});1990}19911992/// Removes the resource of a given type and returns it, if it exists. Otherwise returns `None`.1993#[inline]1994pub fn remove_resource<R: Resource>(&mut self) -> Option<R> {1995let resource_id = self.resource_id::<R>()?;1996let entity = *self.resource_entities.get(resource_id)?;1997let value = self1998.get_entity_mut(entity)1999.expect("ResourceCache is in sync")2000.take::<R>()?;2001Some(value)2002}20032004/// Removes a `!Send` resource from the world and returns it, if present.2005#[deprecated(since = "0.19.0", note = "use World::remove_non_send")]2006pub fn remove_non_send_resource<R: 'static>(&mut self) -> Option<R> {2007self.remove_non_send::<R>()2008}20092010/// Removes `!Send` data from the world and returns it, if present.2011///2012/// `NonSend` resources cannot be sent across threads,2013/// and do not need the `Send + Sync` bounds.2014/// Systems with `NonSend` data are always scheduled on the main thread.2015///2016/// Returns `None` if a value was not previously present.2017///2018/// # Panics2019/// If a value is present, this function will panic if called from a different2020/// thread than where the value was inserted from.2021#[inline]2022pub fn remove_non_send<R: 'static>(&mut self) -> Option<R> {2023let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;2024let (ptr, _, _) = self.storages.non_sends.get_mut(component_id)?.remove()?;2025// SAFETY: `component_id` was gotten via looking up the `R` type2026unsafe { Some(ptr.read::<R>()) }2027}20282029/// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.2030#[inline]2031pub fn contains_resource<R: Resource>(&self) -> bool {2032self.components2033.get_valid_resource_id(TypeId::of::<R>())2034.is_some_and(|component_id| self.contains_resource_by_id(component_id))2035}20362037/// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.2038#[inline]2039pub fn contains_resource_by_id(&self, component_id: ComponentId) -> bool {2040if let Some(entity) = self.resource_entities.get(component_id)2041&& let Ok(entity_ref) = self.get_entity(*entity)2042{2043return entity_ref.contains_id(component_id);2044}2045false2046}20472048/// Returns `true` if `!Send` data of type `R` exists. Otherwise returns `false`.2049#[inline]2050pub fn contains_non_send<R: 'static>(&self) -> bool {2051self.components2052.get_valid_resource_id(TypeId::of::<R>())2053.and_then(|component_id| self.storages.non_sends.get(component_id))2054.is_some_and(NonSendData::is_present)2055}20562057/// Returns `true` if `!Send` data with `component_id` exists. Otherwise returns `false`.2058#[inline]2059pub fn contains_non_send_by_id(&self, component_id: ComponentId) -> bool {2060self.storages2061.non_sends2062.get(component_id)2063.is_some_and(NonSendData::is_present)2064}20652066/// Returns `true` if a resource of type `R` exists and was added since the world's2067/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2068///2069/// This means that:2070/// - When called from an exclusive system, this will check for additions since the system last ran.2071/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]2072/// was called.2073pub fn is_resource_added<R: Resource>(&self) -> bool {2074self.components2075.get_valid_resource_id(TypeId::of::<R>())2076.is_some_and(|component_id| self.is_resource_added_by_id(component_id))2077}20782079/// Returns `true` if a resource with id `component_id` exists and was added since the world's2080/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2081///2082/// This means that:2083/// - When called from an exclusive system, this will check for additions since the system last ran.2084/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]2085/// was called.2086pub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool {2087self.get_resource_change_ticks_by_id(component_id)2088.is_some_and(|ticks| ticks.is_added(self.last_change_tick(), self.read_change_tick()))2089}20902091/// Returns `true` if a resource of type `R` exists and was modified since the world's2092/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2093///2094/// This means that:2095/// - When called from an exclusive system, this will check for changes since the system last ran.2096/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]2097/// was called.2098pub fn is_resource_changed<R: Resource>(&self) -> bool {2099self.components2100.get_valid_resource_id(TypeId::of::<R>())2101.is_some_and(|component_id| self.is_resource_changed_by_id(component_id))2102}21032104/// Returns `true` if a resource with id `component_id` exists and was modified since the world's2105/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2106///2107/// This means that:2108/// - When called from an exclusive system, this will check for changes since the system last ran.2109/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]2110/// was called.2111pub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool {2112self.get_resource_change_ticks_by_id(component_id)2113.is_some_and(|ticks| ticks.is_changed(self.last_change_tick(), self.read_change_tick()))2114}21152116/// Retrieves the change ticks for the given resource.2117pub fn get_resource_change_ticks<R: Resource>(&self) -> Option<ComponentTicks> {2118self.components2119.get_valid_resource_id(TypeId::of::<R>())2120.and_then(|component_id| self.get_resource_change_ticks_by_id(component_id))2121}21222123/// Retrieves the change ticks for the given [`ComponentId`].2124///2125/// **You should prefer to use the typed API [`World::get_resource_change_ticks`] where possible.**2126pub fn get_resource_change_ticks_by_id(2127&self,2128component_id: ComponentId,2129) -> Option<ComponentTicks> {2130let entity = self.resource_entities.get(component_id)?;2131let entity_ref = self.get_entity(*entity).ok()?;2132entity_ref.get_change_ticks_by_id(component_id)2133}21342135/// Gets a reference to the resource of the given type2136///2137/// # Panics2138///2139/// Panics if the resource does not exist.2140/// Use [`get_resource`](World::get_resource) instead if you want to handle this case.2141///2142/// If you want to instead insert a value if the resource does not exist,2143/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2144#[inline]2145#[track_caller]2146pub fn resource<R: Resource>(&self) -> &R {2147match self.get_resource() {2148Some(x) => x,2149None => panic!(2150"Requested resource {} does not exist in the `World`.2151Did you forget to add it using `app.insert_resource` / `app.init_resource`?2152Resources are also implicitly added via `app.add_message`,2153and can be added by plugins.",2154DebugName::type_name::<R>()2155),2156}2157}21582159/// Gets a reference to the resource of the given type2160///2161/// # Panics2162///2163/// Panics if the resource does not exist.2164/// Use [`get_resource_ref`](World::get_resource_ref) instead if you want to handle this case.2165///2166/// If you want to instead insert a value if the resource does not exist,2167/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2168#[inline]2169#[track_caller]2170pub fn resource_ref<R: Resource>(&self) -> Ref<'_, R> {2171match self.get_resource_ref() {2172Some(x) => x,2173None => panic!(2174"Requested resource {} does not exist in the `World`.2175Did you forget to add it using `app.insert_resource` / `app.init_resource`?2176Resources are also implicitly added via `app.add_message`,2177and can be added by plugins.",2178DebugName::type_name::<R>()2179),2180}2181}21822183/// Gets a mutable reference to the resource of the given type2184///2185/// # Panics2186///2187/// Panics if the resource does not exist.2188/// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.2189///2190/// If you want to instead insert a value if the resource does not exist,2191/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2192#[inline]2193#[track_caller]2194pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {2195match self.get_resource_mut() {2196Some(x) => x,2197None => panic!(2198"Requested resource {} does not exist in the `World`.2199Did you forget to add it using `app.insert_resource` / `app.init_resource`?2200Resources are also implicitly added via `app.add_message`,2201and can be added by plugins.",2202DebugName::type_name::<R>()2203),2204}2205}22062207/// Gets a reference to the resource of the given type if it exists2208#[inline]2209pub fn get_resource<R: Resource>(&self) -> Option<&R> {2210// SAFETY:2211// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2212// - `&self` ensures nothing in world is borrowed mutably2213unsafe { self.as_unsafe_world_cell_readonly().get_resource() }2214}22152216/// Gets a reference including change detection to the resource of the given type if it exists.2217#[inline]2218pub fn get_resource_ref<R: Resource>(&self) -> Option<Ref<'_, R>> {2219// SAFETY:2220// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2221// - `&self` ensures nothing in world is borrowed mutably2222unsafe { self.as_unsafe_world_cell_readonly().get_resource_ref() }2223}22242225/// Gets a mutable reference to the resource of the given type if it exists2226#[inline]2227pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {2228// SAFETY:2229// - `as_unsafe_world_cell` gives permission to access everything mutably2230// - `&mut self` ensures nothing in world is borrowed2231unsafe { self.as_unsafe_world_cell().get_resource_mut() }2232}22332234/// Gets a mutable reference to the resource of type `T` if it exists,2235/// otherwise inserts the resource using the result of calling `func`.2236///2237/// # Example2238///2239/// ```2240/// # use bevy_ecs::prelude::*;2241/// #2242/// #[derive(Resource)]2243/// struct MyResource(i32);2244///2245/// # let mut world = World::new();2246/// let my_res = world.get_resource_or_insert_with(|| MyResource(10));2247/// assert_eq!(my_res.0, 10);2248/// ```2249#[inline]2250#[track_caller]2251pub fn get_resource_or_insert_with<R: Resource>(2252&mut self,2253func: impl FnOnce() -> R,2254) -> Mut<'_, R> {2255let caller = MaybeLocation::caller();2256let (resource_id, entity) =2257self.insert_resource_if_not_exists_with_caller(|_world: &mut World| func(), caller);2258let untyped = entity2259.into_mut_by_id(resource_id)2260.expect("Resource must exist");2261// SAFETY: resource is of type R2262unsafe { untyped.with_type() }2263}22642265/// Gets a mutable reference to the resource of type `T` if it exists,2266/// otherwise initializes the resource by calling its [`FromWorld`]2267/// implementation.2268///2269/// # Example2270///2271/// ```2272/// # use bevy_ecs::prelude::*;2273/// #2274/// #[derive(Resource)]2275/// struct Foo(i32);2276///2277/// impl Default for Foo {2278/// fn default() -> Self {2279/// Self(15)2280/// }2281/// }2282///2283/// #[derive(Resource)]2284/// struct MyResource(i32);2285///2286/// impl FromWorld for MyResource {2287/// fn from_world(world: &mut World) -> Self {2288/// let foo = world.get_resource_or_init::<Foo>();2289/// Self(foo.0 * 2)2290/// }2291/// }2292///2293/// # let mut world = World::new();2294/// let my_res = world.get_resource_or_init::<MyResource>();2295/// assert_eq!(my_res.0, 30);2296/// ```2297#[track_caller]2298pub fn get_resource_or_init<R: Resource + FromWorld>(&mut self) -> Mut<'_, R> {2299let caller = MaybeLocation::caller();2300let (resource_id, entity) =2301self.insert_resource_if_not_exists_with_caller(R::from_world, caller);2302let untyped = entity2303.into_mut_by_id(resource_id)2304.expect("Resource must exist");2305// SAFETY: resource is of type R2306unsafe { untyped.with_type() }2307}23082309/// Gets an immutable reference to a non-send resource of the given type, if it exists.2310#[deprecated(since = "0.19.0", note = "use World::non_send")]2311pub fn non_send_resource<R: 'static>(&self) -> &R {2312self.non_send::<R>()2313}23142315/// Gets an immutable reference to the non-send data of the given type, if it exists.2316///2317/// # Panics2318///2319/// Panics if the data does not exist.2320/// Use [`get_non_send`](World::get_non_send) instead if you want to handle this case.2321///2322/// This function will panic if it isn't called from the same thread that the resource was inserted from.2323#[inline]2324#[track_caller]2325pub fn non_send<R: 'static>(&self) -> &R {2326match self.get_non_send() {2327Some(x) => x,2328None => panic!(2329"Requested non-send resource {} does not exist in the `World`.2330Did you forget to add it using `app.insert_non_send` / `app.init_non_send`?2331Non-send resources can also be added by plugins.",2332DebugName::type_name::<R>()2333),2334}2335}23362337/// Gets a mutable reference to a non-send resource of the given type, if it exists.2338#[deprecated(since = "0.19.0", note = "use World::non_send_mut")]2339pub fn non_send_resource_mut<R: 'static>(&mut self) -> Mut<'_, R> {2340self.non_send_mut::<R>()2341}23422343/// Gets a mutable reference to the non-send data of the given type, if it exists.2344///2345/// # Panics2346///2347/// Panics if the data does not exist.2348/// Use [`get_non_send_mut`](World::get_non_send_mut) instead if you want to handle this case.2349///2350/// This function will panic if it isn't called from the same thread that the resource was inserted from.2351#[inline]2352#[track_caller]2353pub fn non_send_mut<R: 'static>(&mut self) -> Mut<'_, R> {2354match self.get_non_send_mut() {2355Some(x) => x,2356None => panic!(2357"Requested non-send resource {} does not exist in the `World`.2358Did you forget to add it using `app.insert_non_send` / `app.init_non_send`?2359Non-send resources can also be added by plugins.",2360DebugName::type_name::<R>()2361),2362}2363}23642365/// Gets a reference to a non-send resource of the given type, if it exists.2366/// Otherwise returns `None`.2367#[deprecated(since = "0.19.0", note = "use World::get_non_send")]2368pub fn get_non_send_resource<R: 'static>(&self) -> Option<&R> {2369self.get_non_send::<R>()2370}23712372/// Gets a reference to the non-send data of the given type, if it exists.2373/// Otherwise returns `None`.2374///2375/// # Panics2376/// This function will panic if it isn't called from the same thread that the resource was inserted from.2377#[inline]2378pub fn get_non_send<R: 'static>(&self) -> Option<&R> {2379// SAFETY:2380// - `as_unsafe_world_cell_readonly` gives permission to access the entire world immutably2381// - `&self` ensures that there are no mutable borrows of world data2382unsafe { self.as_unsafe_world_cell_readonly().get_non_send() }2383}23842385/// Gets a mutable reference to a non-send resource of the given type, if it exists.2386/// Otherwise returns `None`.2387#[deprecated(since = "0.19.0", note = "use World::get_non_send_mut")]2388pub fn get_non_send_resource_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {2389self.get_non_send_mut::<R>()2390}23912392/// Gets a mutable reference to the non-send data of the given type, if it exists.2393/// Otherwise returns `None`.2394///2395/// # Panics2396/// This function will panic if it isn't called from the same thread that the resource was inserted from.2397#[inline]2398pub fn get_non_send_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {2399// SAFETY:2400// - `as_unsafe_world_cell` gives permission to access the entire world mutably2401// - `&mut self` ensures that there are no borrows of world data2402unsafe { self.as_unsafe_world_cell().get_non_send_mut() }2403}24042405/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2406/// adds the `Bundle` of components to each `Entity`.2407/// This is faster than doing equivalent operations one-by-one.2408///2409/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2410/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2411///2412/// This will overwrite any previous values of components shared by the `Bundle`.2413/// See [`World::insert_batch_if_new`] to keep the old values instead.2414///2415/// # Panics2416///2417/// This function will panic if any of the associated entities do not exist.2418///2419/// For the fallible version, see [`World::try_insert_batch`].2420#[track_caller]2421pub fn insert_batch<I, B>(&mut self, batch: I)2422where2423I: IntoIterator,2424I::IntoIter: Iterator<Item = (Entity, B)>,2425B: Bundle<Effect: NoBundleEffect>,2426{2427self.insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller());2428}24292430/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2431/// adds the `Bundle` of components to each `Entity` without overwriting.2432/// This is faster than doing equivalent operations one-by-one.2433///2434/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2435/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2436///2437/// This is the same as [`World::insert_batch`], but in case of duplicate2438/// components it will leave the old values instead of replacing them with new ones.2439///2440/// # Panics2441///2442/// This function will panic if any of the associated entities do not exist.2443///2444/// For the fallible version, see [`World::try_insert_batch_if_new`].2445#[track_caller]2446pub fn insert_batch_if_new<I, B>(&mut self, batch: I)2447where2448I: IntoIterator,2449I::IntoIter: Iterator<Item = (Entity, B)>,2450B: Bundle<Effect: NoBundleEffect>,2451{2452self.insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller());2453}24542455/// Split into a new function so we can differentiate the calling location.2456///2457/// This can be called by:2458/// - [`World::insert_batch`]2459/// - [`World::insert_batch_if_new`]2460#[inline]2461pub(crate) fn insert_batch_with_caller<I, B>(2462&mut self,2463batch: I,2464insert_mode: InsertMode,2465caller: MaybeLocation,2466) where2467I: IntoIterator,2468I::IntoIter: Iterator<Item = (Entity, B)>,2469B: Bundle<Effect: NoBundleEffect>,2470{2471struct InserterArchetypeCache<'w> {2472inserter: BundleInserter<'w>,2473archetype_id: ArchetypeId,2474}24752476let change_tick = self.change_tick();2477let bundle_id = self.register_bundle_info::<B>();24782479let mut batch_iter = batch.into_iter();24802481if let Some((first_entity, first_bundle)) = batch_iter.next() {2482match self.entities().get_spawned(first_entity) {2483Err(err) => {2484panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {first_entity} because: {err}. See: https://bevyengine.org/learn/errors/b0003", core::any::type_name::<B>());2485}2486Ok(first_location) => {2487let mut cache = InserterArchetypeCache {2488// SAFETY: we initialized this bundle_id in `register_info`2489inserter: unsafe {2490BundleInserter::new_with_id(2491self,2492first_location.archetype_id,2493bundle_id,2494change_tick,2495)2496},2497archetype_id: first_location.archetype_id,2498};2499move_as_ptr!(first_bundle);2500// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2501unsafe {2502cache.inserter.insert(2503first_entity,2504first_location,2505first_bundle,2506insert_mode,2507caller,2508RelationshipHookMode::Run,2509)2510};25112512for (entity, bundle) in batch_iter {2513match cache.inserter.entities().get_spawned(entity) {2514Ok(location) => {2515if location.archetype_id != cache.archetype_id {2516cache = InserterArchetypeCache {2517// SAFETY: we initialized this bundle_id in `register_info`2518inserter: unsafe {2519BundleInserter::new_with_id(2520self,2521location.archetype_id,2522bundle_id,2523change_tick,2524)2525},2526archetype_id: location.archetype_id,2527}2528}2529move_as_ptr!(bundle);2530// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2531unsafe {2532cache.inserter.insert(2533entity,2534location,2535bundle,2536insert_mode,2537caller,2538RelationshipHookMode::Run,2539)2540};2541}2542Err(err) => {2543panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {entity} because: {err}. See: https://bevyengine.org/learn/errors/b0003", core::any::type_name::<B>());2544}2545}2546}2547}2548}2549}2550}25512552/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2553/// adds the `Bundle` of components to each `Entity`.2554/// This is faster than doing equivalent operations one-by-one.2555///2556/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2557/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2558///2559/// This will overwrite any previous values of components shared by the `Bundle`.2560/// See [`World::try_insert_batch_if_new`] to keep the old values instead.2561///2562/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2563///2564/// For the panicking version, see [`World::insert_batch`].2565#[track_caller]2566pub fn try_insert_batch<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2567where2568I: IntoIterator,2569I::IntoIter: Iterator<Item = (Entity, B)>,2570B: Bundle<Effect: NoBundleEffect>,2571{2572self.try_insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller())2573}2574/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2575/// adds the `Bundle` of components to each `Entity` without overwriting.2576/// This is faster than doing equivalent operations one-by-one.2577///2578/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2579/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2580///2581/// This is the same as [`World::try_insert_batch`], but in case of duplicate2582/// components it will leave the old values instead of replacing them with new ones.2583///2584/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2585///2586/// For the panicking version, see [`World::insert_batch_if_new`].2587#[track_caller]2588pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2589where2590I: IntoIterator,2591I::IntoIter: Iterator<Item = (Entity, B)>,2592B: Bundle<Effect: NoBundleEffect>,2593{2594self.try_insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller())2595}25962597/// Split into a new function so we can differentiate the calling location.2598///2599/// This can be called by:2600/// - [`World::try_insert_batch`]2601/// - [`World::try_insert_batch_if_new`]2602/// - [`Commands::insert_batch`]2603/// - [`Commands::insert_batch_if_new`]2604/// - [`Commands::try_insert_batch`]2605/// - [`Commands::try_insert_batch_if_new`]2606#[inline]2607pub(crate) fn try_insert_batch_with_caller<I, B>(2608&mut self,2609batch: I,2610insert_mode: InsertMode,2611caller: MaybeLocation,2612) -> Result<(), TryInsertBatchError>2613where2614I: IntoIterator,2615I::IntoIter: Iterator<Item = (Entity, B)>,2616B: Bundle<Effect: NoBundleEffect>,2617{2618struct InserterArchetypeCache<'w> {2619inserter: BundleInserter<'w>,2620archetype_id: ArchetypeId,2621}26222623let change_tick = self.change_tick();2624let bundle_id = self.register_bundle_info::<B>();26252626let mut invalid_entities = Vec::<Entity>::new();2627let mut batch_iter = batch.into_iter();26282629// We need to find the first valid entity so we can initialize the bundle inserter.2630// This differs from `insert_batch_with_caller` because that method can just panic2631// if the first entity is invalid, whereas this method needs to keep going.2632let cache = loop {2633if let Some((first_entity, first_bundle)) = batch_iter.next() {2634if let Ok(first_location) = self.entities().get_spawned(first_entity) {2635let mut cache = InserterArchetypeCache {2636// SAFETY: we initialized this bundle_id in `register_bundle_info`2637inserter: unsafe {2638BundleInserter::new_with_id(2639self,2640first_location.archetype_id,2641bundle_id,2642change_tick,2643)2644},2645archetype_id: first_location.archetype_id,2646};26472648move_as_ptr!(first_bundle);2649// SAFETY:2650// - `entity` is valid, `location` matches entity, bundle matches inserter2651// - `apply_effect` is never called on this bundle.2652// - `first_bundle` is not be accessed or dropped after this.2653unsafe {2654cache.inserter.insert(2655first_entity,2656first_location,2657first_bundle,2658insert_mode,2659caller,2660RelationshipHookMode::Run,2661)2662};2663break Some(cache);2664}2665invalid_entities.push(first_entity);2666} else {2667// We reached the end of the entities the caller provided and none were valid.2668break None;2669}2670};26712672if let Some(mut cache) = cache {2673for (entity, bundle) in batch_iter {2674if let Ok(location) = cache.inserter.entities().get_spawned(entity) {2675if location.archetype_id != cache.archetype_id {2676cache = InserterArchetypeCache {2677// SAFETY: we initialized this bundle_id in `register_info`2678inserter: unsafe {2679BundleInserter::new_with_id(2680self,2681location.archetype_id,2682bundle_id,2683change_tick,2684)2685},2686archetype_id: location.archetype_id,2687}2688}26892690move_as_ptr!(bundle);2691// SAFETY:2692// - `entity` is valid, `location` matches entity, bundle matches inserter2693// - `apply_effect` is never called on this bundle.2694// - `bundle` is not be accessed or dropped after this.2695unsafe {2696cache.inserter.insert(2697entity,2698location,2699bundle,2700insert_mode,2701caller,2702RelationshipHookMode::Run,2703)2704};2705} else {2706invalid_entities.push(entity);2707}2708}2709}27102711if invalid_entities.is_empty() {2712Ok(())2713} else {2714Err(TryInsertBatchError {2715bundle_type: DebugName::type_name::<B>(),2716entities: invalid_entities,2717})2718}2719}27202721/// Temporarily removes the requested resource from this [`World`], runs custom user code,2722/// then re-adds the resource before returning.2723///2724/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2725/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2726///2727/// # Panics2728///2729/// Panics if the resource does not exist.2730/// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.2731///2732/// # Example2733/// ```2734/// use bevy_ecs::prelude::*;2735/// #[derive(Resource)]2736/// struct A(u32);2737/// #[derive(Component)]2738/// struct B(u32);2739/// let mut world = World::new();2740/// world.insert_resource(A(1));2741/// let entity = world.spawn(B(1)).id();2742///2743/// world.resource_scope(|world, mut a: Mut<A>| {2744/// let b = world.get_mut::<B>(entity).unwrap();2745/// a.0 += b.0;2746/// });2747/// assert_eq!(world.get_resource::<A>().unwrap().0, 2);2748/// ```2749///2750/// # Note2751///2752/// If the world's resource metadata is cleared within the scope, such as by calling2753/// [`World::clear_resources`] or [`World::clear_all`], the resource will *not* be re-inserted2754/// at the end of the scope.2755#[track_caller]2756pub fn resource_scope<R: Resource, U>(&mut self, f: impl FnOnce(&mut World, Mut<R>) -> U) -> U {2757self.try_resource_scope(f)2758.unwrap_or_else(|| panic!("resource does not exist: {}", DebugName::type_name::<R>()))2759}27602761/// Temporarily removes the requested resource from this [`World`] if it exists, runs custom user code,2762/// then re-adds the resource before returning. Returns `None` if the resource does not exist in this [`World`].2763///2764/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2765/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2766///2767/// See also [`resource_scope`](Self::resource_scope).2768///2769/// # Note2770///2771/// If the world's resource metadata is cleared within the scope, such as by calling2772/// [`World::clear_resources`] or [`World::clear_all`], the resource will *not* be re-inserted2773/// at the end of the scope.2774pub fn try_resource_scope<R: Resource, U>(2775&mut self,2776f: impl FnOnce(&mut World, Mut<R>) -> U,2777) -> Option<U> {2778let last_change_tick = self.last_change_tick();2779let change_tick = self.change_tick();27802781let component_id = self.components.valid_resource_id::<R>()?;2782let entity = *self.resource_entities.get(component_id)?;2783let mut entity_mut = self.get_entity_mut(entity).ok()?;27842785let mut ticks = entity_mut.get_change_ticks::<R>()?;2786let mut changed_by = entity_mut.get_changed_by::<R>()?;2787let value = entity_mut.take::<R>()?;27882789// type used to manage reinserting the resource at the end of the scope. use of a drop impl means that2790// the resource is inserted even if the user-provided closure unwinds.2791// this facilitates localized panic recovery and makes app shutdown in response to a panic more graceful2792// by avoiding knock-on errors.2793struct ReinsertGuard<'a, R: Resource> {2794world: &'a mut World,2795entity: Entity,2796component_id: ComponentId,2797value: ManuallyDrop<R>,2798ticks: ComponentTicks,2799caller: MaybeLocation,2800}2801impl<R: Resource> Drop for ReinsertGuard<'_, R> {2802fn drop(&mut self) {2803// take ownership of the value first so it'll get dropped if we return early2804// SAFETY: drop semantics ensure that `self.value` will never be accessed again after this call2805let value = unsafe { ManuallyDrop::take(&mut self.value) };28062807let Ok(mut entity_mut) = self.world.get_entity_mut(self.entity) else {2808return;2809};28102811// in debug mode, raise a panic if user code re-inserted a resource of this type within the scope.2812// resource insertion usually indicates a logic error in user code, which is useful to catch at dev time,2813// however it does not inherently lead to corrupted state, so we avoid introducing an unnecessary crash2814// for production builds.2815if entity_mut.contains_id(self.component_id) {2816#[cfg(debug_assertions)]2817{2818// if we're already panicking, log an error instead of panicking, as double-panics result in an abort2819#[cfg(feature = "std")]2820if std::thread::panicking() {2821log::error!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\2822In release builds, the value inserted will be overwritten at the end of the scope.",2823DebugName::type_name::<R>());2824// return early to maintain consistent behavior with non-panicking calls in debug builds2825return;2826}28272828panic!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\2829In release builds, the value inserted will be overwritten at the end of the scope.",2830DebugName::type_name::<R>());2831}2832#[cfg(not(debug_assertions))]2833{2834#[cold]2835#[inline(never)]2836fn warn_reinsert(resource_name: &str) {2837warn!(2838"Resource `{resource_name}` was inserted during a call to World::resource_scope: the inserted value will be overwritten.",2839);2840}28412842warn_reinsert(&DebugName::type_name::<R>());2843}2844}28452846move_as_ptr!(value);28472848// See EntityWorldMut::insert_with_caller for the original code.2849// This is copied here to update the change ticks. This way we can ensure that the commands2850// ran during self.flush(), interact with the correct ticks on the resource component.2851{2852let location = entity_mut.location();2853let mut bundle_inserter = BundleInserter::new::<R>(2854// SAFETY: We update the entity location like in EntityWorldMut::insert_with_caller2855unsafe { entity_mut.world_mut() },2856location.archetype_id,2857self.ticks.changed,2858);2859// SAFETY:2860// - `location` matches current entity and thus must currently exist in the source2861// archetype for this inserter and its location within the archetype.2862// - `T` matches the type used to create the `BundleInserter`.2863// - `apply_effect` is called exactly once after this function.2864// - The value pointed at by `bundle` is not accessed for anything other than `apply_effect`2865// and the caller ensures that the value is not accessed or dropped after this function2866// returns.2867let (bundle, _) = value.partial_move(|bundle| unsafe {2868bundle_inserter.insert(2869self.entity,2870location,2871bundle,2872InsertMode::Replace,2873self.caller,2874RelationshipHookMode::Run,2875)2876});2877entity_mut.update_location();28782879// Set the added tick to the original.2880entity_mut2881.get_mut::<R>()2882.unwrap()2883.set_last_added(self.ticks.added);28842885// SAFETY: We update the entity location afterwards.2886unsafe { entity_mut.world_mut() }.flush();28872888entity_mut.update_location();2889// SAFETY:2890// - This is called exactly once after the `BundleInsert::insert` call before returning to safe code.2891// - `bundle` points to the same `B` that `BundleInsert::insert` was called on.2892unsafe { R::apply_effect(bundle, &mut entity_mut) };2893}2894}2895}28962897let mut guard = ReinsertGuard {2898world: self,2899entity,2900component_id,2901value: ManuallyDrop::new(value),2902ticks,2903caller: changed_by,2904};29052906let value_mut = Mut {2907value: &mut *guard.value,2908ticks: ComponentTicksMut {2909added: &mut ticks.added,2910changed: &mut ticks.changed,2911changed_by: changed_by.as_mut(),2912last_run: last_change_tick,2913this_run: change_tick,2914},2915};29162917let result = f(guard.world, value_mut);29182919Some(result)2920}29212922/// Writes a [`Message`].2923/// This method returns the [`MessageId`] of the written `message`,2924/// or [`None`] if the `message` could not be written.2925#[inline]2926pub fn write_message<M: Message>(&mut self, message: M) -> Option<MessageId<M>> {2927self.write_message_batch(core::iter::once(message))?.next()2928}29292930/// Writes the default value of the [`Message`] of type `M`.2931/// This method returns the [`MessageId`] of the written message,2932/// or [`None`] if the `event` could not be written.2933#[inline]2934pub fn write_message_default<M: Message + Default>(&mut self) -> Option<MessageId<M>> {2935self.write_message(M::default())2936}29372938/// Writes a batch of [`Message`]s from an iterator.2939/// This method returns the [IDs](`MessageId`) of the written `messages`,2940/// or [`None`] if the `events` could not be written.2941#[inline]2942pub fn write_message_batch<M: Message>(2943&mut self,2944messages: impl IntoIterator<Item = M>,2945) -> Option<WriteBatchIds<M>> {2946let Some(mut events_resource) = self.get_resource_mut::<Messages<M>>() else {2947log::error!(2948"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 ",2949DebugName::type_name::<M>()2950);2951return None;2952};2953Some(events_resource.write_batch(messages))2954}29552956/// Inserts a new resource with the given `value`. Will replace the value if it already existed.2957///2958/// **You should prefer to use the typed API [`World::insert_resource`] where possible and only2959/// use this in cases where the actual types are not known at compile time.**2960///2961/// # Safety2962/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.2963#[inline]2964#[track_caller]2965pub unsafe fn insert_resource_by_id(2966&mut self,2967component_id: ComponentId,2968value: OwningPtr<'_>,2969caller: MaybeLocation,2970) {2971// if the resource already exists, we replace it on the same entity2972let mut entity_mut = if let Some(entity) = self.resource_entities.get(component_id) {2973self.get_entity_mut(*entity)2974.expect("ResourceCache is in sync")2975} else {2976self.spawn_empty()2977};2978entity_mut.insert_by_id_with_caller(2979component_id,2980value,2981InsertMode::Replace,2982caller,2983RelationshipHookMode::Run,2984);2985}29862987/// Inserts new `!Send` data with the given `value`. Will replace the value if it already2988/// existed.2989///2990/// **You should prefer to use the typed API [`World::insert_non_send`] where possible and only2991/// use this in cases where the actual types are not known at compile time.**2992///2993/// # Panics2994/// If a value is already present, this function will panic if not called from the same2995/// thread that the original value was inserted from.2996///2997/// # Safety2998/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.2999#[inline]3000#[track_caller]3001pub unsafe fn insert_non_send_by_id(3002&mut self,3003component_id: ComponentId,3004value: OwningPtr<'_>,3005caller: MaybeLocation,3006) {3007let change_tick = self.change_tick();30083009let resource = self.initialize_non_send_internal(component_id);3010// SAFETY: `value` is valid for `component_id`, ensured by caller3011unsafe {3012resource.insert(value, change_tick, caller);3013}3014}30153016/// # Panics3017/// Panics if `component_id` is not registered in this world3018#[inline]3019pub(crate) fn initialize_non_send_internal(3020&mut self,3021component_id: ComponentId,3022) -> &mut NonSendData {3023self.flush_components();3024self.storages3025.non_sends3026.initialize_with(component_id, &self.components)3027}30283029/// Applies any commands in the world's internal [`CommandQueue`].3030/// This does not apply commands from any systems, only those stored in the world.3031///3032/// # Panics3033/// This will panic if any of the queued commands are [`spawn`](Commands::spawn).3034/// If this is possible, you should instead use [`flush`](Self::flush).3035pub(crate) fn flush_commands(&mut self) {3036// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`3037if !unsafe { self.command_queue.is_empty() } {3038// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`3039unsafe {3040self.command_queue3041.clone()3042.apply_or_drop_queued(Some(self.into()));3043};3044}3045}30463047/// Applies any queued component registration.3048/// For spawning vanilla rust component types and resources, this is not strictly necessary.3049/// However, flushing components can make information available more quickly, and can have performance benefits.3050/// Additionally, for components and resources registered dynamically through a raw descriptor or similar,3051/// this is the only way to complete their registration.3052pub(crate) fn flush_components(&mut self) {3053self.components_registrator().apply_queued_registrations();3054}30553056/// Flushes queued entities and commands.3057///3058/// Queued entities will be spawned, and then commands will be applied.3059#[inline]3060#[track_caller]3061pub fn flush(&mut self) {3062self.flush_components();3063self.flush_commands();3064}30653066/// Increments the world's current change tick and returns the old value.3067///3068/// If you need to call this method, but do not have `&mut` access to the world,3069/// consider using [`as_unsafe_world_cell_readonly`](Self::as_unsafe_world_cell_readonly)3070/// to obtain an [`UnsafeWorldCell`] and calling [`increment_change_tick`](UnsafeWorldCell::increment_change_tick) on that.3071/// Note that this *can* be done in safe code, despite the name of the type.3072#[inline]3073pub fn increment_change_tick(&mut self) -> Tick {3074let change_tick = self.change_tick.get_mut();3075let prev_tick = *change_tick;3076*change_tick = change_tick.wrapping_add(1);3077Tick::new(prev_tick)3078}30793080/// Reads the current change tick of this world.3081///3082/// If you have exclusive (`&mut`) access to the world, consider using [`change_tick()`](Self::change_tick),3083/// which is more efficient since it does not require atomic synchronization.3084#[inline]3085pub fn read_change_tick(&self) -> Tick {3086let tick = self.change_tick.load(Ordering::Acquire);3087Tick::new(tick)3088}30893090/// Reads the current change tick of this world.3091///3092/// This does the same thing as [`read_change_tick()`](Self::read_change_tick), only this method3093/// is more efficient since it does not require atomic synchronization.3094#[inline]3095pub fn change_tick(&mut self) -> Tick {3096let tick = *self.change_tick.get_mut();3097Tick::new(tick)3098}30993100/// When called from within an exclusive system (a [`System`] that takes `&mut World` as its first3101/// parameter), this method returns the [`Tick`] indicating the last time the exclusive system was run.3102///3103/// Otherwise, this returns the `Tick` indicating the last time that [`World::clear_trackers`] was called.3104///3105/// [`System`]: crate::system::System3106#[inline]3107pub fn last_change_tick(&self) -> Tick {3108self.last_change_tick3109}31103111/// Returns the id of the last ECS event that was fired.3112/// Used internally to ensure observers don't trigger multiple times for the same event.3113#[inline]3114pub(crate) fn last_trigger_id(&self) -> u32 {3115self.last_trigger_id3116}31173118/// Sets [`World::last_change_tick()`] to the specified value during a scope.3119/// When the scope terminates, it will return to its old value.3120///3121/// This is useful if you need a region of code to be able to react to earlier changes made in the same system.3122///3123/// # Examples3124///3125/// ```3126/// # use bevy_ecs::prelude::*;3127/// // This function runs an update loop repeatedly, allowing each iteration of the loop3128/// // to react to changes made in the previous loop iteration.3129/// fn update_loop(3130/// world: &mut World,3131/// mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,3132/// ) {3133/// let mut last_change_tick = world.last_change_tick();3134///3135/// // Repeatedly run the update function until it requests a break.3136/// loop {3137/// let control_flow = world.last_change_tick_scope(last_change_tick, |world| {3138/// // Increment the change tick so we can detect changes from the previous update.3139/// last_change_tick = world.change_tick();3140/// world.increment_change_tick();3141///3142/// // Update once.3143/// update_fn(world)3144/// });3145///3146/// // End the loop when the closure returns `ControlFlow::Break`.3147/// if control_flow.is_break() {3148/// break;3149/// }3150/// }3151/// }3152/// #3153/// # #[derive(Resource)] struct Count(u32);3154/// # let mut world = World::new();3155/// # world.insert_resource(Count(0));3156/// # let saved_last_tick = world.last_change_tick();3157/// # let mut num_updates = 0;3158/// # update_loop(&mut world, |world| {3159/// # let mut c = world.resource_mut::<Count>();3160/// # match c.0 {3161/// # 0 => {3162/// # assert_eq!(num_updates, 0);3163/// # assert!(c.is_added());3164/// # c.0 = 1;3165/// # }3166/// # 1 => {3167/// # assert_eq!(num_updates, 1);3168/// # assert!(!c.is_added());3169/// # assert!(c.is_changed());3170/// # c.0 = 2;3171/// # }3172/// # 2 if c.is_changed() => {3173/// # assert_eq!(num_updates, 2);3174/// # assert!(!c.is_added());3175/// # }3176/// # 2 => {3177/// # assert_eq!(num_updates, 3);3178/// # assert!(!c.is_changed());3179/// # world.remove_resource::<Count>();3180/// # world.insert_resource(Count(3));3181/// # }3182/// # 3 if c.is_changed() => {3183/// # assert_eq!(num_updates, 4);3184/// # assert!(c.is_added());3185/// # }3186/// # 3 => {3187/// # assert_eq!(num_updates, 5);3188/// # assert!(!c.is_added());3189/// # c.0 = 4;3190/// # return std::ops::ControlFlow::Break(());3191/// # }3192/// # _ => unreachable!(),3193/// # }3194/// # num_updates += 1;3195/// # std::ops::ControlFlow::Continue(())3196/// # });3197/// # assert_eq!(num_updates, 5);3198/// # assert_eq!(world.resource::<Count>().0, 4);3199/// # assert_eq!(world.last_change_tick(), saved_last_tick);3200/// ```3201pub fn last_change_tick_scope<T>(3202&mut self,3203last_change_tick: Tick,3204f: impl FnOnce(&mut World) -> T,3205) -> T {3206struct LastTickGuard<'a> {3207world: &'a mut World,3208last_tick: Tick,3209}32103211// By setting the change tick in the drop impl, we ensure that3212// the change tick gets reset even if a panic occurs during the scope.3213impl Drop for LastTickGuard<'_> {3214fn drop(&mut self) {3215self.world.last_change_tick = self.last_tick;3216}3217}32183219let guard = LastTickGuard {3220last_tick: self.last_change_tick,3221world: self,3222};32233224guard.world.last_change_tick = last_change_tick;32253226f(guard.world)3227}32283229/// Iterates all component change ticks and clamps any older than [`MAX_CHANGE_AGE`](crate::change_detection::MAX_CHANGE_AGE).3230/// This also triggers [`CheckChangeTicks`] observers and returns the same event here.3231///3232/// Calling this method prevents [`Tick`]s overflowing and thus prevents false positives when comparing them.3233///3234/// **Note:** Does nothing and returns `None` if the [`World`] counter has not been incremented at least [`CHECK_TICK_THRESHOLD`]3235/// times since the previous pass.3236// TODO: benchmark and optimize3237pub fn check_change_ticks(&mut self) -> Option<CheckChangeTicks> {3238let change_tick = self.change_tick();3239if change_tick.relative_to(self.last_check_tick).get() < CHECK_TICK_THRESHOLD {3240return None;3241}32423243let check = CheckChangeTicks(change_tick);32443245let Storages {3246ref mut tables,3247ref mut sparse_sets,3248ref mut non_sends,3249} = self.storages;32503251#[cfg(feature = "trace")]3252let _span = tracing::info_span!("check component ticks").entered();3253tables.check_change_ticks(check);3254sparse_sets.check_change_ticks(check);3255non_sends.check_change_ticks(check);3256self.entities.check_change_ticks(check);32573258if let Some(mut schedules) = self.get_resource_mut::<Schedules>() {3259schedules.check_change_ticks(check);3260}32613262self.trigger(check);3263self.flush();32643265self.last_check_tick = change_tick;32663267Some(check)3268}32693270/// Clears all entities and resources, invalidating all [`Entity`] and resource fetches3271/// such as [`Res`](crate::system::Res), [`ResMut`](crate::system::ResMut)3272///3273/// Since resources are entities, this is identical to [`clear_entities`](Self::clear_entities).3274/// Non-send data is not cleared.3275pub fn clear_all(&mut self) {3276self.clear_entities();3277}32783279/// Despawns all entities in this [`World`].3280///3281/// **Note:** This includes all resources, as they are stored as components.3282/// Any resource fetch to this [`World`] will fail unless they are re-initialized,3283/// including engine-internal resources that are only initialized on app/world construction.3284///3285/// This can easily cause systems expecting certain resources to immediately start panicking.3286/// Use with caution.3287pub fn clear_entities(&mut self) {3288self.storages.tables.clear();3289self.storages.sparse_sets.clear_entities();3290self.archetypes.clear_entities();3291self.entities.clear();3292self.entity_allocator.restart();3293}32943295/// Clears all resources in this [`World`].3296///3297/// **Note:** Any resource fetch to this [`World`] will fail unless they are re-initialized,3298/// including engine-internal resources that are only initialized on app/world construction.3299///3300/// This can easily cause systems expecting certain resources to immediately start panicking.3301/// Use with caution.3302pub fn clear_resources(&mut self) {3303let pairs: Vec<(ComponentId, Entity)> = self3304.resource_entities()3305.iter()3306.map(|(id, entity)| (*id, *entity))3307.collect();3308for (component_id, entity) in pairs {3309self.entity_mut(entity).remove_by_id(component_id);3310}3311}33123313/// Clears all non-send data in this [`World`].3314pub fn clear_non_send(&mut self) {3315self.storages.non_sends.clear();3316}33173318/// Registers all of the components in the given [`Bundle`] and returns both the component3319/// ids and the bundle id.3320///3321/// This is largely equivalent to calling [`register_component`](Self::register_component) on each3322/// component in the bundle.3323#[inline]3324pub fn register_bundle<B: Bundle>(&mut self) -> &BundleInfo {3325let id = self.register_bundle_info::<B>();33263327// SAFETY: We just initialized the bundle so its id should definitely be valid.3328unsafe { self.bundles.get(id).debug_checked_unwrap() }3329}33303331pub(crate) fn register_bundle_info<B: Bundle>(&mut self) -> BundleId {3332// SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.3333let mut registrator =3334unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };33353336// SAFETY: `registrator`, `self.storages` and `self.bundles` all come from this world.3337unsafe {3338self.bundles3339.register_info::<B>(&mut registrator, &mut self.storages)3340}3341}33423343pub(crate) fn register_contributed_bundle_info<B: Bundle>(&mut self) -> BundleId {3344// SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.3345let mut registrator =3346unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };33473348// SAFETY: `registrator`, `self.bundles` and `self.storages` are all from this world.3349unsafe {3350self.bundles3351.register_contributed_bundle_info::<B>(&mut registrator, &mut self.storages)3352}3353}33543355/// Registers the given [`ComponentId`]s as a dynamic bundle and returns both the required component ids and the bundle id.3356///3357/// Note that the components need to be registered first, this function only creates a bundle combining them. Components3358/// can be registered with [`World::register_component`]/[`_with_descriptor`](World::register_component_with_descriptor).3359///3360/// **You should prefer to use the typed API [`World::register_bundle`] where possible and only use this in cases where3361/// not all of the actual types are known at compile time.**3362///3363/// # Panics3364/// This function will panic if any of the provided component ids do not belong to a component known to this [`World`].3365#[inline]3366pub fn register_dynamic_bundle(&mut self, component_ids: &[ComponentId]) -> &BundleInfo {3367let id =3368self.bundles3369.init_dynamic_info(&mut self.storages, &self.components, component_ids);3370// SAFETY: We just initialized the bundle so its id should definitely be valid.3371unsafe { self.bundles.get(id).debug_checked_unwrap() }3372}33733374/// Convenience method for accessing the world's default error handler,3375/// which can be overwritten with [`DefaultErrorHandler`].3376#[inline]3377pub fn default_error_handler(&self) -> ErrorHandler {3378self.get_resource::<DefaultErrorHandler>()3379.copied()3380.unwrap_or_default()3381.03382}3383}33843385impl World {3386/// Gets a pointer to the resource with the id [`ComponentId`] if it exists.3387/// The returned pointer must not be used to modify the resource, and must not be3388/// dereferenced after the immutable borrow of the [`World`] ends.3389///3390/// **You should prefer to use the typed API [`World::get_resource`] where possible and only3391/// use this in cases where the actual types are not known at compile time.**3392#[inline]3393pub fn get_resource_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {3394// SAFETY:3395// - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably3396// - `&self` ensures there are no mutable borrows on world data3397unsafe {3398self.as_unsafe_world_cell_readonly()3399.get_resource_by_id(component_id)3400}3401}34023403/// Gets a pointer to the resource with the id [`ComponentId`] if it exists.3404/// The returned pointer may be used to modify the resource, as long as the mutable borrow3405/// of the [`World`] is still valid.3406///3407/// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only3408/// use this in cases where the actual types are not known at compile time.**3409#[inline]3410pub fn get_resource_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {3411// SAFETY:3412// - `&mut self` ensures that all accessed data is unaliased3413// - `as_unsafe_world_cell` provides mutable permission to the whole world3414unsafe {3415self.as_unsafe_world_cell()3416.get_resource_mut_by_id(component_id)3417}3418}34193420/// Iterates over all resources in the world.3421///3422/// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading the contents3423/// of each resource will require the use of unsafe code.3424///3425/// # Examples3426///3427/// ## Printing the size of all resources3428///3429/// ```3430/// # use bevy_ecs::prelude::*;3431/// # #[derive(Resource)]3432/// # struct A(u32);3433/// # #[derive(Resource)]3434/// # struct B(u32);3435/// #3436/// # let mut world = World::new();3437/// # world.remove_resource::<bevy_ecs::entity_disabling::DefaultQueryFilters>();3438/// # world.insert_resource(A(1));3439/// # world.insert_resource(B(2));3440/// let mut total = 0;3441/// for (info, _) in world.iter_resources() {3442/// println!("Resource: {}", info.name());3443/// println!("Size: {} bytes", info.layout().size());3444/// total += info.layout().size();3445/// }3446/// println!("Total size: {} bytes", total);3447/// # assert_eq!(total, size_of::<A>() + size_of::<B>());3448/// ```3449///3450/// ## Dynamically running closures for resources matching specific `TypeId`s3451///3452/// ```3453/// # use bevy_ecs::prelude::*;3454/// # use std::collections::HashMap;3455/// # use std::any::TypeId;3456/// # use bevy_ptr::Ptr;3457/// # #[derive(Resource)]3458/// # struct A(u32);3459/// # #[derive(Resource)]3460/// # struct B(u32);3461/// #3462/// # let mut world = World::new();3463/// # world.insert_resource(A(1));3464/// # world.insert_resource(B(2));3465/// #3466/// // In this example, `A` and `B` are resources. We deliberately do not use the3467/// // `bevy_reflect` crate here to showcase the low-level [`Ptr`] usage. You should3468/// // probably use something like `ReflectFromPtr` in a real-world scenario.3469///3470/// // Create the hash map that will store the closures for each resource type3471/// let mut closures: HashMap<TypeId, Box<dyn Fn(&Ptr<'_>)>> = HashMap::default();3472///3473/// // Add closure for `A`3474/// closures.insert(TypeId::of::<A>(), Box::new(|ptr| {3475/// // SAFETY: We assert ptr is the same type of A with TypeId of A3476/// let a = unsafe { &ptr.deref::<A>() };3477/// # assert_eq!(a.0, 1);3478/// // ... do something with `a` here3479/// }));3480///3481/// // Add closure for `B`3482/// closures.insert(TypeId::of::<B>(), Box::new(|ptr| {3483/// // SAFETY: We assert ptr is the same type of B with TypeId of B3484/// let b = unsafe { &ptr.deref::<B>() };3485/// # assert_eq!(b.0, 2);3486/// // ... do something with `b` here3487/// }));3488///3489/// // Iterate all resources, in order to run the closures for each matching resource type3490/// for (info, ptr) in world.iter_resources() {3491/// let Some(type_id) = info.type_id() else {3492/// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources3493/// // dynamically inserted via a scripting language) in which case we can't match them.3494/// continue;3495/// };3496///3497/// let Some(closure) = closures.get(&type_id) else {3498/// // No closure for this resource type, skip it.3499/// continue;3500/// };3501///3502/// // Run the closure for the resource3503/// closure(&ptr);3504/// }3505/// ```3506#[inline]3507pub fn iter_resources(&self) -> impl Iterator<Item = (&ComponentInfo, Ptr<'_>)> {3508self.resource_entities3509.indices()3510.iter()3511.filter_map(|component_id| {3512let component_info = self.components().get_info(*component_id)?;3513let resource = self.get_resource_by_id(*component_id)?;3514Some((component_info, resource))3515})3516}35173518/// Mutably iterates over all resources in the world.3519///3520/// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading from or writing3521/// to the contents of each resource will require the use of unsafe code.3522///3523/// # Example3524///3525/// ```3526/// # use bevy_ecs::prelude::*;3527/// # use bevy_ecs::change_detection::MutUntyped;3528/// # use std::collections::HashMap;3529/// # use std::any::TypeId;3530/// # #[derive(Resource)]3531/// # struct A(u32);3532/// # #[derive(Resource)]3533/// # struct B(u32);3534/// #3535/// # let mut world = World::new();3536/// # world.insert_resource(A(1));3537/// # world.insert_resource(B(2));3538/// #3539/// // In this example, `A` and `B` are resources. We deliberately do not use the3540/// // `bevy_reflect` crate here to showcase the low-level `MutUntyped` usage. You should3541/// // probably use something like `ReflectFromPtr` in a real-world scenario.3542///3543/// // Create the hash map that will store the mutator closures for each resource type3544/// let mut mutators: HashMap<TypeId, Box<dyn Fn(&mut MutUntyped<'_>)>> = HashMap::default();3545///3546/// // Add mutator closure for `A`3547/// mutators.insert(TypeId::of::<A>(), Box::new(|mut_untyped| {3548/// // Note: `MutUntyped::as_mut()` automatically marks the resource as changed3549/// // for ECS change detection, and gives us a `PtrMut` we can use to mutate the resource.3550/// // SAFETY: We assert ptr is the same type of A with TypeId of A3551/// let a = unsafe { &mut mut_untyped.as_mut().deref_mut::<A>() };3552/// # a.0 += 1;3553/// // ... mutate `a` here3554/// }));3555///3556/// // Add mutator closure for `B`3557/// mutators.insert(TypeId::of::<B>(), Box::new(|mut_untyped| {3558/// // SAFETY: We assert ptr is the same type of B with TypeId of B3559/// let b = unsafe { &mut mut_untyped.as_mut().deref_mut::<B>() };3560/// # b.0 += 1;3561/// // ... mutate `b` here3562/// }));3563///3564/// // Iterate all resources, in order to run the mutator closures for each matching resource type3565/// for (info, mut mut_untyped) in world.iter_resources_mut() {3566/// let Some(type_id) = info.type_id() else {3567/// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources3568/// // dynamically inserted via a scripting language) in which case we can't match them.3569/// continue;3570/// };3571///3572/// let Some(mutator) = mutators.get(&type_id) else {3573/// // No mutator closure for this resource type, skip it.3574/// continue;3575/// };3576///3577/// // Run the mutator closure for the resource3578/// mutator(&mut mut_untyped);3579/// }3580/// # assert_eq!(world.resource::<A>().0, 2);3581/// # assert_eq!(world.resource::<B>().0, 3);3582/// ```3583pub fn iter_resources_mut(&mut self) -> impl Iterator<Item = (&ComponentInfo, MutUntyped<'_>)> {3584let unsafe_world = self.as_unsafe_world_cell();3585// SAFETY: exclusive world access to all resources3586let resource_entities = unsafe { unsafe_world.resource_entities() };3587let components = unsafe_world.components();35883589resource_entities3590.iter()3591.map(|(component_id, entity)| (*component_id, *entity))3592.filter_map(move |(component_id, entity)| {3593// SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.3594let component_info =3595unsafe { components.get_info(component_id).debug_checked_unwrap() };35963597let entity_cell = unsafe_world.get_entity(entity).ok()?;35983599// SAFETY:3600// - We have exclusive world access3601// - `UnsafeEntityCell::get_mut_by_id` doesn't access components3602// or resource_entities mutably3603// - `resource_entities` doesn't contain duplicate entities, so3604// no duplicate references are created3605let mut_untyped = unsafe { entity_cell.get_mut_by_id(component_id).ok()? };36063607Some((component_info, mut_untyped))3608})3609}36103611/// Gets a pointer to `!Send` data with the id [`ComponentId`] if it exists.3612/// The returned pointer must not be used to modify the resource, and must not be3613/// dereferenced after the immutable borrow of the [`World`] ends.3614///3615/// **You should prefer to use the typed API [`World::get_non_send`] where possible and only3616/// use this in cases where the actual types are not known at compile time.**3617///3618/// # Panics3619/// This function will panic if it isn't called from the same thread that the data was inserted from.3620#[inline]3621pub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {3622// SAFETY:3623// - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably3624// - `&self` ensures there are no mutable borrows on world data3625unsafe {3626self.as_unsafe_world_cell_readonly()3627.get_non_send_by_id(component_id)3628}3629}36303631/// Gets mutable access to `!Send` data with the id [`ComponentId`] if it exists.3632/// The returned pointer may be used to modify the data, as long as the mutable borrow3633/// of the [`World`] is still valid.3634///3635/// **You should prefer to use the typed API [`World::get_non_send_mut`] where possible and only3636/// use this in cases where the actual types are not known at compile time.**3637///3638/// # Panics3639/// This function will panic if it isn't called from the same thread that the data was inserted from.3640#[inline]3641pub fn get_non_send_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {3642// SAFETY:3643// - `&mut self` ensures that all accessed data is unaliased3644// - `as_unsafe_world_cell` provides mutable permission to the whole world3645unsafe {3646self.as_unsafe_world_cell()3647.get_non_send_mut_by_id(component_id)3648}3649}36503651/// Removes the resource of a given type, if it exists.3652/// Returns `true` if the resource is successfully removed and `false` if3653/// the entity does not exist.3654///3655/// **You should prefer to use the typed API [`World::remove_resource`] where possible and only3656/// use this in cases where the actual types are not known at compile time.**3657pub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> bool {3658if let Some(entity) = self.resource_entities.remove(component_id)3659&& let Ok(mut entity_mut) = self.get_entity_mut(entity)3660&& entity_mut.contains_id(component_id)3661{3662entity_mut.remove_by_id(component_id);3663true3664} else {3665false3666}3667}36683669/// Removes the non-send data of a given type, if it exists. Otherwise returns `None`.3670///3671/// **You should prefer to use the typed API [`World::remove_non_send`] where possible and only3672/// use this in cases where the actual types are not known at compile time.**3673///3674/// # Panics3675/// This function will panic if it isn't called from the same thread that the data was inserted from.3676pub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()> {3677self.storages3678.non_sends3679.get_mut(component_id)?3680.remove_and_drop();3681Some(())3682}36833684/// Retrieves an immutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].3685/// Returns `None` if the `entity` does not have a [`Component`] of the given type.3686///3687/// **You should prefer to use the typed API [`World::get_mut`] where possible and only3688/// use this in cases where the actual types are not known at compile time.**3689///3690/// # Panics3691/// This function will panic if it isn't called from the same thread that the resource was inserted from.3692#[inline]3693pub fn get_by_id(&self, entity: Entity, component_id: ComponentId) -> Option<Ptr<'_>> {3694self.get_entity(entity).ok()?.get_by_id(component_id).ok()3695}36963697/// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].3698/// Returns `None` if the `entity` does not have a [`Component`] of the given type.3699///3700/// **You should prefer to use the typed API [`World::get_mut`] where possible and only3701/// use this in cases where the actual types are not known at compile time.**3702#[inline]3703pub fn get_mut_by_id(3704&mut self,3705entity: Entity,3706component_id: ComponentId,3707) -> Option<MutUntyped<'_>> {3708self.get_entity_mut(entity)3709.ok()?3710.into_mut_by_id(component_id)3711.ok()3712}3713}37143715// Schedule-related methods3716impl World {3717/// Adds the specified [`Schedule`] to the world.3718/// If a schedule already exists with the same [label](Schedule::label), it will be replaced.3719///3720/// The schedule can later be run3721/// by calling [`.run_schedule(label)`](Self::run_schedule) or by directly3722/// accessing the [`Schedules`] resource.3723///3724/// The `Schedules` resource will be initialized if it does not already exist.3725///3726/// An alternative to this is to call [`Schedules::add_systems()`] with some3727/// [`ScheduleLabel`] and let the schedule for that label be created if it3728/// does not already exist.3729pub fn add_schedule(&mut self, schedule: Schedule) {3730let mut schedules = self.get_resource_or_init::<Schedules>();3731schedules.insert(schedule);3732}37333734/// Temporarily removes the schedule associated with `label` from the world,3735/// runs user code, and finally re-adds the schedule.3736/// This returns a [`TryRunScheduleError`] if there is no schedule3737/// associated with `label`.3738///3739/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3740/// and system state is cached.3741///3742/// For simple cases where you just need to call the schedule once,3743/// consider using [`World::try_run_schedule`] instead.3744/// For other use cases, see the example on [`World::schedule_scope`].3745pub fn try_schedule_scope<R>(3746&mut self,3747label: impl ScheduleLabel,3748f: impl FnOnce(&mut World, &mut Schedule) -> R,3749) -> Result<R, TryRunScheduleError> {3750let label = label.intern();3751let Some(mut schedule) = self3752.get_resource_mut::<Schedules>()3753.and_then(|mut s| s.remove(label))3754else {3755return Err(TryRunScheduleError(label));3756};37573758let value = f(self, &mut schedule);37593760let old = self.resource_mut::<Schedules>().insert(schedule);3761if old.is_some() {3762warn!("Schedule `{label:?}` was inserted during a call to `World::schedule_scope`: its value has been overwritten");3763}37643765Ok(value)3766}37673768/// Temporarily removes the schedule associated with `label` from the world,3769/// runs user code, and finally re-adds the schedule.3770///3771/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3772/// and system state is cached.3773///3774/// # Examples3775///3776/// ```3777/// # use bevy_ecs::{prelude::*, schedule::ScheduleLabel};3778/// # #[derive(ScheduleLabel, Debug, Clone, Copy, PartialEq, Eq, Hash)]3779/// # pub struct MySchedule;3780/// # #[derive(Resource)]3781/// # struct Counter(usize);3782/// #3783/// # let mut world = World::new();3784/// # world.insert_resource(Counter(0));3785/// # let mut schedule = Schedule::new(MySchedule);3786/// # schedule.add_systems(tick_counter);3787/// # world.init_resource::<Schedules>();3788/// # world.add_schedule(schedule);3789/// # fn tick_counter(mut counter: ResMut<Counter>) { counter.0 += 1; }3790/// // Run the schedule five times.3791/// world.schedule_scope(MySchedule, |world, schedule| {3792/// for _ in 0..5 {3793/// schedule.run(world);3794/// }3795/// });3796/// # assert_eq!(world.resource::<Counter>().0, 5);3797/// ```3798///3799/// For simple cases where you just need to call the schedule once,3800/// consider using [`World::run_schedule`] instead.3801///3802/// # Panics3803///3804/// If the requested schedule does not exist.3805pub fn schedule_scope<R>(3806&mut self,3807label: impl ScheduleLabel,3808f: impl FnOnce(&mut World, &mut Schedule) -> R,3809) -> R {3810self.try_schedule_scope(label, f)3811.unwrap_or_else(|e| panic!("{e}"))3812}38133814/// Attempts to run the [`Schedule`] associated with the `label` a single time,3815/// and returns a [`TryRunScheduleError`] if the schedule does not exist.3816///3817/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3818/// and system state is cached.3819///3820/// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.3821pub fn try_run_schedule(3822&mut self,3823label: impl ScheduleLabel,3824) -> Result<(), TryRunScheduleError> {3825self.try_schedule_scope(label, |world, sched| sched.run(world))3826}38273828/// Runs the [`Schedule`] associated with the `label` a single time.3829///3830/// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,3831/// and system state is cached.3832///3833/// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.3834/// This avoids the need to create a unique [`ScheduleLabel`].3835///3836/// # Panics3837///3838/// If the requested schedule does not exist.3839pub fn run_schedule(&mut self, label: impl ScheduleLabel) {3840self.schedule_scope(label, |world, sched| sched.run(world));3841}38423843/// Ignore system order ambiguities caused by conflicts on [`Component`]s of type `T`.3844pub fn allow_ambiguous_component<T: Component>(&mut self) {3845let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();3846schedules.allow_ambiguous_component::<T>(self);3847self.insert_resource(schedules);3848}38493850/// Ignore system order ambiguities caused by conflicts on [`Resource`]s of type `T`.3851pub fn allow_ambiguous_resource<T: Resource>(&mut self) {3852let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();3853schedules.allow_ambiguous_resource::<T>(self);3854self.insert_resource(schedules);3855}3856}38573858impl fmt::Debug for World {3859fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {3860// SAFETY: `UnsafeWorldCell` requires that this must only access metadata.3861// Accessing any data stored in the world would be unsound.3862f.debug_struct("World")3863.field("id", &self.id)3864.field("entity_count", &self.entities.count_spawned())3865.field("archetype_count", &self.archetypes.len())3866.field("component_count", &self.components.len())3867.field("resource_count", &self.resource_entities.len())3868.finish()3869}3870}38713872// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread3873unsafe impl Send for World {}3874// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread3875unsafe impl Sync for World {}38763877/// Creates an instance of the type this trait is implemented for3878/// using data from the supplied [`World`].3879///3880/// This can be helpful for complex initialization or context-aware defaults.3881///3882/// [`FromWorld`] is automatically implemented for any type implementing [`Default`]3883/// and may also be derived for:3884/// - any struct whose fields all implement `FromWorld`3885/// - any enum where one variant has the attribute `#[from_world]`3886///3887/// ```rs3888///3889/// #[derive(Default)]3890/// struct A;3891///3892/// #[derive(Default)]3893/// struct B(Option<u32>)3894///3895/// struct C;3896///3897/// impl FromWorld for C {3898/// fn from_world(_world: &mut World) -> Self {3899/// Self3900/// }3901/// }3902///3903/// #[derive(FromWorld)]3904/// struct D(A, B, C);3905///3906/// #[derive(FromWorld)]3907/// enum E {3908/// #[from_world]3909/// F,3910/// G3911/// }3912/// ```3913pub trait FromWorld {3914/// Creates `Self` using data from the given [`World`].3915fn from_world(world: &mut World) -> Self;3916}39173918impl<T: Default> FromWorld for T {3919/// Creates `Self` using [`default()`](`Default::default`).3920#[track_caller]3921fn from_world(_world: &mut World) -> Self {3922T::default()3923}3924}39253926#[cfg(test)]3927#[expect(clippy::print_stdout, reason = "Allowed in tests.")]3928mod tests {3929use super::{FromWorld, World};3930use crate::{3931change_detection::{DetectChangesMut, MaybeLocation},3932component::{ComponentCloneBehavior, ComponentDescriptor, ComponentInfo, StorageType},3933entity::EntityHashSet,3934entity_disabling::{DefaultQueryFilters, Disabled},3935prelude::{Event, Mut, On, Res},3936ptr::OwningPtr,3937resource::Resource,3938world::{error::EntityMutableFetchError, DeferredWorld},3939};3940use alloc::{3941borrow::ToOwned,3942string::{String, ToString},3943sync::Arc,3944vec,3945vec::Vec,3946};3947use bevy_ecs_macros::Component;3948use bevy_platform::collections::{HashMap, HashSet};3949use bevy_utils::prelude::DebugName;3950use core::{3951any::TypeId,3952panic,3953sync::atomic::{AtomicBool, AtomicU32, Ordering},3954};3955use std::{println, sync::Mutex};39563957type ID = u8;39583959#[derive(Clone, Copy, Debug, PartialEq, Eq)]3960enum DropLogItem {3961Create(ID),3962Drop(ID),3963}39643965#[derive(Component)]3966struct MayPanicInDrop {3967drop_log: Arc<Mutex<Vec<DropLogItem>>>,3968expected_panic_flag: Arc<AtomicBool>,3969should_panic: bool,3970id: u8,3971}39723973impl MayPanicInDrop {3974fn new(3975drop_log: &Arc<Mutex<Vec<DropLogItem>>>,3976expected_panic_flag: &Arc<AtomicBool>,3977should_panic: bool,3978id: u8,3979) -> Self {3980println!("creating component with id {id}");3981drop_log.lock().unwrap().push(DropLogItem::Create(id));39823983Self {3984drop_log: Arc::clone(drop_log),3985expected_panic_flag: Arc::clone(expected_panic_flag),3986should_panic,3987id,3988}3989}3990}39913992impl Drop for MayPanicInDrop {3993fn drop(&mut self) {3994println!("dropping component with id {}", self.id);39953996{3997let mut drop_log = self.drop_log.lock().unwrap();3998drop_log.push(DropLogItem::Drop(self.id));3999// Don't keep the mutex while panicking, or we'll poison it.4000drop(drop_log);4001}40024003if self.should_panic {4004self.expected_panic_flag.store(true, Ordering::SeqCst);4005panic!("testing what happens on panic inside drop");4006}4007}4008}40094010struct DropTestHelper {4011drop_log: Arc<Mutex<Vec<DropLogItem>>>,4012/// Set to `true` right before we intentionally panic, so that if we get4013/// a panic, we know if it was intended or not.4014expected_panic_flag: Arc<AtomicBool>,4015}40164017impl DropTestHelper {4018pub fn new() -> Self {4019Self {4020drop_log: Arc::new(Mutex::new(Vec::<DropLogItem>::new())),4021expected_panic_flag: Arc::new(AtomicBool::new(false)),4022}4023}40244025pub fn make_component(&self, should_panic: bool, id: ID) -> MayPanicInDrop {4026MayPanicInDrop::new(&self.drop_log, &self.expected_panic_flag, should_panic, id)4027}40284029pub fn finish(self, panic_res: std::thread::Result<()>) -> Vec<DropLogItem> {4030let drop_log = self.drop_log.lock().unwrap();4031let expected_panic_flag = self.expected_panic_flag.load(Ordering::SeqCst);40324033if !expected_panic_flag {4034match panic_res {4035Ok(()) => panic!("Expected a panic but it didn't happen"),4036Err(e) => std::panic::resume_unwind(e),4037}4038}40394040drop_log.to_owned()4041}4042}40434044#[test]4045fn panic_while_overwriting_component() {4046let helper = DropTestHelper::new();40474048let res = std::panic::catch_unwind(|| {4049let mut world = World::new();4050world4051.spawn_empty()4052.insert(helper.make_component(true, 0))4053.insert(helper.make_component(false, 1));40544055println!("Done inserting! Dropping world...");4056});40574058let drop_log = helper.finish(res);40594060assert_eq!(4061&*drop_log,4062[4063DropLogItem::Create(0),4064DropLogItem::Create(1),4065DropLogItem::Drop(0),4066DropLogItem::Drop(1),4067]4068);4069}40704071#[derive(Resource)]4072struct TestResource(u32);40734074#[derive(Resource)]4075struct TestResource2(String);40764077#[derive(Resource)]4078struct TestResource3;40794080#[test]4081fn get_resource_by_id() {4082let mut world = World::new();4083world.insert_resource(TestResource(42));4084let component_id = world4085.components()4086.get_valid_resource_id(TypeId::of::<TestResource>())4087.unwrap();40884089let resource = world.get_resource_by_id(component_id).unwrap();4090// SAFETY: `TestResource` is the correct resource type4091let resource = unsafe { resource.deref::<TestResource>() };40924093assert_eq!(resource.0, 42);4094}40954096#[test]4097fn get_resource_mut_by_id() {4098let mut world = World::new();4099world.insert_resource(TestResource(42));4100let component_id = world4101.components()4102.get_valid_resource_id(TypeId::of::<TestResource>())4103.unwrap();41044105{4106let mut resource = world.get_resource_mut_by_id(component_id).unwrap();4107resource.set_changed();4108// SAFETY: `TestResource` is the correct resource type4109let resource = unsafe { resource.into_inner().deref_mut::<TestResource>() };4110resource.0 = 43;4111}41124113let resource = world.get_resource_by_id(component_id).unwrap();4114// SAFETY: `TestResource` is the correct resource type4115let resource = unsafe { resource.deref::<TestResource>() };41164117assert_eq!(resource.0, 43);4118}41194120#[test]4121fn iter_resources() {4122let mut world = World::new();4123// Remove DefaultQueryFilters so it doesn't show up in the iterator4124world.remove_resource::<DefaultQueryFilters>();4125world.insert_resource(TestResource(42));4126world.insert_resource(TestResource2("Hello, world!".to_string()));4127world.insert_resource(TestResource3);4128world.remove_resource::<TestResource3>();41294130let mut iter = world.iter_resources();41314132let (info, ptr) = iter.next().unwrap();4133assert_eq!(info.name(), DebugName::type_name::<TestResource>());4134// SAFETY: We know that the resource is of type `TestResource`4135assert_eq!(unsafe { ptr.deref::<TestResource>().0 }, 42);41364137let (info, ptr) = iter.next().unwrap();4138assert_eq!(info.name(), DebugName::type_name::<TestResource2>());4139assert_eq!(4140// SAFETY: We know that the resource is of type `TestResource2`4141unsafe { &ptr.deref::<TestResource2>().0 },4142&"Hello, world!".to_string()4143);41444145assert!(iter.next().is_none());4146}41474148#[test]4149fn iter_resources_mut() {4150let mut world = World::new();4151// Remove DefaultQueryFilters so it doesn't show up in the iterator4152world.remove_resource::<DefaultQueryFilters>();4153world.insert_resource(TestResource(42));4154world.insert_resource(TestResource2("Hello, world!".to_string()));4155world.insert_resource(TestResource3);4156world.remove_resource::<TestResource3>();41574158let mut iter = world.iter_resources_mut();41594160let (info, mut mut_untyped) = iter.next().unwrap();4161assert_eq!(info.name(), DebugName::type_name::<TestResource>());4162// SAFETY: We know that the resource is of type `TestResource`4163unsafe {4164mut_untyped.as_mut().deref_mut::<TestResource>().0 = 43;4165};41664167let (info, mut mut_untyped) = iter.next().unwrap();4168assert_eq!(info.name(), DebugName::type_name::<TestResource2>());4169// SAFETY: We know that the resource is of type `TestResource2`4170unsafe {4171mut_untyped.as_mut().deref_mut::<TestResource2>().0 = "Hello, world?".to_string();4172};41734174assert!(iter.next().is_none());4175drop(iter);41764177assert_eq!(world.resource::<TestResource>().0, 43);4178assert_eq!(4179world.resource::<TestResource2>().0,4180"Hello, world?".to_string()4181);4182}41834184#[test]4185fn custom_non_send_with_layout() {4186static DROP_COUNT: AtomicU32 = AtomicU32::new(0);41874188let mut world = World::new();41894190// SAFETY: the drop function is valid for the layout and the data will be safe to access from any thread4191let descriptor = unsafe {4192ComponentDescriptor::new_with_layout(4193"Custom Test Component".to_string(),4194StorageType::Table,4195core::alloc::Layout::new::<[u8; 8]>(),4196Some(|ptr| {4197let data = ptr.read::<[u8; 8]>();4198assert_eq!(data, [0, 1, 2, 3, 4, 5, 6, 7]);4199DROP_COUNT.fetch_add(1, Ordering::SeqCst);4200}),4201true,4202ComponentCloneBehavior::Default,4203None,4204)4205};42064207let component_id = world.register_component_with_descriptor(descriptor);42084209let value: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];4210OwningPtr::make(value, |ptr| {4211// SAFETY: value is valid for the component layout4212unsafe {4213world.insert_non_send_by_id(component_id, ptr, MaybeLocation::caller());4214}4215});42164217// SAFETY: [u8; 8] is the correct type for the resource4218let data = unsafe {4219world4220.get_non_send_by_id(component_id)4221.unwrap()4222.deref::<[u8; 8]>()4223};4224assert_eq!(*data, [0, 1, 2, 3, 4, 5, 6, 7]);42254226assert!(world.remove_non_send_by_id(component_id).is_some());42274228assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);4229}42304231#[derive(Resource)]4232struct TestFromWorld(u32);4233impl FromWorld for TestFromWorld {4234fn from_world(world: &mut World) -> Self {4235let b = world.resource::<TestResource>();4236Self(b.0)4237}4238}42394240#[test]4241fn init_resource_does_not_overwrite() {4242let mut world = World::new();4243world.insert_resource(TestResource(0));4244world.init_resource::<TestFromWorld>();4245world.insert_resource(TestResource(1));4246world.init_resource::<TestFromWorld>();42474248let resource = world.resource::<TestFromWorld>();42494250assert_eq!(resource.0, 0);4251}42524253#[test]4254fn init_non_send_does_not_overwrite() {4255let mut world = World::new();4256world.insert_resource(TestResource(0));4257world.init_non_send::<TestFromWorld>();4258world.insert_resource(TestResource(1));4259world.init_non_send::<TestFromWorld>();42604261let resource = world.non_send::<TestFromWorld>();42624263assert_eq!(resource.0, 0);4264}42654266#[derive(Component)]4267struct Foo;42684269#[derive(Component)]4270struct Bar;42714272#[derive(Component)]4273struct Baz;42744275#[test]4276fn inspect_entity_components() {4277let mut world = World::new();4278let ent0 = world.spawn((Foo, Bar, Baz)).id();4279let ent1 = world.spawn((Foo, Bar)).id();4280let ent2 = world.spawn((Bar, Baz)).id();4281let ent3 = world.spawn((Foo, Baz)).id();4282let ent4 = world.spawn(Foo).id();4283let ent5 = world.spawn(Bar).id();4284let ent6 = world.spawn(Baz).id();42854286fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {4287component_infos4288.into_iter()4289.map(ComponentInfo::type_id)4290.collect()4291}42924293let foo_id = TypeId::of::<Foo>();4294let bar_id = TypeId::of::<Bar>();4295let baz_id = TypeId::of::<Baz>();4296assert_eq!(4297to_type_ids(world.inspect_entity(ent0).unwrap().collect()),4298[Some(foo_id), Some(bar_id), Some(baz_id)]4299.into_iter()4300.collect::<HashSet<_>>()4301);4302assert_eq!(4303to_type_ids(world.inspect_entity(ent1).unwrap().collect()),4304[Some(foo_id), Some(bar_id)]4305.into_iter()4306.collect::<HashSet<_>>()4307);4308assert_eq!(4309to_type_ids(world.inspect_entity(ent2).unwrap().collect()),4310[Some(bar_id), Some(baz_id)]4311.into_iter()4312.collect::<HashSet<_>>()4313);4314assert_eq!(4315to_type_ids(world.inspect_entity(ent3).unwrap().collect()),4316[Some(foo_id), Some(baz_id)]4317.into_iter()4318.collect::<HashSet<_>>()4319);4320assert_eq!(4321to_type_ids(world.inspect_entity(ent4).unwrap().collect()),4322[Some(foo_id)].into_iter().collect::<HashSet<_>>()4323);4324assert_eq!(4325to_type_ids(world.inspect_entity(ent5).unwrap().collect()),4326[Some(bar_id)].into_iter().collect::<HashSet<_>>()4327);4328assert_eq!(4329to_type_ids(world.inspect_entity(ent6).unwrap().collect()),4330[Some(baz_id)].into_iter().collect::<HashSet<_>>()4331);4332}43334334#[test]4335fn iterate_entities() {4336let mut world = World::new();4337let mut entity_counters = <HashMap<_, _>>::default();43384339let iterate_and_count_entities = |world: &World, entity_counters: &mut HashMap<_, _>| {4340entity_counters.clear();4341for entity in world.iter_entities() {4342let counter = entity_counters.entry(entity.id()).or_insert(0);4343*counter += 1;4344}4345};43464347// Adding one entity and validating iteration4348let ent0 = world.spawn((Foo, Bar, Baz)).id();43494350iterate_and_count_entities(&world, &mut entity_counters);4351assert_eq!(entity_counters[&ent0], 1);4352assert_eq!(entity_counters.len(), 2);43534354// Spawning three more entities and then validating iteration4355let ent1 = world.spawn((Foo, Bar)).id();4356let ent2 = world.spawn((Bar, Baz)).id();4357let ent3 = world.spawn((Foo, Baz)).id();43584359iterate_and_count_entities(&world, &mut entity_counters);43604361assert_eq!(entity_counters[&ent0], 1);4362assert_eq!(entity_counters[&ent1], 1);4363assert_eq!(entity_counters[&ent2], 1);4364assert_eq!(entity_counters[&ent3], 1);4365assert_eq!(entity_counters.len(), 5);43664367// Despawning first entity and then validating the iteration4368assert!(world.despawn(ent0));43694370iterate_and_count_entities(&world, &mut entity_counters);43714372assert_eq!(entity_counters[&ent1], 1);4373assert_eq!(entity_counters[&ent2], 1);4374assert_eq!(entity_counters[&ent3], 1);4375assert_eq!(entity_counters.len(), 4);43764377// Spawning three more entities, despawning three and then validating the iteration4378let ent4 = world.spawn(Foo).id();4379let ent5 = world.spawn(Bar).id();4380let ent6 = world.spawn(Baz).id();43814382assert!(world.despawn(ent2));4383assert!(world.despawn(ent3));4384assert!(world.despawn(ent4));43854386iterate_and_count_entities(&world, &mut entity_counters);43874388assert_eq!(entity_counters[&ent1], 1);4389assert_eq!(entity_counters[&ent5], 1);4390assert_eq!(entity_counters[&ent6], 1);4391assert_eq!(entity_counters.len(), 4);43924393// Despawning remaining entities and then validating the iteration4394assert!(world.despawn(ent1));4395assert!(world.despawn(ent5));4396assert!(world.despawn(ent6));43974398iterate_and_count_entities(&world, &mut entity_counters);43994400assert_eq!(entity_counters.len(), 1);4401}44024403#[test]4404fn spawn_empty_bundle() {4405let mut world = World::new();4406world.spawn(());4407}44084409#[test]4410fn get_entity() {4411let mut world = World::new();44124413let e1 = world.spawn_empty().id();4414let e2 = world.spawn_empty().id();44154416assert!(world.get_entity(e1).is_ok());4417assert!(world.get_entity([e1, e2]).is_ok());4418assert!(world4419.get_entity(&[e1, e2] /* this is an array not a slice */)4420.is_ok());4421assert!(world.get_entity(&vec![e1, e2][..]).is_ok());4422assert!(world4423.get_entity(&EntityHashSet::from_iter([e1, e2]))4424.is_ok());44254426world.entity_mut(e1).despawn();44274428assert_eq!(4429Err(e1),4430world.get_entity(e1).map(|_| {}).map_err(|e| e.entity())4431);4432assert_eq!(4433Err(e1),4434world4435.get_entity([e1, e2])4436.map(|_| {})4437.map_err(|e| e.entity())4438);4439assert_eq!(4440Err(e1),4441world4442.get_entity(&[e1, e2] /* this is an array not a slice */)4443.map(|_| {})4444.map_err(|e| e.entity())4445);4446assert_eq!(4447Err(e1),4448world4449.get_entity(&vec![e1, e2][..])4450.map(|_| {})4451.map_err(|e| e.entity())4452);4453assert_eq!(4454Err(e1),4455world4456.get_entity(&EntityHashSet::from_iter([e1, e2]))4457.map(|_| {})4458.map_err(|e| e.entity())4459);4460}44614462#[test]4463fn get_entity_mut() {4464let mut world = World::new();44654466let e1 = world.spawn_empty().id();4467let e2 = world.spawn_empty().id();44684469assert!(world.get_entity_mut(e1).is_ok());4470assert!(world.get_entity_mut([e1, e2]).is_ok());4471assert!(world4472.get_entity_mut(&[e1, e2] /* this is an array not a slice */)4473.is_ok());4474assert!(world.get_entity_mut(&vec![e1, e2][..]).is_ok());4475assert!(world4476.get_entity_mut(&EntityHashSet::from_iter([e1, e2]))4477.is_ok());44784479assert_eq!(4480Err(EntityMutableFetchError::AliasedMutability(e1)),4481world.get_entity_mut([e1, e2, e1]).map(|_| {})4482);4483assert_eq!(4484Err(EntityMutableFetchError::AliasedMutability(e1)),4485world4486.get_entity_mut(&[e1, e2, e1] /* this is an array not a slice */)4487.map(|_| {})4488);4489assert_eq!(4490Err(EntityMutableFetchError::AliasedMutability(e1)),4491world.get_entity_mut(&vec![e1, e2, e1][..]).map(|_| {})4492);4493// Aliased mutability isn't allowed by HashSets4494assert!(world4495.get_entity_mut(&EntityHashSet::from_iter([e1, e2, e1]))4496.is_ok());44974498world.entity_mut(e1).despawn();4499assert!(world.get_entity_mut(e2).is_ok());45004501assert!(matches!(4502world.get_entity_mut(e1).map(|_| {}),4503Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e14504));4505assert!(matches!(4506world.get_entity_mut([e1, e2]).map(|_| {}),4507Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));4508assert!(matches!(4509world4510.get_entity_mut(&[e1, e2] /* this is an array not a slice */)4511.map(|_| {}),4512Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));4513assert!(matches!(4514world.get_entity_mut(&vec![e1, e2][..]).map(|_| {}),4515Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1,4516));4517assert!(matches!(4518world4519.get_entity_mut(&EntityHashSet::from_iter([e1, e2]))4520.map(|_| {}),4521Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));4522}45234524#[test]4525#[track_caller]4526fn entity_spawn_despawn_tracking() {4527use core::panic::Location;45284529let mut world = World::new();4530let entity = world.spawn_empty().id();4531assert_eq!(4532world.entities.entity_get_spawned_or_despawned_by(entity),4533MaybeLocation::new(Some(Location::caller()))4534);4535assert_eq!(4536world.entities.entity_get_spawn_or_despawn_tick(entity),4537Some(world.change_tick())4538);4539let new = world.despawn_no_free(entity).unwrap();4540assert_eq!(4541world.entities.entity_get_spawned_or_despawned_by(entity),4542MaybeLocation::new(Some(Location::caller()))4543);4544assert_eq!(4545world.entities.entity_get_spawn_or_despawn_tick(entity),4546Some(world.change_tick())4547);45484549world.spawn_empty_at(new).unwrap();4550assert_eq!(entity.index(), new.index());4551assert_eq!(4552world.entities.entity_get_spawned_or_despawned_by(entity),4553MaybeLocation::new(None)4554);4555assert_eq!(4556world.entities.entity_get_spawn_or_despawn_tick(entity),4557None4558);4559world.despawn(new);4560assert_eq!(4561world.entities.entity_get_spawned_or_despawned_by(entity),4562MaybeLocation::new(None)4563);4564assert_eq!(4565world.entities.entity_get_spawn_or_despawn_tick(entity),4566None4567);4568}45694570#[test]4571fn new_world_has_disabling() {4572let mut world = World::new();4573world.spawn(Foo);4574world.spawn((Foo, Disabled));4575assert_eq!(1, world.query::<&Foo>().iter(&world).count());45764577// If we explicitly remove the resource, no entities should be filtered anymore4578world.remove_resource::<DefaultQueryFilters>();4579assert_eq!(2, world.query::<&Foo>().iter(&world).count());4580}45814582#[test]4583fn entities_and_commands() {4584#[derive(Component, PartialEq, Debug)]4585struct Foo(u32);45864587let mut world = World::new();45884589let eid = world.spawn(Foo(35)).id();45904591let (mut fetcher, mut commands) = world.entities_and_commands();4592let emut = fetcher.get_mut(eid).unwrap();4593commands.entity(eid).despawn();4594assert_eq!(emut.get::<Foo>().unwrap(), &Foo(35));45954596world.flush();45974598assert!(world.get_entity(eid).is_err());4599}46004601#[test]4602fn resource_query_after_resource_scope() {4603#[derive(Event)]4604struct EventA;46054606#[derive(Resource)]4607struct ResourceA;46084609let mut world = World::default();46104611world.insert_resource(ResourceA);4612world.add_observer(move |_event: On<EventA>, _res: Res<ResourceA>| {});4613world.resource_scope(|world, _res: Mut<ResourceA>| {4614// since we use commands, this should trigger outside of the resource_scope, so the observer should work.4615world.commands().trigger(EventA);4616});4617}46184619#[test]4620fn entities_and_commands_deferred() {4621#[derive(Component, PartialEq, Debug)]4622struct Foo(u32);46234624let mut world = World::new();46254626let eid = world.spawn(Foo(1)).id();46274628let mut dworld = DeferredWorld::from(&mut world);46294630let (mut fetcher, mut commands) = dworld.entities_and_commands();4631let emut = fetcher.get_mut(eid).unwrap();4632commands.entity(eid).despawn();4633assert_eq!(emut.get::<Foo>().unwrap(), &Foo(1));46344635world.flush();46364637assert!(world.get_entity(eid).is_err());4638}4639}464046414642