#![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, DISCARD, INSERT, REMOVE},54message::{Message, MessageId, Messages, WriteBatchIds},55observer::Observers,56prelude::{Add, Despawn, DetectChangesMut, Discard, Insert, Remove},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_discard = self.register_event_key::<Discard>();169assert_eq!(DISCARD, on_discard);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`].663#[deprecated(since = "0.19.0", note = "use component_id")]664pub fn resource_id<T: Resource>(&self) -> Option<ComponentId> {665self.components.get_id(TypeId::of::<T>())666}667668/// Returns [`EntityRef`]s that expose read-only operations for the given669/// `entities`. This will panic if any of the given entities do not exist. Use670/// [`World::get_entity`] if you want to check for entity existence instead671/// of implicitly panicking.672///673/// This function supports fetching a single entity or multiple entities:674/// - Pass an [`Entity`] to receive a single [`EntityRef`].675/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].676/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.677///678/// # Panics679///680/// If any of the given `entities` do not exist in the world.681///682/// # Examples683///684/// ## Single [`Entity`]685///686/// ```687/// # use bevy_ecs::prelude::*;688/// #[derive(Component)]689/// struct Position {690/// x: f32,691/// y: f32,692/// }693///694/// let mut world = World::new();695/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();696///697/// let position = world.entity(entity).get::<Position>().unwrap();698/// assert_eq!(position.x, 0.0);699/// ```700///701/// ## Array of [`Entity`]s702///703/// ```704/// # use bevy_ecs::prelude::*;705/// #[derive(Component)]706/// struct Position {707/// x: f32,708/// y: f32,709/// }710///711/// let mut world = World::new();712/// let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();713/// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();714///715/// let [e1_ref, e2_ref] = world.entity([e1, e2]);716/// let e1_position = e1_ref.get::<Position>().unwrap();717/// assert_eq!(e1_position.x, 0.0);718/// let e2_position = e2_ref.get::<Position>().unwrap();719/// assert_eq!(e2_position.x, 1.0);720/// ```721///722/// ## Slice of [`Entity`]s723///724/// ```725/// # use bevy_ecs::prelude::*;726/// #[derive(Component)]727/// struct Position {728/// x: f32,729/// y: f32,730/// }731///732/// let mut world = World::new();733/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();734/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();735/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();736///737/// let ids = vec![e1, e2, e3];738/// for eref in world.entity(&ids[..]) {739/// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);740/// }741/// ```742///743/// ## [`EntityHashSet`](crate::entity::EntityHashSet)744///745/// ```746/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};747/// #[derive(Component)]748/// struct Position {749/// x: f32,750/// y: f32,751/// }752///753/// let mut world = World::new();754/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();755/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();756/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();757///758/// let ids = EntityHashSet::from_iter([e1, e2, e3]);759/// for (_id, eref) in world.entity(&ids) {760/// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);761/// }762/// ```763///764/// [`EntityHashSet`]: crate::entity::EntityHashSet765#[inline]766#[track_caller]767pub fn entity<F: WorldEntityFetch>(&self, entities: F) -> F::Ref<'_> {768match self.get_entity(entities) {769Ok(res) => res,770Err(err) => panic!("{err}"),771}772}773774/// Returns [`EntityMut`]s that expose read and write operations for the775/// given `entities`. This will panic if any of the given entities do not776/// exist. Use [`World::get_entity_mut`] if you want to check for entity777/// existence instead of implicitly panicking.778///779/// This function supports fetching a single entity or multiple entities:780/// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].781/// - This reference type allows for structural changes to the entity,782/// such as adding or removing components, or despawning the entity.783/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].784/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.785/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an786/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).787///788/// In order to perform structural changes on the returned entity reference,789/// such as adding or removing components, or despawning the entity, only a790/// single [`Entity`] can be passed to this function. Allowing multiple791/// entities at the same time with structural access would lead to undefined792/// behavior, so [`EntityMut`] is returned when requesting multiple entities.793///794/// # Panics795///796/// If any of the given `entities` do not exist in the world.797///798/// # Examples799///800/// ## Single [`Entity`]801///802/// ```803/// # use bevy_ecs::prelude::*;804/// #[derive(Component)]805/// struct Position {806/// x: f32,807/// y: f32,808/// }809///810/// let mut world = World::new();811/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();812///813/// let mut entity_mut = world.entity_mut(entity);814/// let mut position = entity_mut.get_mut::<Position>().unwrap();815/// position.y = 1.0;816/// assert_eq!(position.x, 0.0);817/// entity_mut.despawn();818/// # assert!(world.get_entity_mut(entity).is_err());819/// ```820///821/// ## Array of [`Entity`]s822///823/// ```824/// # use bevy_ecs::prelude::*;825/// #[derive(Component)]826/// struct Position {827/// x: f32,828/// y: f32,829/// }830///831/// let mut world = World::new();832/// let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();833/// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();834///835/// let [mut e1_ref, mut e2_ref] = world.entity_mut([e1, e2]);836/// let mut e1_position = e1_ref.get_mut::<Position>().unwrap();837/// e1_position.x = 1.0;838/// assert_eq!(e1_position.x, 1.0);839/// let mut e2_position = e2_ref.get_mut::<Position>().unwrap();840/// e2_position.x = 2.0;841/// assert_eq!(e2_position.x, 2.0);842/// ```843///844/// ## Slice of [`Entity`]s845///846/// ```847/// # use bevy_ecs::prelude::*;848/// #[derive(Component)]849/// struct Position {850/// x: f32,851/// y: f32,852/// }853///854/// let mut world = World::new();855/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();856/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();857/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();858///859/// let ids = vec![e1, e2, e3];860/// for mut eref in world.entity_mut(&ids[..]) {861/// let mut pos = eref.get_mut::<Position>().unwrap();862/// pos.y = 2.0;863/// assert_eq!(pos.y, 2.0);864/// }865/// ```866///867/// ## [`EntityHashSet`](crate::entity::EntityHashSet)868///869/// ```870/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};871/// #[derive(Component)]872/// struct Position {873/// x: f32,874/// y: f32,875/// }876///877/// let mut world = World::new();878/// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();879/// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();880/// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();881///882/// let ids = EntityHashSet::from_iter([e1, e2, e3]);883/// for (_id, mut eref) in world.entity_mut(&ids) {884/// let mut pos = eref.get_mut::<Position>().unwrap();885/// pos.y = 2.0;886/// assert_eq!(pos.y, 2.0);887/// }888/// ```889///890/// [`EntityHashSet`]: crate::entity::EntityHashSet891#[inline]892#[track_caller]893pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::Mut<'_> {894#[inline(never)]895#[cold]896#[track_caller]897fn panic_on_err(e: EntityMutableFetchError) -> ! {898panic!("{e}");899}900901match self.get_entity_mut(entities) {902Ok(fetched) => fetched,903Err(e) => panic_on_err(e),904}905}906907/// Returns the components of an [`Entity`] through [`ComponentInfo`].908#[inline]909pub fn inspect_entity(910&self,911entity: Entity,912) -> Result<impl Iterator<Item = &ComponentInfo>, EntityNotSpawnedError> {913let entity_location = self.entities().get_spawned(entity)?;914915let archetype = self916.archetypes()917.get(entity_location.archetype_id)918.expect("ArchetypeId was retrieved from an EntityLocation and should correspond to an Archetype");919920Ok(archetype921.iter_components()922.filter_map(|id| self.components().get_info(id)))923}924925/// Returns [`EntityRef`]s that expose read-only operations for the given926/// `entities`, returning [`Err`] if any of the given entities do not exist.927/// Instead of immediately unwrapping the value returned from this function,928/// prefer [`World::entity`].929///930/// This function supports fetching a single entity or multiple entities:931/// - Pass an [`Entity`] to receive a single [`EntityRef`].932/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].933/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.934/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an935/// [`EntityHashMap<EntityRef>`](crate::entity::EntityHashMap).936///937/// # Errors938///939/// If any of the given `entities` do not exist in the world, the first940/// [`Entity`] found to be missing will return an [`EntityNotSpawnedError`].941///942/// # Examples943///944/// For examples, see [`World::entity`].945///946/// [`EntityHashSet`]: crate::entity::EntityHashSet947#[inline]948pub fn get_entity<F: WorldEntityFetch>(949&self,950entities: F,951) -> Result<F::Ref<'_>, EntityNotSpawnedError> {952let cell = self.as_unsafe_world_cell_readonly();953// SAFETY: `&self` gives read access to the entire world, and prevents mutable access.954unsafe { entities.fetch_ref(cell) }955}956957/// Returns [`EntityMut`]s that expose read and write operations for the958/// given `entities`, returning [`Err`] if any of the given entities do not959/// exist. Instead of immediately unwrapping the value returned from this960/// function, prefer [`World::entity_mut`].961///962/// This function supports fetching a single entity or multiple entities:963/// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].964/// - This reference type allows for structural changes to the entity,965/// such as adding or removing components, or despawning the entity.966/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].967/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.968/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an969/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).970///971/// In order to perform structural changes on the returned entity reference,972/// such as adding or removing components, or despawning the entity, only a973/// single [`Entity`] can be passed to this function. Allowing multiple974/// entities at the same time with structural access would lead to undefined975/// behavior, so [`EntityMut`] is returned when requesting multiple entities.976///977/// # Errors978///979/// - Returns [`EntityMutableFetchError::NotSpawned`] if any of the given `entities` do not exist in the world.980/// - Only the first entity found to be missing will be returned.981/// - Returns [`EntityMutableFetchError::AliasedMutability`] if the same entity is requested multiple times.982///983/// # Examples984///985/// For examples, see [`World::entity_mut`].986///987/// [`EntityHashSet`]: crate::entity::EntityHashSet988#[inline]989pub fn get_entity_mut<F: WorldEntityFetch>(990&mut self,991entities: F,992) -> Result<F::Mut<'_>, EntityMutableFetchError> {993let cell = self.as_unsafe_world_cell();994// SAFETY: `&mut self` gives mutable access to the entire world,995// and prevents any other access to the world.996unsafe { entities.fetch_mut(cell) }997}998999/// Returns an [`Entity`] iterator of current entities.1000///1001/// This is useful in contexts where you only have immutable access to the [`World`].1002/// If you have mutable access to the [`World`], use1003/// [`query()::<EntityRef>().iter(&world)`](World::query()) instead.1004///1005/// Note that this does iterate through *all* entities, including resource entities.1006#[inline]1007pub fn iter_entities(&self) -> impl Iterator<Item = EntityRef<'_>> + '_ {1008self.archetypes.iter().flat_map(|archetype| {1009archetype1010.entities_with_location()1011.map(|(entity, location)| {1012// SAFETY: entity exists and location accurately specifies the archetype where the entity is stored.1013let cell = UnsafeEntityCell::new(1014self.as_unsafe_world_cell_readonly(),1015entity,1016location,1017self.last_change_tick,1018self.read_change_tick(),1019);1020// SAFETY: `&self` gives read access to the entire world.1021unsafe { EntityRef::new(cell) }1022})1023})1024}10251026/// Simultaneously provides access to entity data and a command queue, which1027/// will be applied when the world is next flushed.1028///1029/// This allows using borrowed entity data to construct commands where the1030/// borrow checker would otherwise prevent it.1031///1032/// See [`DeferredWorld::entities_and_commands`] for the deferred version.1033///1034/// # Example1035///1036/// ```rust1037/// # use bevy_ecs::{prelude::*, world::DeferredWorld};1038/// #[derive(Component)]1039/// struct Targets(Vec<Entity>);1040/// #[derive(Component)]1041/// struct TargetedBy(Entity);1042///1043/// let mut world: World = // ...1044/// # World::new();1045/// # let e1 = world.spawn_empty().id();1046/// # let e2 = world.spawn_empty().id();1047/// # let eid = world.spawn(Targets(vec![e1, e2])).id();1048/// let (entities, mut commands) = world.entities_and_commands();1049///1050/// let entity = entities.get(eid).unwrap();1051/// for &target in entity.get::<Targets>().unwrap().0.iter() {1052/// commands.entity(target).insert(TargetedBy(eid));1053/// }1054/// # world.flush();1055/// # assert_eq!(world.get::<TargetedBy>(e1).unwrap().0, eid);1056/// # assert_eq!(world.get::<TargetedBy>(e2).unwrap().0, eid);1057/// ```1058pub fn entities_and_commands(&mut self) -> (EntityFetcher<'_>, Commands<'_, '_>) {1059let cell = self.as_unsafe_world_cell();1060// SAFETY: `&mut self` gives mutable access to the entire world, and prevents simultaneous access.1061let fetcher = unsafe { EntityFetcher::new(cell) };1062// SAFETY:1063// - `&mut self` gives mutable access to the entire world, and prevents simultaneous access.1064// - Command queue access does not conflict with entity access.1065let raw_queue = unsafe { cell.get_raw_command_queue() };1066// SAFETY: `&mut self` ensures the commands does not outlive the world.1067let commands = unsafe {1068Commands::new_raw_from_entities(raw_queue, cell.entity_allocator(), cell.entities())1069};10701071(fetcher, commands)1072}10731074/// Spawns the bundle on the valid but not spawned entity.1075/// If the entity can not be spawned for any reason, returns an error.1076///1077/// If it succeeds, this declares the entity to have this bundle.1078///1079/// In general, you should prefer [`spawn`](Self::spawn).1080/// Spawn internally calls this method, but it takes care of finding a suitable [`Entity`] for you.1081/// This is made available for advanced use, which you can see at [`EntityAllocator::alloc`].1082///1083/// # Risk1084///1085/// It is possible to spawn an `entity` that has not been allocated yet;1086/// 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.1087/// This would cause a panic.1088///1089/// Manual spawning is a powerful tool, but must be used carefully.1090///1091/// # Example1092///1093/// Currently, this is primarily used to spawn entities that come from [`EntityAllocator::alloc`].1094/// See that for an example.1095#[track_caller]1096pub fn spawn_at<B: Bundle>(1097&mut self,1098entity: Entity,1099bundle: B,1100) -> Result<EntityWorldMut<'_>, SpawnError> {1101move_as_ptr!(bundle);1102self.spawn_at_with_caller(entity, bundle, MaybeLocation::caller())1103}11041105pub(crate) fn spawn_at_with_caller<B: Bundle>(1106&mut self,1107entity: Entity,1108bundle: MovingPtr<'_, B>,1109caller: MaybeLocation,1110) -> Result<EntityWorldMut<'_>, SpawnError> {1111self.entities.check_can_spawn_at(entity)?;1112Ok(self.spawn_at_unchecked(entity, bundle, caller))1113}11141115/// Spawns `bundle` on `entity`.1116///1117/// # Panics1118///1119/// Panics if the entity index is already constructed1120pub(crate) fn spawn_at_unchecked<B: Bundle>(1121&mut self,1122entity: Entity,1123bundle: MovingPtr<'_, B>,1124caller: MaybeLocation,1125) -> EntityWorldMut<'_> {1126let change_tick = self.change_tick();1127let mut bundle_spawner = BundleSpawner::new::<B>(self, change_tick);1128let (bundle, entity_location) = bundle.partial_move(|bundle| {1129// SAFETY:1130// - `B` matches `bundle_spawner`'s type1131// - `entity` is allocated but non-existent1132// - `B::Effect` is unconstrained, and `B::apply_effect` is called exactly once on the bundle after this call.1133// - This function ensures that the value pointed to by `bundle` must not be accessed for anything afterwards by consuming1134// the `MovingPtr`. The value is otherwise only used to call `apply_effect` within this function, and the safety invariants1135// of `DynamicBundle` ensure that only the elements that have not been moved out of by this call are accessed.1136unsafe { bundle_spawner.spawn_at::<B>(entity, bundle, caller) }1137});11381139let mut entity_location = Some(entity_location);11401141// SAFETY: command_queue is not referenced anywhere else1142if !unsafe { self.command_queue.is_empty() } {1143self.flush();1144entity_location = self.entities().get_spawned(entity).ok();1145}11461147// SAFETY: The entity and location started as valid.1148// If they were changed by commands, the location was updated to match.1149let mut entity = unsafe { EntityWorldMut::new(self, entity, entity_location) };1150// SAFETY:1151// - This is called exactly once after `get_components` has been called in `spawn_non_existent`.1152// - `bundle` had it's `get_components` function called exactly once inside `spawn_non_existent`.1153unsafe { B::apply_effect(bundle, &mut entity) };1154entity1155}11561157/// A faster version of [`spawn_at`](Self::spawn_at) for the empty bundle.1158#[track_caller]1159pub fn spawn_empty_at(&mut self, entity: Entity) -> Result<EntityWorldMut<'_>, SpawnError> {1160self.spawn_empty_at_with_caller(entity, MaybeLocation::caller())1161}11621163pub(crate) fn spawn_empty_at_with_caller(1164&mut self,1165entity: Entity,1166caller: MaybeLocation,1167) -> Result<EntityWorldMut<'_>, SpawnError> {1168self.entities.check_can_spawn_at(entity)?;1169Ok(self.spawn_empty_at_unchecked(entity, caller))1170}11711172/// A faster version of [`spawn_at_unchecked`](Self::spawn_at_unchecked) for the empty bundle.1173///1174/// # Panics1175///1176/// Panics if the entity index is already spawned1177pub(crate) fn spawn_empty_at_unchecked(1178&mut self,1179entity: Entity,1180caller: MaybeLocation,1181) -> EntityWorldMut<'_> {1182// SAFETY: Locations are immediately made valid1183unsafe {1184let archetype = self.archetypes.empty_mut();1185// PERF: consider avoiding allocating entities in the empty archetype unless needed1186let table_row = self.storages.tables[archetype.table_id()].allocate(entity);1187// SAFETY: no components are allocated by archetype.allocate() because the archetype is1188// empty1189let location = archetype.allocate(entity, table_row);1190let change_tick = self.change_tick();1191let was_at = self.entities.set_location(entity.index(), Some(location));1192assert!(1193was_at.is_none(),1194"Attempting to construct an empty entity, but it was already constructed."1195);1196self.entities1197.mark_spawned_or_despawned(entity.index(), caller, change_tick);11981199EntityWorldMut::new(self, entity, Some(location))1200}1201}12021203/// Spawns a new [`Entity`] with a given [`Bundle`] of [components](`Component`) and returns1204/// a corresponding [`EntityWorldMut`], which can be used to add components to the entity or1205/// retrieve its id. In case large batches of entities need to be spawned, consider using1206/// [`World::spawn_batch`] instead.1207///1208/// ```1209/// use bevy_ecs::{bundle::Bundle, component::Component, world::World};1210///1211/// #[derive(Component)]1212/// struct Position {1213/// x: f32,1214/// y: f32,1215/// }1216///1217/// #[derive(Component)]1218/// struct Velocity {1219/// x: f32,1220/// y: f32,1221/// };1222///1223/// #[derive(Component)]1224/// struct Name(&'static str);1225///1226/// #[derive(Bundle)]1227/// struct PhysicsBundle {1228/// position: Position,1229/// velocity: Velocity,1230/// }1231///1232/// let mut world = World::new();1233///1234/// // `spawn` can accept a single component:1235/// world.spawn(Position { x: 0.0, y: 0.0 });1236///1237/// // It can also accept a tuple of components:1238/// world.spawn((1239/// Position { x: 0.0, y: 0.0 },1240/// Velocity { x: 1.0, y: 1.0 },1241/// ));1242///1243/// // Or it can accept a pre-defined Bundle of components:1244/// world.spawn(PhysicsBundle {1245/// position: Position { x: 2.0, y: 2.0 },1246/// velocity: Velocity { x: 0.0, y: 4.0 },1247/// });1248///1249/// let entity = world1250/// // Tuples can also mix Bundles and Components1251/// .spawn((1252/// PhysicsBundle {1253/// position: Position { x: 2.0, y: 2.0 },1254/// velocity: Velocity { x: 0.0, y: 4.0 },1255/// },1256/// Name("Elaina Proctor"),1257/// ))1258/// // Calling id() will return the unique identifier for the spawned entity1259/// .id();1260/// let position = world.entity(entity).get::<Position>().unwrap();1261/// assert_eq!(position.x, 2.0);1262/// ```1263#[track_caller]1264pub fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityWorldMut<'_> {1265move_as_ptr!(bundle);1266self.spawn_with_caller(bundle, MaybeLocation::caller())1267}12681269pub(crate) fn spawn_with_caller<B: Bundle>(1270&mut self,1271bundle: MovingPtr<'_, B>,1272caller: MaybeLocation,1273) -> EntityWorldMut<'_> {1274let entity = self.entity_allocator.alloc();1275// This was just spawned from null, so it shouldn't panic.1276self.spawn_at_unchecked(entity, bundle, caller)1277}12781279/// Spawns a new [`Entity`] and returns a corresponding [`EntityWorldMut`], which can be used1280/// to add components to the entity or retrieve its id.1281///1282/// ```1283/// use bevy_ecs::{component::Component, world::World};1284///1285/// #[derive(Component)]1286/// struct Position {1287/// x: f32,1288/// y: f32,1289/// }1290/// #[derive(Component)]1291/// struct Label(&'static str);1292/// #[derive(Component)]1293/// struct Num(u32);1294///1295/// let mut world = World::new();1296/// let entity = world.spawn_empty()1297/// .insert(Position { x: 0.0, y: 0.0 }) // add a single component1298/// .insert((Num(1), Label("hello"))) // add a bundle of components1299/// .id();1300///1301/// let position = world.entity(entity).get::<Position>().unwrap();1302/// assert_eq!(position.x, 0.0);1303/// ```1304#[track_caller]1305pub fn spawn_empty(&mut self) -> EntityWorldMut<'_> {1306self.spawn_empty_with_caller(MaybeLocation::caller())1307}13081309pub(crate) fn spawn_empty_with_caller(&mut self, caller: MaybeLocation) -> EntityWorldMut<'_> {1310let entity = self.entity_allocator.alloc();1311// This was just spawned from null, so it shouldn't panic.1312self.spawn_empty_at_unchecked(entity, caller)1313}13141315/// Spawns a batch of entities with the same component [`Bundle`] type. Takes a given1316/// [`Bundle`] iterator and returns a corresponding [`Entity`] iterator.1317/// This is more efficient than spawning entities and adding components to them individually1318/// using [`World::spawn`], but it is limited to spawning entities with the same [`Bundle`]1319/// type, whereas spawning individually is more flexible.1320///1321/// ```1322/// use bevy_ecs::{component::Component, entity::Entity, world::World};1323///1324/// #[derive(Component)]1325/// struct Str(&'static str);1326/// #[derive(Component)]1327/// struct Num(u32);1328///1329/// let mut world = World::new();1330/// let entities = world.spawn_batch(vec![1331/// (Str("a"), Num(0)), // the first entity1332/// (Str("b"), Num(1)), // the second entity1333/// ]).collect::<Vec<Entity>>();1334///1335/// assert_eq!(entities.len(), 2);1336/// ```1337#[track_caller]1338pub fn spawn_batch<I>(&mut self, iter: I) -> SpawnBatchIter<'_, I::IntoIter>1339where1340I: IntoIterator,1341I::Item: Bundle<Effect: NoBundleEffect>,1342{1343SpawnBatchIter::new(self, iter.into_iter(), MaybeLocation::caller())1344}13451346/// Retrieves a reference to the given `entity`'s [`Component`] of the given type.1347/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1348/// ```1349/// use bevy_ecs::{component::Component, world::World};1350///1351/// #[derive(Component)]1352/// struct Position {1353/// x: f32,1354/// y: f32,1355/// }1356///1357/// let mut world = World::new();1358/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1359/// let position = world.get::<Position>(entity).unwrap();1360/// assert_eq!(position.x, 0.0);1361/// ```1362#[inline]1363pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {1364self.get_entity(entity).ok()?.get()1365}13661367/// Retrieves a mutable reference to the given `entity`'s [`Component`] of the given type.1368/// Returns `None` if the `entity` does not have a [`Component`] of the given type.1369/// ```1370/// use bevy_ecs::{component::Component, world::World};1371///1372/// #[derive(Component)]1373/// struct Position {1374/// x: f32,1375/// y: f32,1376/// }1377///1378/// let mut world = World::new();1379/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1380/// let mut position = world.get_mut::<Position>(entity).unwrap();1381/// position.x = 1.0;1382/// ```1383#[inline]1384pub fn get_mut<T: Component<Mutability = Mutable>>(1385&mut self,1386entity: Entity,1387) -> Option<Mut<'_, T>> {1388self.get_entity_mut(entity).ok()?.into_mut()1389}13901391/// Temporarily removes a [`Component`] `T` from the provided [`Entity`] and1392/// runs the provided closure on it, returning the result if `T` was available.1393/// This will trigger the `Remove` and `Discard` component hooks without1394/// causing an archetype move.1395///1396/// This is most useful with immutable components, where removal and reinsertion1397/// is the only way to modify a value.1398///1399/// If you do not need to ensure the above hooks are triggered, and your component1400/// is mutable, prefer using [`get_mut`](World::get_mut).1401///1402/// # Examples1403///1404/// ```rust1405/// # use bevy_ecs::prelude::*;1406/// #1407/// #[derive(Component, PartialEq, Eq, Debug)]1408/// #[component(immutable)]1409/// struct Foo(bool);1410///1411/// # let mut world = World::default();1412/// # world.register_component::<Foo>();1413/// #1414/// # let entity = world.spawn(Foo(false)).id();1415/// #1416/// world.modify_component(entity, |foo: &mut Foo| {1417/// foo.0 = true;1418/// });1419/// #1420/// # assert_eq!(world.get::<Foo>(entity), Some(&Foo(true)));1421/// ```1422#[inline]1423#[track_caller]1424pub fn modify_component<T: Component, R>(1425&mut self,1426entity: Entity,1427f: impl FnOnce(&mut T) -> R,1428) -> Result<Option<R>, EntityMutableFetchError> {1429let mut world = DeferredWorld::from(&mut *self);14301431let result = world.modify_component_with_relationship_hook_mode(1432entity,1433RelationshipHookMode::Run,1434f,1435)?;14361437self.flush();1438Ok(result)1439}14401441/// Temporarily removes a [`Component`] identified by the provided1442/// [`ComponentId`] from the provided [`Entity`] and runs the provided1443/// closure on it, returning the result if the component was available.1444/// This will trigger the `Remove` and `Discard` component hooks without1445/// causing an archetype move.1446///1447/// This is most useful with immutable components, where removal and reinsertion1448/// is the only way to modify a value.1449///1450/// If you do not need to ensure the above hooks are triggered, and your component1451/// is mutable, prefer using [`get_mut_by_id`](World::get_mut_by_id).1452///1453/// You should prefer the typed [`modify_component`](World::modify_component)1454/// whenever possible.1455#[inline]1456#[track_caller]1457pub fn modify_component_by_id<R>(1458&mut self,1459entity: Entity,1460component_id: ComponentId,1461f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,1462) -> Result<Option<R>, EntityMutableFetchError> {1463let mut world = DeferredWorld::from(&mut *self);14641465let result = world.modify_component_by_id_with_relationship_hook_mode(1466entity,1467component_id,1468RelationshipHookMode::Run,1469f,1470)?;14711472self.flush();1473Ok(result)1474}14751476/// Despawns the given [`Entity`], if it exists.1477/// This will also remove all of the entity's [`Components`](Component).1478///1479/// Returns `true` if the entity is successfully despawned and `false` if1480/// the entity does not exist.1481/// This counts despawning a not constructed entity as a success, and frees it to the allocator.1482/// See [entity](crate::entity) module docs for more about construction.1483///1484/// # Note1485///1486/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1487/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1488///1489/// ```1490/// use bevy_ecs::{component::Component, world::World};1491///1492/// #[derive(Component)]1493/// struct Position {1494/// x: f32,1495/// y: f32,1496/// }1497///1498/// let mut world = World::new();1499/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();1500/// assert!(world.despawn(entity));1501/// assert!(world.get_entity(entity).is_err());1502/// assert!(world.get::<Position>(entity).is_none());1503/// ```1504#[track_caller]1505#[inline]1506pub fn despawn(&mut self, entity: Entity) -> bool {1507if let Err(error) = self.despawn_with_caller(entity, MaybeLocation::caller()) {1508warn!("{error}");1509false1510} else {1511true1512}1513}15141515/// Despawns the given `entity`, if it exists. This will also remove all of the entity's1516/// [`Components`](Component).1517///1518/// Returns an [`EntityDespawnError`] if the entity is not spawned to be despawned.1519///1520/// # Note1521///1522/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1523/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1524#[track_caller]1525#[inline]1526pub fn try_despawn(&mut self, entity: Entity) -> Result<(), EntityDespawnError> {1527self.despawn_with_caller(entity, MaybeLocation::caller())1528}15291530#[inline]1531pub(crate) fn despawn_with_caller(1532&mut self,1533entity: Entity,1534caller: MaybeLocation,1535) -> Result<(), EntityDespawnError> {1536match self.get_entity_mut(entity) {1537Ok(entity) => {1538entity.despawn_with_caller(caller);1539Ok(())1540}1541// Only one entity.1542Err(EntityMutableFetchError::AliasedMutability(_)) => unreachable!(),1543Err(EntityMutableFetchError::NotSpawned(err)) => Err(EntityDespawnError(err)),1544}1545}15461547/// Performs [`try_despawn_no_free`](Self::try_despawn_no_free), warning on errors.1548/// See that method for more information.1549#[track_caller]1550#[inline]1551pub fn despawn_no_free(&mut self, entity: Entity) -> Option<Entity> {1552match self.despawn_no_free_with_caller(entity, MaybeLocation::caller()) {1553Ok(entity) => Some(entity),1554Err(error) => {1555warn!("{error}");1556None1557}1558}1559}15601561/// Despawns the given `entity`, if it exists.1562/// This will also remove all of the entity's [`Component`]s.1563///1564/// The *only* difference between this and [despawning](Self::despawn) an entity is that this does not release the `entity` to be reused.1565/// 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.1566/// In general, [`despawn`](Self::despawn) should be used instead, which automatically allows the row to be reused.1567///1568/// Returns the new [`Entity`] if of the despawned [`EntityIndex`](crate::entity::EntityIndex), which should eventually either be re-spawned or freed to the allocator.1569/// Returns an [`EntityDespawnError`] if the entity is not spawned.1570///1571/// # Note1572///1573/// This will also *despawn* the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured1574/// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1575///1576/// # Example1577///1578/// There is no simple example in which this would be practical, but one use for this is a custom entity allocator.1579/// Despawning internally calls this and frees the entity id to Bevy's default entity allocator.1580/// The same principal can be used to create custom allocators with additional properties.1581/// For example, this could be used to make an allocator that yields groups of consecutive [`EntityIndex`](crate::entity::EntityIndex)s, etc.1582/// See [`EntityAllocator::alloc`] for more on this.1583#[track_caller]1584#[inline]1585pub fn try_despawn_no_free(&mut self, entity: Entity) -> Result<Entity, EntityDespawnError> {1586self.despawn_no_free_with_caller(entity, MaybeLocation::caller())1587}15881589#[inline]1590pub(crate) fn despawn_no_free_with_caller(1591&mut self,1592entity: Entity,1593caller: MaybeLocation,1594) -> Result<Entity, EntityDespawnError> {1595let mut entity = self.get_entity_mut(entity).map_err(|err| match err {1596EntityMutableFetchError::NotSpawned(err) => err,1597// Only one entity.1598EntityMutableFetchError::AliasedMutability(_) => unreachable!(),1599})?;1600entity.despawn_no_free_with_caller(caller);1601Ok(entity.id())1602}16031604/// Clears the internal component tracker state.1605///1606/// The world maintains some internal state about changed and removed components. This state1607/// is used by [`RemovedComponents`] to provide access to the entities that had a specific type1608/// of component removed since last tick.1609///1610/// The state is also used for change detection when accessing components and resources outside1611/// of a system, for example via [`World::get_mut()`] or [`World::get_resource_mut()`].1612///1613/// By clearing this internal state, the world "forgets" about those changes, allowing a new round1614/// of detection to be recorded.1615///1616/// When using `bevy_ecs` as part of the full Bevy engine, this method is called automatically1617/// by `bevy_app::App::update` and `bevy_app::SubApp::update`, so you don't need to call it manually.1618/// When using `bevy_ecs` as a separate standalone crate however, you do need to call this manually.1619///1620/// ```1621/// # use bevy_ecs::prelude::*;1622/// # #[derive(Component, Default)]1623/// # struct Transform;1624/// // a whole new world1625/// let mut world = World::new();1626///1627/// // you changed it1628/// let entity = world.spawn(Transform::default()).id();1629///1630/// // change is detected1631/// let transform = world.get_mut::<Transform>(entity).unwrap();1632/// assert!(transform.is_changed());1633///1634/// // update the last change tick1635/// world.clear_trackers();1636///1637/// // change is no longer detected1638/// let transform = world.get_mut::<Transform>(entity).unwrap();1639/// assert!(!transform.is_changed());1640/// ```1641///1642/// [`RemovedComponents`]: crate::lifecycle::RemovedComponents1643pub fn clear_trackers(&mut self) {1644self.removed_components.update();1645self.last_change_tick = self.increment_change_tick();1646}16471648/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1649/// run queries on the [`World`] by storing and reusing the [`QueryState`].1650/// ```1651/// use bevy_ecs::{component::Component, entity::Entity, world::World};1652///1653/// #[derive(Component, Debug, PartialEq)]1654/// struct Position {1655/// x: f32,1656/// y: f32,1657/// }1658///1659/// #[derive(Component)]1660/// struct Velocity {1661/// x: f32,1662/// y: f32,1663/// }1664///1665/// let mut world = World::new();1666/// let entities = world.spawn_batch(vec![1667/// (Position { x: 0.0, y: 0.0}, Velocity { x: 1.0, y: 0.0 }),1668/// (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }),1669/// ]).collect::<Vec<Entity>>();1670///1671/// let mut query = world.query::<(&mut Position, &Velocity)>();1672/// for (mut position, velocity) in query.iter_mut(&mut world) {1673/// position.x += velocity.x;1674/// position.y += velocity.y;1675/// }1676///1677/// assert_eq!(world.get::<Position>(entities[0]).unwrap(), &Position { x: 1.0, y: 0.0 });1678/// assert_eq!(world.get::<Position>(entities[1]).unwrap(), &Position { x: 0.0, y: 1.0 });1679/// ```1680///1681/// To iterate over entities in a deterministic order,1682/// sort the results of the query using the desired component as a key.1683/// Note that this requires fetching the whole result set from the query1684/// and allocation of a [`Vec`] to store it.1685///1686/// ```1687/// use bevy_ecs::{component::Component, entity::Entity, world::World};1688///1689/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Debug)]1690/// struct Order(i32);1691/// #[derive(Component, PartialEq, Debug)]1692/// struct Label(&'static str);1693///1694/// let mut world = World::new();1695/// let a = world.spawn((Order(2), Label("second"))).id();1696/// let b = world.spawn((Order(3), Label("third"))).id();1697/// let c = world.spawn((Order(1), Label("first"))).id();1698/// let mut entities = world.query::<(Entity, &Order, &Label)>()1699/// .iter(&world)1700/// .collect::<Vec<_>>();1701/// // Sort the query results by their `Order` component before comparing1702/// // to expected results. Query iteration order should not be relied on.1703/// entities.sort_by_key(|e| e.1);1704/// assert_eq!(entities, vec![1705/// (c, &Order(1), &Label("first")),1706/// (a, &Order(2), &Label("second")),1707/// (b, &Order(3), &Label("third")),1708/// ]);1709/// ```1710#[inline]1711pub fn query<D: QueryData>(&mut self) -> QueryState<D, ()> {1712self.query_filtered::<D, ()>()1713}17141715/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1716/// run queries on the [`World`] by storing and reusing the [`QueryState`].1717/// ```1718/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1719///1720/// #[derive(Component)]1721/// struct A;1722/// #[derive(Component)]1723/// struct B;1724///1725/// let mut world = World::new();1726/// let e1 = world.spawn(A).id();1727/// let e2 = world.spawn((A, B)).id();1728///1729/// let mut query = world.query_filtered::<Entity, With<B>>();1730/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1731///1732/// assert_eq!(matching_entities, vec![e2]);1733/// ```1734#[inline]1735pub fn query_filtered<D: QueryData, F: QueryFilter>(&mut self) -> QueryState<D, F> {1736QueryState::new(self)1737}17381739/// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently1740/// run queries on the [`World`] by storing and reusing the [`QueryState`].1741/// ```1742/// use bevy_ecs::{component::Component, entity::Entity, world::World};1743///1744/// #[derive(Component, Debug, PartialEq)]1745/// struct Position {1746/// x: f32,1747/// y: f32,1748/// }1749///1750/// let mut world = World::new();1751/// world.spawn_batch(vec![1752/// Position { x: 0.0, y: 0.0 },1753/// Position { x: 1.0, y: 1.0 },1754/// ]);1755///1756/// fn get_positions(world: &World) -> Vec<(Entity, &Position)> {1757/// let mut query = world.try_query::<(Entity, &Position)>().unwrap();1758/// query.iter(world).collect()1759/// }1760///1761/// let positions = get_positions(&world);1762///1763/// assert_eq!(world.get::<Position>(positions[0].0).unwrap(), positions[0].1);1764/// assert_eq!(world.get::<Position>(positions[1].0).unwrap(), positions[1].1);1765/// ```1766///1767/// Requires only an immutable world reference, but may fail if, for example,1768/// the components that make up this query have not been registered into the world.1769/// ```1770/// use bevy_ecs::{component::Component, entity::Entity, world::World};1771///1772/// #[derive(Component)]1773/// struct A;1774///1775/// let mut world = World::new();1776///1777/// let none_query = world.try_query::<&A>();1778/// assert!(none_query.is_none());1779///1780/// world.register_component::<A>();1781///1782/// let some_query = world.try_query::<&A>();1783/// assert!(some_query.is_some());1784/// ```1785#[inline]1786pub fn try_query<D: QueryData>(&self) -> Option<QueryState<D, ()>> {1787self.try_query_filtered::<D, ()>()1788}17891790/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently1791/// run queries on the [`World`] by storing and reusing the [`QueryState`].1792/// ```1793/// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};1794///1795/// #[derive(Component)]1796/// struct A;1797/// #[derive(Component)]1798/// struct B;1799///1800/// let mut world = World::new();1801/// let e1 = world.spawn(A).id();1802/// let e2 = world.spawn((A, B)).id();1803///1804/// let mut query = world.try_query_filtered::<Entity, With<B>>().unwrap();1805/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();1806///1807/// assert_eq!(matching_entities, vec![e2]);1808/// ```1809///1810/// Requires only an immutable world reference, but may fail if, for example,1811/// the components that make up this query have not been registered into the world.1812#[inline]1813pub fn try_query_filtered<D: QueryData, F: QueryFilter>(&self) -> Option<QueryState<D, F>> {1814QueryState::try_new(self)1815}18161817/// Returns an iterator of entities that had components of type `T` removed1818/// since the last call to [`World::clear_trackers`].1819pub fn removed<T: Component>(&self) -> impl Iterator<Item = Entity> + '_ {1820self.components1821.get_valid_id(TypeId::of::<T>())1822.map(|component_id| self.removed_with_id(component_id))1823.into_iter()1824.flatten()1825}18261827/// Returns an iterator of entities that had components with the given `component_id` removed1828/// since the last call to [`World::clear_trackers`].1829pub fn removed_with_id(&self, component_id: ComponentId) -> impl Iterator<Item = Entity> + '_ {1830self.removed_components1831.get(component_id)1832.map(|removed| removed.iter_current_update_messages().cloned())1833.into_iter()1834.flatten()1835.map(Into::into)1836}18371838/// Registers a new non-send resource type and returns the [`ComponentId`] created for it.1839///1840/// This enables the dynamic registration of new non-send resources definitions at runtime for1841/// advanced use cases.1842///1843/// # Note1844///1845/// Registering a non-send resource does not insert it into [`World`]. For insertion, you could use1846/// [`World::insert_non_send_by_id`].1847pub fn register_non_send_with_descriptor(1848&mut self,1849descriptor: ComponentDescriptor,1850) -> ComponentId {1851self.components_registrator()1852.register_component_with_descriptor(descriptor)1853}18541855fn insert_resource_if_not_exists_with_caller<R: Resource>(1856&mut self,1857func: impl FnOnce(&mut World) -> R,1858caller: MaybeLocation,1859) -> (ComponentId, EntityWorldMut<'_>) {1860let resource_id = self.register_resource::<R>();18611862if let Some(&entity) = self.resource_entities.get(resource_id) {1863let entity_ref = self.get_entity(entity).expect("ResourceCache is in sync");1864if !entity_ref.contains_id(resource_id) {1865let resource = func(self);1866move_as_ptr!(resource);1867self.entity_mut(entity).insert_with_caller(1868resource,1869InsertMode::Replace,1870caller,1871RelationshipHookMode::Run,1872);1873}1874return (resource_id, self.entity_mut(entity));1875}18761877let resource = func(self);1878move_as_ptr!(resource);1879let entity_mut = self.spawn_with_caller(resource, caller); // ResourceCache is updated automatically1880(resource_id, entity_mut)1881}18821883/// Initializes a new resource and returns the [`ComponentId`] created for it.1884///1885/// If the resource already exists, nothing happens.1886///1887/// The value given by the [`FromWorld::from_world`] method will be used.1888/// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],1889/// and those default values will be here instead.1890#[inline]1891#[track_caller]1892pub fn init_resource<R: Resource + FromWorld>(&mut self) -> ComponentId {1893let caller = MaybeLocation::caller();1894self.insert_resource_if_not_exists_with_caller(R::from_world, caller)1895.01896}18971898/// Inserts a new resource with the given `value`.1899///1900/// Resources are "unique" data of a given type.1901/// If you insert a resource of a type that already exists,1902/// you will overwrite any existing data.1903#[inline]1904#[track_caller]1905pub fn insert_resource<R: Resource>(&mut self, value: R) {1906self.insert_resource_with_caller(value, MaybeLocation::caller());1907}19081909/// Split into a new function so we can pass the calling location into the function when using1910/// as a command.1911#[inline]1912pub(crate) fn insert_resource_with_caller<R: Resource>(1913&mut self,1914value: R,1915caller: MaybeLocation,1916) {1917let component_id = self.components_registrator().register_component::<R>();1918OwningPtr::make(value, |ptr| {1919// SAFETY: component_id was just initialized and corresponds to resource of type R.1920unsafe {1921self.insert_resource_by_id(component_id, ptr, caller);1922}1923});1924}19251926/// Initializes a new non-send resource and returns the [`ComponentId`] created for it.1927#[deprecated(since = "0.19.0", note = "use World::init_non_send")]1928pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> ComponentId {1929self.init_non_send::<R>()1930}19311932/// Initializes new non-send data and returns the [`ComponentId`] created for it.1933///1934/// If the data already exists, nothing happens.1935///1936/// The value given by the [`FromWorld::from_world`] method will be used.1937/// Note that any non-send data with the `Default` trait automatically implements1938/// `FromWorld`, and those default values will be here instead.1939///1940/// # Panics1941///1942/// Panics if called from a thread other than the main thread.1943#[inline]1944#[track_caller]1945pub fn init_non_send<R: 'static + FromWorld>(&mut self) -> ComponentId {1946let caller = MaybeLocation::caller();1947let component_id = self.components_registrator().register_non_send::<R>();1948if self1949.storages1950.non_sends1951.get(component_id)1952.is_none_or(|data| !data.is_present())1953{1954let value = R::from_world(self);1955OwningPtr::make(value, |ptr| {1956// SAFETY: component_id was just initialized and corresponds to resource of type R.1957unsafe {1958self.insert_non_send_by_id(component_id, ptr, caller);1959}1960});1961}1962component_id1963}19641965/// Inserts a new non-send resource with the given `value`.1966#[deprecated(since = "0.19.0", note = "use World::insert_non_send")]1967pub fn insert_non_send_resource<R: 'static>(&mut self, value: R) {1968self.insert_non_send(value);1969}19701971/// Inserts new non-send data with the given `value`.1972///1973/// `NonSend` data cannot be sent across threads,1974/// and do not need the `Send + Sync` bounds.1975/// Systems with `NonSend` resources are always scheduled on the main thread.1976///1977/// # Panics1978/// If a value is already present, this function will panic if called1979/// from a different thread than where the original value was inserted from.1980#[inline]1981#[track_caller]1982pub fn insert_non_send<R: 'static>(&mut self, value: R) {1983let caller = MaybeLocation::caller();1984let component_id = self.components_registrator().register_non_send::<R>();1985OwningPtr::make(value, |ptr| {1986// SAFETY: component_id was just initialized and corresponds to the data of type R.1987unsafe {1988self.insert_non_send_by_id(component_id, ptr, caller);1989}1990});1991}19921993/// Removes the resource of a given type and returns it, if it exists. Otherwise returns `None`.1994#[inline]1995pub fn remove_resource<R: Resource>(&mut self) -> Option<R> {1996let resource_id = self.component_id::<R>()?;1997let entity = *self.resource_entities.get(resource_id)?;1998let value = self1999.get_entity_mut(entity)2000.expect("ResourceCache is in sync")2001.take::<R>()?;2002Some(value)2003}20042005/// Removes a `!Send` resource from the world and returns it, if present.2006#[deprecated(since = "0.19.0", note = "use World::remove_non_send")]2007pub fn remove_non_send_resource<R: 'static>(&mut self) -> Option<R> {2008self.remove_non_send::<R>()2009}20102011/// Removes `!Send` data from the world and returns it, if present.2012///2013/// `NonSend` resources cannot be sent across threads,2014/// and do not need the `Send + Sync` bounds.2015/// Systems with `NonSend` data are always scheduled on the main thread.2016///2017/// Returns `None` if a value was not previously present.2018///2019/// # Panics2020/// If a value is present, this function will panic if called from a different2021/// thread than where the value was inserted from.2022#[inline]2023pub fn remove_non_send<R: 'static>(&mut self) -> Option<R> {2024let component_id = self.components.get_valid_id(TypeId::of::<R>())?;2025let (ptr, _, _) = self.storages.non_sends.get_mut(component_id)?.remove()?;2026// SAFETY: `component_id` was gotten via looking up the `R` type2027unsafe { Some(ptr.read::<R>()) }2028}20292030/// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.2031#[inline]2032pub fn contains_resource<R: Resource>(&self) -> bool {2033self.components2034.get_valid_id(TypeId::of::<R>())2035.is_some_and(|component_id| self.contains_resource_by_id(component_id))2036}20372038/// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.2039#[inline]2040pub fn contains_resource_by_id(&self, component_id: ComponentId) -> bool {2041if let Some(entity) = self.resource_entities.get(component_id)2042&& let Ok(entity_ref) = self.get_entity(*entity)2043{2044return entity_ref.contains_id(component_id);2045}2046false2047}20482049/// Returns `true` if `!Send` data of type `R` exists. Otherwise returns `false`.2050#[inline]2051pub fn contains_non_send<R: 'static>(&self) -> bool {2052self.components2053.get_valid_id(TypeId::of::<R>())2054.and_then(|component_id| self.storages.non_sends.get(component_id))2055.is_some_and(NonSendData::is_present)2056}20572058/// Returns `true` if `!Send` data with `component_id` exists. Otherwise returns `false`.2059#[inline]2060pub fn contains_non_send_by_id(&self, component_id: ComponentId) -> bool {2061self.storages2062.non_sends2063.get(component_id)2064.is_some_and(NonSendData::is_present)2065}20662067/// Returns `true` if a resource of type `R` exists and was added since the world's2068/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2069///2070/// This means that:2071/// - When called from an exclusive system, this will check for additions since the system last ran.2072/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]2073/// was called.2074pub fn is_resource_added<R: Resource>(&self) -> bool {2075self.components2076.get_valid_id(TypeId::of::<R>())2077.is_some_and(|component_id| self.is_resource_added_by_id(component_id))2078}20792080/// Returns `true` if a resource with id `component_id` exists and was added since the world's2081/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2082///2083/// This means that:2084/// - When called from an exclusive system, this will check for additions since the system last ran.2085/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]2086/// was called.2087pub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool {2088self.get_resource_change_ticks_by_id(component_id)2089.is_some_and(|ticks| ticks.is_added(self.last_change_tick(), self.read_change_tick()))2090}20912092/// Returns `true` if a resource of type `R` exists and was modified since the world's2093/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2094///2095/// This means that:2096/// - When called from an exclusive system, this will check for changes since the system last ran.2097/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]2098/// was called.2099pub fn is_resource_changed<R: Resource>(&self) -> bool {2100self.components2101.get_valid_id(TypeId::of::<R>())2102.is_some_and(|component_id| self.is_resource_changed_by_id(component_id))2103}21042105/// Returns `true` if a resource with id `component_id` exists and was modified since the world's2106/// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.2107///2108/// This means that:2109/// - When called from an exclusive system, this will check for changes since the system last ran.2110/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]2111/// was called.2112pub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool {2113self.get_resource_change_ticks_by_id(component_id)2114.is_some_and(|ticks| ticks.is_changed(self.last_change_tick(), self.read_change_tick()))2115}21162117/// Retrieves the change ticks for the given resource.2118pub fn get_resource_change_ticks<R: Resource>(&self) -> Option<ComponentTicks> {2119self.components2120.get_valid_id(TypeId::of::<R>())2121.and_then(|component_id| self.get_resource_change_ticks_by_id(component_id))2122}21232124/// Retrieves the change ticks for the given [`ComponentId`].2125///2126/// **You should prefer to use the typed API [`World::get_resource_change_ticks`] where possible.**2127pub fn get_resource_change_ticks_by_id(2128&self,2129component_id: ComponentId,2130) -> Option<ComponentTicks> {2131let entity = self.resource_entities.get(component_id)?;2132let entity_ref = self.get_entity(*entity).ok()?;2133entity_ref.get_change_ticks_by_id(component_id)2134}21352136/// Gets a reference to the resource of the given type2137///2138/// # Panics2139///2140/// Panics if the resource does not exist.2141/// Use [`get_resource`](World::get_resource) instead if you want to handle this case.2142///2143/// If you want to instead insert a value if the resource does not exist,2144/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2145#[inline]2146#[track_caller]2147pub fn resource<R: Resource>(&self) -> &R {2148match self.get_resource() {2149Some(x) => x,2150None => panic!(2151"Requested resource {} does not exist in the `World`.2152Did you forget to add it using `app.insert_resource` / `app.init_resource`?2153Resources are also implicitly added via `app.add_message`,2154and can be added by plugins.",2155DebugName::type_name::<R>()2156),2157}2158}21592160/// Gets a reference to the resource of the given type2161///2162/// # Panics2163///2164/// Panics if the resource does not exist.2165/// Use [`get_resource_ref`](World::get_resource_ref) instead if you want to handle this case.2166///2167/// If you want to instead insert a value if the resource does not exist,2168/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2169#[inline]2170#[track_caller]2171pub fn resource_ref<R: Resource>(&self) -> Ref<'_, R> {2172match self.get_resource_ref() {2173Some(x) => x,2174None => panic!(2175"Requested resource {} does not exist in the `World`.2176Did you forget to add it using `app.insert_resource` / `app.init_resource`?2177Resources are also implicitly added via `app.add_message`,2178and can be added by plugins.",2179DebugName::type_name::<R>()2180),2181}2182}21832184/// Gets a mutable reference to the resource of the given type2185///2186/// # Panics2187///2188/// Panics if the resource does not exist.2189/// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.2190///2191/// If you want to instead insert a value if the resource does not exist,2192/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).2193#[inline]2194#[track_caller]2195pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {2196match self.get_resource_mut() {2197Some(x) => x,2198None => panic!(2199"Requested resource {} does not exist in the `World`.2200Did you forget to add it using `app.insert_resource` / `app.init_resource`?2201Resources are also implicitly added via `app.add_message`,2202and can be added by plugins.",2203DebugName::type_name::<R>()2204),2205}2206}22072208/// Gets a reference to the resource of the given type if it exists2209#[inline]2210pub fn get_resource<R: Resource>(&self) -> Option<&R> {2211// SAFETY:2212// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2213// - `&self` ensures nothing in world is borrowed mutably2214unsafe { self.as_unsafe_world_cell_readonly().get_resource() }2215}22162217/// Gets a reference including change detection to the resource of the given type if it exists.2218#[inline]2219pub fn get_resource_ref<R: Resource>(&self) -> Option<Ref<'_, R>> {2220// SAFETY:2221// - `as_unsafe_world_cell_readonly` gives permission to access everything immutably2222// - `&self` ensures nothing in world is borrowed mutably2223unsafe { self.as_unsafe_world_cell_readonly().get_resource_ref() }2224}22252226/// Gets a mutable reference to the resource of the given type if it exists2227#[inline]2228pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {2229// SAFETY:2230// - `as_unsafe_world_cell` gives permission to access everything mutably2231// - `&mut self` ensures nothing in world is borrowed2232unsafe { self.as_unsafe_world_cell().get_resource_mut() }2233}22342235/// Gets a mutable reference to the resource of type `T` if it exists,2236/// otherwise inserts the resource using the result of calling `func`.2237///2238/// # Example2239///2240/// ```2241/// # use bevy_ecs::prelude::*;2242/// #2243/// #[derive(Resource)]2244/// struct MyResource(i32);2245///2246/// # let mut world = World::new();2247/// let my_res = world.get_resource_or_insert_with(|| MyResource(10));2248/// assert_eq!(my_res.0, 10);2249/// ```2250#[inline]2251#[track_caller]2252pub fn get_resource_or_insert_with<R: Resource>(2253&mut self,2254func: impl FnOnce() -> R,2255) -> Mut<'_, R> {2256let caller = MaybeLocation::caller();2257let (resource_id, entity) =2258self.insert_resource_if_not_exists_with_caller(|_world: &mut World| func(), caller);2259let untyped = entity2260.into_mut_by_id(resource_id)2261.expect("Resource must exist");2262// SAFETY: resource is of type R2263unsafe { untyped.with_type() }2264}22652266/// Gets a mutable reference to the resource of type `T` if it exists,2267/// otherwise initializes the resource by calling its [`FromWorld`]2268/// implementation.2269///2270/// # Example2271///2272/// ```2273/// # use bevy_ecs::prelude::*;2274/// #2275/// #[derive(Resource)]2276/// struct Foo(i32);2277///2278/// impl Default for Foo {2279/// fn default() -> Self {2280/// Self(15)2281/// }2282/// }2283///2284/// #[derive(Resource)]2285/// struct MyResource(i32);2286///2287/// impl FromWorld for MyResource {2288/// fn from_world(world: &mut World) -> Self {2289/// let foo = world.get_resource_or_init::<Foo>();2290/// Self(foo.0 * 2)2291/// }2292/// }2293///2294/// # let mut world = World::new();2295/// let my_res = world.get_resource_or_init::<MyResource>();2296/// assert_eq!(my_res.0, 30);2297/// ```2298#[track_caller]2299pub fn get_resource_or_init<R: Resource + FromWorld>(&mut self) -> Mut<'_, R> {2300let caller = MaybeLocation::caller();2301let (resource_id, entity) =2302self.insert_resource_if_not_exists_with_caller(R::from_world, caller);2303let untyped = entity2304.into_mut_by_id(resource_id)2305.expect("Resource must exist");2306// SAFETY: resource is of type R2307unsafe { untyped.with_type() }2308}23092310/// Gets an immutable reference to a non-send resource of the given type, if it exists.2311#[deprecated(since = "0.19.0", note = "use World::non_send")]2312pub fn non_send_resource<R: 'static>(&self) -> &R {2313self.non_send::<R>()2314}23152316/// Gets an immutable reference to the non-send data of the given type, if it exists.2317///2318/// # Panics2319///2320/// Panics if the data does not exist.2321/// Use [`get_non_send`](World::get_non_send) instead if you want to handle this case.2322///2323/// This function will panic if it isn't called from the same thread that the resource was inserted from.2324#[inline]2325#[track_caller]2326pub fn non_send<R: 'static>(&self) -> &R {2327match self.get_non_send() {2328Some(x) => x,2329None => panic!(2330"Requested non-send resource {} does not exist in the `World`.2331Did you forget to add it using `app.insert_non_send` / `app.init_non_send`?2332Non-send resources can also be added by plugins.",2333DebugName::type_name::<R>()2334),2335}2336}23372338/// Gets a mutable reference to a non-send resource of the given type, if it exists.2339#[deprecated(since = "0.19.0", note = "use World::non_send_mut")]2340pub fn non_send_resource_mut<R: 'static>(&mut self) -> Mut<'_, R> {2341self.non_send_mut::<R>()2342}23432344/// Gets a mutable reference to the non-send data of the given type, if it exists.2345///2346/// # Panics2347///2348/// Panics if the data does not exist.2349/// Use [`get_non_send_mut`](World::get_non_send_mut) instead if you want to handle this case.2350///2351/// This function will panic if it isn't called from the same thread that the resource was inserted from.2352#[inline]2353#[track_caller]2354pub fn non_send_mut<R: 'static>(&mut self) -> Mut<'_, R> {2355match self.get_non_send_mut() {2356Some(x) => x,2357None => panic!(2358"Requested non-send resource {} does not exist in the `World`.2359Did you forget to add it using `app.insert_non_send` / `app.init_non_send`?2360Non-send resources can also be added by plugins.",2361DebugName::type_name::<R>()2362),2363}2364}23652366/// Gets a reference to a non-send resource of the given type, if it exists.2367/// Otherwise returns `None`.2368#[deprecated(since = "0.19.0", note = "use World::get_non_send")]2369pub fn get_non_send_resource<R: 'static>(&self) -> Option<&R> {2370self.get_non_send::<R>()2371}23722373/// Gets a reference to the non-send data of the given type, if it exists.2374/// Otherwise returns `None`.2375///2376/// # Panics2377/// This function will panic if it isn't called from the same thread that the resource was inserted from.2378#[inline]2379pub fn get_non_send<R: 'static>(&self) -> Option<&R> {2380// SAFETY:2381// - `as_unsafe_world_cell_readonly` gives permission to access the entire world immutably2382// - `&self` ensures that there are no mutable borrows of world data2383unsafe { self.as_unsafe_world_cell_readonly().get_non_send() }2384}23852386/// Gets a mutable reference to a non-send resource of the given type, if it exists.2387/// Otherwise returns `None`.2388#[deprecated(since = "0.19.0", note = "use World::get_non_send_mut")]2389pub fn get_non_send_resource_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {2390self.get_non_send_mut::<R>()2391}23922393/// Gets a mutable reference to the non-send data of the given type, if it exists.2394/// Otherwise returns `None`.2395///2396/// # Panics2397/// This function will panic if it isn't called from the same thread that the resource was inserted from.2398#[inline]2399pub fn get_non_send_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {2400// SAFETY:2401// - `as_unsafe_world_cell` gives permission to access the entire world mutably2402// - `&mut self` ensures that there are no borrows of world data2403unsafe { self.as_unsafe_world_cell().get_non_send_mut() }2404}24052406/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2407/// adds the `Bundle` of components to each `Entity`.2408/// This is faster than doing equivalent operations one-by-one.2409///2410/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2411/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2412///2413/// This will overwrite any previous values of components shared by the `Bundle`.2414/// See [`World::insert_batch_if_new`] to keep the old values instead.2415///2416/// # Panics2417///2418/// This function will panic if any of the associated entities do not exist.2419///2420/// For the fallible version, see [`World::try_insert_batch`].2421#[track_caller]2422pub fn insert_batch<I, B>(&mut self, batch: I)2423where2424I: IntoIterator,2425I::IntoIter: Iterator<Item = (Entity, B)>,2426B: Bundle<Effect: NoBundleEffect>,2427{2428self.insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller());2429}24302431/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2432/// adds the `Bundle` of components to each `Entity` without overwriting.2433/// This is faster than doing equivalent operations one-by-one.2434///2435/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2436/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2437///2438/// This is the same as [`World::insert_batch`], but in case of duplicate2439/// components it will leave the old values instead of replacing them with new ones.2440///2441/// # Panics2442///2443/// This function will panic if any of the associated entities do not exist.2444///2445/// For the fallible version, see [`World::try_insert_batch_if_new`].2446#[track_caller]2447pub fn insert_batch_if_new<I, B>(&mut self, batch: I)2448where2449I: IntoIterator,2450I::IntoIter: Iterator<Item = (Entity, B)>,2451B: Bundle<Effect: NoBundleEffect>,2452{2453self.insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller());2454}24552456/// Split into a new function so we can differentiate the calling location.2457///2458/// This can be called by:2459/// - [`World::insert_batch`]2460/// - [`World::insert_batch_if_new`]2461#[inline]2462pub(crate) fn insert_batch_with_caller<I, B>(2463&mut self,2464batch: I,2465insert_mode: InsertMode,2466caller: MaybeLocation,2467) where2468I: IntoIterator,2469I::IntoIter: Iterator<Item = (Entity, B)>,2470B: Bundle<Effect: NoBundleEffect>,2471{2472struct InserterArchetypeCache<'w> {2473inserter: BundleInserter<'w>,2474archetype_id: ArchetypeId,2475}24762477let change_tick = self.change_tick();2478let bundle_id = self.register_bundle_info::<B>();24792480let mut batch_iter = batch.into_iter();24812482if let Some((first_entity, first_bundle)) = batch_iter.next() {2483match self.entities().get_spawned(first_entity) {2484Err(err) => {2485panic!("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>());2486}2487Ok(first_location) => {2488let mut cache = InserterArchetypeCache {2489// SAFETY: we initialized this bundle_id in `register_info`2490inserter: unsafe {2491BundleInserter::new_with_id(2492self,2493first_location.archetype_id,2494bundle_id,2495change_tick,2496)2497},2498archetype_id: first_location.archetype_id,2499};2500move_as_ptr!(first_bundle);2501// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2502unsafe {2503cache.inserter.insert(2504first_entity,2505first_location,2506first_bundle,2507insert_mode,2508caller,2509RelationshipHookMode::Run,2510)2511};25122513for (entity, bundle) in batch_iter {2514match cache.inserter.entities().get_spawned(entity) {2515Ok(location) => {2516if location.archetype_id != cache.archetype_id {2517cache = InserterArchetypeCache {2518// SAFETY: we initialized this bundle_id in `register_info`2519inserter: unsafe {2520BundleInserter::new_with_id(2521self,2522location.archetype_id,2523bundle_id,2524change_tick,2525)2526},2527archetype_id: location.archetype_id,2528}2529}2530move_as_ptr!(bundle);2531// SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter2532unsafe {2533cache.inserter.insert(2534entity,2535location,2536bundle,2537insert_mode,2538caller,2539RelationshipHookMode::Run,2540)2541};2542}2543Err(err) => {2544panic!("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>());2545}2546}2547}2548}2549}2550}2551}25522553/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2554/// adds the `Bundle` of components to each `Entity`.2555/// This is faster than doing equivalent operations one-by-one.2556///2557/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2558/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2559///2560/// This will overwrite any previous values of components shared by the `Bundle`.2561/// See [`World::try_insert_batch_if_new`] to keep the old values instead.2562///2563/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2564///2565/// For the panicking version, see [`World::insert_batch`].2566#[track_caller]2567pub fn try_insert_batch<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2568where2569I: IntoIterator,2570I::IntoIter: Iterator<Item = (Entity, B)>,2571B: Bundle<Effect: NoBundleEffect>,2572{2573self.try_insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller())2574}2575/// For a given batch of ([`Entity`], [`Bundle`]) pairs,2576/// adds the `Bundle` of components to each `Entity` without overwriting.2577/// This is faster than doing equivalent operations one-by-one.2578///2579/// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,2580/// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.2581///2582/// This is the same as [`World::try_insert_batch`], but in case of duplicate2583/// components it will leave the old values instead of replacing them with new ones.2584///2585/// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.2586///2587/// For the panicking version, see [`World::insert_batch_if_new`].2588#[track_caller]2589pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>2590where2591I: IntoIterator,2592I::IntoIter: Iterator<Item = (Entity, B)>,2593B: Bundle<Effect: NoBundleEffect>,2594{2595self.try_insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller())2596}25972598/// Split into a new function so we can differentiate the calling location.2599///2600/// This can be called by:2601/// - [`World::try_insert_batch`]2602/// - [`World::try_insert_batch_if_new`]2603/// - [`Commands::insert_batch`]2604/// - [`Commands::insert_batch_if_new`]2605/// - [`Commands::try_insert_batch`]2606/// - [`Commands::try_insert_batch_if_new`]2607#[inline]2608pub(crate) fn try_insert_batch_with_caller<I, B>(2609&mut self,2610batch: I,2611insert_mode: InsertMode,2612caller: MaybeLocation,2613) -> Result<(), TryInsertBatchError>2614where2615I: IntoIterator,2616I::IntoIter: Iterator<Item = (Entity, B)>,2617B: Bundle<Effect: NoBundleEffect>,2618{2619struct InserterArchetypeCache<'w> {2620inserter: BundleInserter<'w>,2621archetype_id: ArchetypeId,2622}26232624let change_tick = self.change_tick();2625let bundle_id = self.register_bundle_info::<B>();26262627let mut invalid_entities = Vec::<Entity>::new();2628let mut batch_iter = batch.into_iter();26292630// We need to find the first valid entity so we can initialize the bundle inserter.2631// This differs from `insert_batch_with_caller` because that method can just panic2632// if the first entity is invalid, whereas this method needs to keep going.2633let cache = loop {2634if let Some((first_entity, first_bundle)) = batch_iter.next() {2635if let Ok(first_location) = self.entities().get_spawned(first_entity) {2636let mut cache = InserterArchetypeCache {2637// SAFETY: we initialized this bundle_id in `register_bundle_info`2638inserter: unsafe {2639BundleInserter::new_with_id(2640self,2641first_location.archetype_id,2642bundle_id,2643change_tick,2644)2645},2646archetype_id: first_location.archetype_id,2647};26482649move_as_ptr!(first_bundle);2650// SAFETY:2651// - `entity` is valid, `location` matches entity, bundle matches inserter2652// - `apply_effect` is never called on this bundle.2653// - `first_bundle` is not be accessed or dropped after this.2654unsafe {2655cache.inserter.insert(2656first_entity,2657first_location,2658first_bundle,2659insert_mode,2660caller,2661RelationshipHookMode::Run,2662)2663};2664break Some(cache);2665}2666invalid_entities.push(first_entity);2667} else {2668// We reached the end of the entities the caller provided and none were valid.2669break None;2670}2671};26722673if let Some(mut cache) = cache {2674for (entity, bundle) in batch_iter {2675if let Ok(location) = cache.inserter.entities().get_spawned(entity) {2676if location.archetype_id != cache.archetype_id {2677cache = InserterArchetypeCache {2678// SAFETY: we initialized this bundle_id in `register_info`2679inserter: unsafe {2680BundleInserter::new_with_id(2681self,2682location.archetype_id,2683bundle_id,2684change_tick,2685)2686},2687archetype_id: location.archetype_id,2688}2689}26902691move_as_ptr!(bundle);2692// SAFETY:2693// - `entity` is valid, `location` matches entity, bundle matches inserter2694// - `apply_effect` is never called on this bundle.2695// - `bundle` is not be accessed or dropped after this.2696unsafe {2697cache.inserter.insert(2698entity,2699location,2700bundle,2701insert_mode,2702caller,2703RelationshipHookMode::Run,2704)2705};2706} else {2707invalid_entities.push(entity);2708}2709}2710}27112712if invalid_entities.is_empty() {2713Ok(())2714} else {2715Err(TryInsertBatchError {2716bundle_type: DebugName::type_name::<B>(),2717entities: invalid_entities,2718})2719}2720}27212722/// Temporarily removes the requested resource from this [`World`], runs custom user code,2723/// then re-adds the resource before returning.2724///2725/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2726/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2727///2728/// # Panics2729///2730/// Panics if the resource does not exist.2731/// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.2732///2733/// # Example2734/// ```2735/// use bevy_ecs::prelude::*;2736/// #[derive(Resource)]2737/// struct A(u32);2738/// #[derive(Component)]2739/// struct B(u32);2740/// let mut world = World::new();2741/// world.insert_resource(A(1));2742/// let entity = world.spawn(B(1)).id();2743///2744/// world.resource_scope(|world, mut a: Mut<A>| {2745/// let b = world.get_mut::<B>(entity).unwrap();2746/// a.0 += b.0;2747/// });2748/// assert_eq!(world.get_resource::<A>().unwrap().0, 2);2749/// ```2750///2751/// # Note2752///2753/// If the world's resource metadata is cleared within the scope, such as by calling2754/// [`World::clear_resources`] or [`World::clear_all`], the resource will *not* be re-inserted2755/// at the end of the scope.2756#[track_caller]2757pub fn resource_scope<R: Resource, U>(&mut self, f: impl FnOnce(&mut World, Mut<R>) -> U) -> U {2758self.try_resource_scope(f)2759.unwrap_or_else(|| panic!("resource does not exist: {}", DebugName::type_name::<R>()))2760}27612762/// Temporarily removes the requested resource from this [`World`] if it exists, runs custom user code,2763/// then re-adds the resource before returning. Returns `None` if the resource does not exist in this [`World`].2764///2765/// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].2766/// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).2767///2768/// See also [`resource_scope`](Self::resource_scope).2769///2770/// # Note2771///2772/// If the world's resource metadata is cleared within the scope, such as by calling2773/// [`World::clear_resources`] or [`World::clear_all`], the resource will *not* be re-inserted2774/// at the end of the scope.2775pub fn try_resource_scope<R: Resource, U>(2776&mut self,2777f: impl FnOnce(&mut World, Mut<R>) -> U,2778) -> Option<U> {2779let last_change_tick = self.last_change_tick();2780let change_tick = self.change_tick();27812782let component_id = self.components.valid_component_id::<R>()?;2783let entity = *self.resource_entities.get(component_id)?;2784let mut entity_mut = self.get_entity_mut(entity).ok()?;27852786let mut ticks = entity_mut.get_change_ticks::<R>()?;2787let mut changed_by = entity_mut.get_changed_by::<R>()?;2788let value = entity_mut.take::<R>()?;27892790// type used to manage reinserting the resource at the end of the scope. use of a drop impl means that2791// the resource is inserted even if the user-provided closure unwinds.2792// this facilitates localized panic recovery and makes app shutdown in response to a panic more graceful2793// by avoiding knock-on errors.2794struct ReinsertGuard<'a, R: Resource> {2795world: &'a mut World,2796entity: Entity,2797component_id: ComponentId,2798value: ManuallyDrop<R>,2799ticks: ComponentTicks,2800caller: MaybeLocation,2801}2802impl<R: Resource> Drop for ReinsertGuard<'_, R> {2803fn drop(&mut self) {2804// take ownership of the value first so it'll get dropped if we return early2805// SAFETY: drop semantics ensure that `self.value` will never be accessed again after this call2806let value = unsafe { ManuallyDrop::take(&mut self.value) };28072808let Ok(mut entity_mut) = self.world.get_entity_mut(self.entity) else {2809return;2810};28112812// in debug mode, raise a panic if user code re-inserted a resource of this type within the scope.2813// resource insertion usually indicates a logic error in user code, which is useful to catch at dev time,2814// however it does not inherently lead to corrupted state, so we avoid introducing an unnecessary crash2815// for production builds.2816if entity_mut.contains_id(self.component_id) {2817#[cfg(debug_assertions)]2818{2819// if we're already panicking, log an error instead of panicking, as double-panics result in an abort2820#[cfg(feature = "std")]2821if std::thread::panicking() {2822log::error!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\2823In release builds, the value inserted will be overwritten at the end of the scope.",2824DebugName::type_name::<R>());2825// return early to maintain consistent behavior with non-panicking calls in debug builds2826return;2827}28282829panic!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\2830In release builds, the value inserted will be overwritten at the end of the scope.",2831DebugName::type_name::<R>());2832}2833#[cfg(not(debug_assertions))]2834{2835#[cold]2836#[inline(never)]2837fn warn_reinsert(resource_name: &str) {2838warn!(2839"Resource `{resource_name}` was inserted during a call to World::resource_scope: the inserted value will be overwritten.",2840);2841}28422843warn_reinsert(&DebugName::type_name::<R>());2844}2845}28462847move_as_ptr!(value);28482849// See EntityWorldMut::insert_with_caller for the original code.2850// This is copied here to update the change ticks. This way we can ensure that the commands2851// ran during self.flush(), interact with the correct ticks on the resource component.2852{2853let location = entity_mut.location();2854let mut bundle_inserter = BundleInserter::new::<R>(2855// SAFETY: We update the entity location like in EntityWorldMut::insert_with_caller2856unsafe { entity_mut.world_mut() },2857location.archetype_id,2858self.ticks.changed,2859);2860// SAFETY:2861// - `location` matches current entity and thus must currently exist in the source2862// archetype for this inserter and its location within the archetype.2863// - `T` matches the type used to create the `BundleInserter`.2864// - `apply_effect` is called exactly once after this function.2865// - The value pointed at by `bundle` is not accessed for anything other than `apply_effect`2866// and the caller ensures that the value is not accessed or dropped after this function2867// returns.2868let (bundle, _) = value.partial_move(|bundle| unsafe {2869bundle_inserter.insert(2870self.entity,2871location,2872bundle,2873InsertMode::Replace,2874self.caller,2875RelationshipHookMode::Run,2876)2877});2878entity_mut.update_location();28792880// Set the added tick to the original.2881entity_mut2882.get_mut::<R>()2883.unwrap()2884.set_last_added(self.ticks.added);28852886// SAFETY: We update the entity location afterwards.2887unsafe { entity_mut.world_mut() }.flush();28882889entity_mut.update_location();2890// SAFETY:2891// - This is called exactly once after the `BundleInsert::insert` call before returning to safe code.2892// - `bundle` points to the same `B` that `BundleInsert::insert` was called on.2893unsafe { R::apply_effect(bundle, &mut entity_mut) };2894}2895}2896}28972898let mut guard = ReinsertGuard {2899world: self,2900entity,2901component_id,2902value: ManuallyDrop::new(value),2903ticks,2904caller: changed_by,2905};29062907let value_mut = Mut {2908value: &mut *guard.value,2909ticks: ComponentTicksMut {2910added: &mut ticks.added,2911changed: &mut ticks.changed,2912changed_by: changed_by.as_mut(),2913last_run: last_change_tick,2914this_run: change_tick,2915},2916};29172918let result = f(guard.world, value_mut);29192920Some(result)2921}29222923/// Writes a [`Message`].2924/// This method returns the [`MessageId`] of the written `message`,2925/// or [`None`] if the `message` could not be written.2926#[inline]2927pub fn write_message<M: Message>(&mut self, message: M) -> Option<MessageId<M>> {2928self.write_message_batch(core::iter::once(message))?.next()2929}29302931/// Writes the default value of the [`Message`] of type `M`.2932/// This method returns the [`MessageId`] of the written message,2933/// or [`None`] if the `event` could not be written.2934#[inline]2935pub fn write_message_default<M: Message + Default>(&mut self) -> Option<MessageId<M>> {2936self.write_message(M::default())2937}29382939/// Writes a batch of [`Message`]s from an iterator.2940/// This method returns the [IDs](`MessageId`) of the written `messages`,2941/// or [`None`] if the `events` could not be written.2942#[inline]2943pub fn write_message_batch<M: Message>(2944&mut self,2945messages: impl IntoIterator<Item = M>,2946) -> Option<WriteBatchIds<M>> {2947let Some(mut events_resource) = self.get_resource_mut::<Messages<M>>() else {2948log::error!(2949"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 ",2950DebugName::type_name::<M>()2951);2952return None;2953};2954Some(events_resource.write_batch(messages))2955}29562957/// Inserts a new resource with the given `value`. Will replace the value if it already existed.2958///2959/// **You should prefer to use the typed API [`World::insert_resource`] where possible and only2960/// use this in cases where the actual types are not known at compile time.**2961///2962/// # Safety2963/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.2964#[inline]2965#[track_caller]2966pub unsafe fn insert_resource_by_id(2967&mut self,2968component_id: ComponentId,2969value: OwningPtr<'_>,2970caller: MaybeLocation,2971) {2972// if the resource already exists, we replace it on the same entity2973let mut entity_mut = if let Some(entity) = self.resource_entities.get(component_id) {2974self.get_entity_mut(*entity)2975.expect("ResourceCache is in sync")2976} else {2977self.spawn_empty()2978};2979entity_mut.insert_by_id_with_caller(2980component_id,2981value,2982InsertMode::Replace,2983caller,2984RelationshipHookMode::Run,2985);2986}29872988/// Inserts new `!Send` data with the given `value`. Will replace the value if it already2989/// existed.2990///2991/// **You should prefer to use the typed API [`World::insert_non_send`] where possible and only2992/// use this in cases where the actual types are not known at compile time.**2993///2994/// # Panics2995/// If a value is already present, this function will panic if not called from the same2996/// thread that the original value was inserted from.2997///2998/// # Safety2999/// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.3000#[inline]3001#[track_caller]3002pub unsafe fn insert_non_send_by_id(3003&mut self,3004component_id: ComponentId,3005value: OwningPtr<'_>,3006caller: MaybeLocation,3007) {3008let change_tick = self.change_tick();30093010let resource = self.initialize_non_send_internal(component_id);3011// SAFETY: `value` is valid for `component_id`, ensured by caller3012unsafe {3013resource.insert(value, change_tick, caller);3014}3015}30163017/// # Panics3018/// Panics if `component_id` is not registered in this world3019#[inline]3020pub(crate) fn initialize_non_send_internal(3021&mut self,3022component_id: ComponentId,3023) -> &mut NonSendData {3024self.flush_components();3025self.storages3026.non_sends3027.initialize_with(component_id, &self.components)3028}30293030/// Applies any commands in the world's internal [`CommandQueue`].3031/// This does not apply commands from any systems, only those stored in the world.3032///3033/// # Panics3034/// This will panic if any of the queued commands are [`spawn`](Commands::spawn).3035/// If this is possible, you should instead use [`flush`](Self::flush).3036pub(crate) fn flush_commands(&mut self) {3037// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`3038if !unsafe { self.command_queue.is_empty() } {3039// SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`3040unsafe {3041self.command_queue3042.clone()3043.apply_or_drop_queued(Some(self.into()));3044};3045}3046}30473048/// Applies any queued component registration.3049/// For spawning vanilla rust component types and resources, this is not strictly necessary.3050/// However, flushing components can make information available more quickly, and can have performance benefits.3051/// Additionally, for components and resources registered dynamically through a raw descriptor or similar,3052/// this is the only way to complete their registration.3053pub(crate) fn flush_components(&mut self) {3054self.components_registrator().apply_queued_registrations();3055}30563057/// Flushes queued entities and commands.3058///3059/// Queued entities will be spawned, and then commands will be applied.3060#[inline]3061#[track_caller]3062pub fn flush(&mut self) {3063self.flush_components();3064self.flush_commands();3065}30663067/// Increments the world's current change tick and returns the old value.3068///3069/// If you need to call this method, but do not have `&mut` access to the world,3070/// consider using [`as_unsafe_world_cell_readonly`](Self::as_unsafe_world_cell_readonly)3071/// to obtain an [`UnsafeWorldCell`] and calling [`increment_change_tick`](UnsafeWorldCell::increment_change_tick) on that.3072/// Note that this *can* be done in safe code, despite the name of the type.3073#[inline]3074pub fn increment_change_tick(&mut self) -> Tick {3075let change_tick = self.change_tick.get_mut();3076let prev_tick = *change_tick;3077*change_tick = change_tick.wrapping_add(1);3078Tick::new(prev_tick)3079}30803081/// Reads the current change tick of this world.3082///3083/// If you have exclusive (`&mut`) access to the world, consider using [`change_tick()`](Self::change_tick),3084/// which is more efficient since it does not require atomic synchronization.3085#[inline]3086pub fn read_change_tick(&self) -> Tick {3087let tick = self.change_tick.load(Ordering::Acquire);3088Tick::new(tick)3089}30903091/// Reads the current change tick of this world.3092///3093/// This does the same thing as [`read_change_tick()`](Self::read_change_tick), only this method3094/// is more efficient since it does not require atomic synchronization.3095#[inline]3096pub fn change_tick(&mut self) -> Tick {3097let tick = *self.change_tick.get_mut();3098Tick::new(tick)3099}31003101/// When called from within an exclusive system (a [`System`] that takes `&mut World` as its first3102/// parameter), this method returns the [`Tick`] indicating the last time the exclusive system was run.3103///3104/// Otherwise, this returns the `Tick` indicating the last time that [`World::clear_trackers`] was called.3105///3106/// [`System`]: crate::system::System3107#[inline]3108pub fn last_change_tick(&self) -> Tick {3109self.last_change_tick3110}31113112/// Returns the id of the last ECS event that was fired.3113/// Used internally to ensure observers don't trigger multiple times for the same event.3114#[inline]3115pub(crate) fn last_trigger_id(&self) -> u32 {3116self.last_trigger_id3117}31183119/// Sets [`World::last_change_tick()`] to the specified value during a scope.3120/// When the scope terminates, it will return to its old value.3121///3122/// This is useful if you need a region of code to be able to react to earlier changes made in the same system.3123///3124/// # Examples3125///3126/// ```3127/// # use bevy_ecs::prelude::*;3128/// // This function runs an update loop repeatedly, allowing each iteration of the loop3129/// // to react to changes made in the previous loop iteration.3130/// fn update_loop(3131/// world: &mut World,3132/// mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,3133/// ) {3134/// let mut last_change_tick = world.last_change_tick();3135///3136/// // Repeatedly run the update function until it requests a break.3137/// loop {3138/// let control_flow = world.last_change_tick_scope(last_change_tick, |world| {3139/// // Increment the change tick so we can detect changes from the previous update.3140/// last_change_tick = world.change_tick();3141/// world.increment_change_tick();3142///3143/// // Update once.3144/// update_fn(world)3145/// });3146///3147/// // End the loop when the closure returns `ControlFlow::Break`.3148/// if control_flow.is_break() {3149/// break;3150/// }3151/// }3152/// }3153/// #3154/// # #[derive(Resource)] struct Count(u32);3155/// # let mut world = World::new();3156/// # world.insert_resource(Count(0));3157/// # let saved_last_tick = world.last_change_tick();3158/// # let mut num_updates = 0;3159/// # update_loop(&mut world, |world| {3160/// # let mut c = world.resource_mut::<Count>();3161/// # match c.0 {3162/// # 0 => {3163/// # assert_eq!(num_updates, 0);3164/// # assert!(c.is_added());3165/// # c.0 = 1;3166/// # }3167/// # 1 => {3168/// # assert_eq!(num_updates, 1);3169/// # assert!(!c.is_added());3170/// # assert!(c.is_changed());3171/// # c.0 = 2;3172/// # }3173/// # 2 if c.is_changed() => {3174/// # assert_eq!(num_updates, 2);3175/// # assert!(!c.is_added());3176/// # }3177/// # 2 => {3178/// # assert_eq!(num_updates, 3);3179/// # assert!(!c.is_changed());3180/// # world.remove_resource::<Count>();3181/// # world.insert_resource(Count(3));3182/// # }3183/// # 3 if c.is_changed() => {3184/// # assert_eq!(num_updates, 4);3185/// # assert!(c.is_added());3186/// # }3187/// # 3 => {3188/// # assert_eq!(num_updates, 5);3189/// # assert!(!c.is_added());3190/// # c.0 = 4;3191/// # return std::ops::ControlFlow::Break(());3192/// # }3193/// # _ => unreachable!(),3194/// # }3195/// # num_updates += 1;3196/// # std::ops::ControlFlow::Continue(())3197/// # });3198/// # assert_eq!(num_updates, 5);3199/// # assert_eq!(world.resource::<Count>().0, 4);3200/// # assert_eq!(world.last_change_tick(), saved_last_tick);3201/// ```3202pub fn last_change_tick_scope<T>(3203&mut self,3204last_change_tick: Tick,3205f: impl FnOnce(&mut World) -> T,3206) -> T {3207struct LastTickGuard<'a> {3208world: &'a mut World,3209last_tick: Tick,3210}32113212// By setting the change tick in the drop impl, we ensure that3213// the change tick gets reset even if a panic occurs during the scope.3214impl Drop for LastTickGuard<'_> {3215fn drop(&mut self) {3216self.world.last_change_tick = self.last_tick;3217}3218}32193220let guard = LastTickGuard {3221last_tick: self.last_change_tick,3222world: self,3223};32243225guard.world.last_change_tick = last_change_tick;32263227f(guard.world)3228}32293230/// Iterates all component change ticks and clamps any older than [`MAX_CHANGE_AGE`](crate::change_detection::MAX_CHANGE_AGE).3231/// This also triggers [`CheckChangeTicks`] observers and returns the same event here.3232///3233/// Calling this method prevents [`Tick`]s overflowing and thus prevents false positives when comparing them.3234///3235/// **Note:** Does nothing and returns `None` if the [`World`] counter has not been incremented at least [`CHECK_TICK_THRESHOLD`]3236/// times since the previous pass.3237// TODO: benchmark and optimize3238pub fn check_change_ticks(&mut self) -> Option<CheckChangeTicks> {3239let change_tick = self.change_tick();3240if change_tick.relative_to(self.last_check_tick).get() < CHECK_TICK_THRESHOLD {3241return None;3242}32433244let check = CheckChangeTicks(change_tick);32453246let Storages {3247ref mut tables,3248ref mut sparse_sets,3249ref mut non_sends,3250} = self.storages;32513252#[cfg(feature = "trace")]3253let _span = tracing::info_span!("check component ticks").entered();3254tables.check_change_ticks(check);3255sparse_sets.check_change_ticks(check);3256non_sends.check_change_ticks(check);3257self.entities.check_change_ticks(check);32583259if let Some(mut schedules) = self.get_resource_mut::<Schedules>() {3260schedules.check_change_ticks(check);3261}32623263self.trigger(check);3264self.flush();32653266self.last_check_tick = change_tick;32673268Some(check)3269}32703271/// Clears all entities, resources, and non-send data.3272/// This invalidates all [`Entity`] and resource fetches such as [`Res`](crate::system::Res),3273/// [`ResMut`](crate::system::ResMut)3274pub fn clear_all(&mut self) {3275self.clear_entities();3276self.clear_non_send();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_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_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