bevy_ecs/world/mod.rs
1//! Defines the [`World`] and APIs for accessing it directly.
2
3pub(crate) mod command_queue;
4mod deferred_world;
5mod entity_access;
6mod entity_fetch;
7mod filtered_resource;
8mod identifier;
9mod spawn_batch;
10
11pub mod error;
12#[cfg(feature = "bevy_reflect")]
13pub mod reflect;
14pub mod unsafe_world_cell;
15
16pub use crate::{
17 change_detection::{Mut, Ref, CHECK_TICK_THRESHOLD},
18 world::command_queue::CommandQueue,
19};
20pub use bevy_ecs_macros::FromWorld;
21pub use deferred_world::DeferredWorld;
22pub use entity_access::{
23 ComponentEntry, DynamicComponentFetch, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
24 EntityWorldMut, FilteredEntityMut, FilteredEntityRef, OccupiedComponentEntry,
25 TryFromFilteredError, UnsafeFilteredEntityMut, VacantComponentEntry,
26};
27pub use entity_fetch::{EntityFetcher, WorldEntityFetch};
28pub use filtered_resource::*;
29pub use identifier::WorldId;
30pub use spawn_batch::*;
31
32use crate::{
33 archetype::{ArchetypeId, Archetypes},
34 bundle::{
35 Bundle, BundleId, BundleInfo, BundleInserter, BundleSpawner, Bundles, InsertMode,
36 NoBundleEffect,
37 },
38 change_detection::{
39 CheckChangeTicks, ComponentTicks, ComponentTicksMut, MaybeLocation, MutUntyped, Tick,
40 },
41 component::{
42 Component, ComponentDescriptor, ComponentId, ComponentIds, ComponentInfo, Components,
43 ComponentsQueuedRegistrator, ComponentsRegistrator, Mutable, RequiredComponents,
44 RequiredComponentsError,
45 },
46 entity::{Entities, Entity, EntityAllocator, EntityNotSpawnedError, SpawnError},
47 entity_disabling::DefaultQueryFilters,
48 error::{DefaultErrorHandler, ErrorHandler},
49 lifecycle::{ComponentHooks, RemovedComponentMessages, ADD, DESPAWN, INSERT, REMOVE, REPLACE},
50 message::{Message, MessageId, Messages, WriteBatchIds},
51 observer::Observers,
52 prelude::{Add, Despawn, Insert, Remove, Replace},
53 query::{DebugCheckedUnwrap, QueryData, QueryFilter, QueryState},
54 relationship::RelationshipHookMode,
55 resource::Resource,
56 schedule::{Schedule, ScheduleLabel, Schedules},
57 storage::{ResourceData, Storages},
58 system::Commands,
59 world::{
60 command_queue::RawCommandQueue,
61 error::{
62 EntityDespawnError, EntityMutableFetchError, TryInsertBatchError, TryRunScheduleError,
63 },
64 },
65};
66use alloc::{boxed::Box, vec::Vec};
67use bevy_platform::sync::atomic::{AtomicU32, Ordering};
68use bevy_ptr::{move_as_ptr, MovingPtr, OwningPtr, Ptr};
69use bevy_utils::prelude::DebugName;
70use core::{any::TypeId, fmt, mem::ManuallyDrop};
71use log::warn;
72use unsafe_world_cell::UnsafeWorldCell;
73
74/// Stores and exposes operations on [entities](Entity), [components](Component), resources,
75/// and their associated metadata.
76///
77/// Each [`Entity`] has a set of unique components, based on their type.
78/// Entity components can be created, updated, removed, and queried using a given [`World`].
79///
80/// For complex access patterns involving [`SystemParam`](crate::system::SystemParam),
81/// consider using [`SystemState`](crate::system::SystemState).
82///
83/// To mutate different parts of the world simultaneously,
84/// use [`World::resource_scope`] or [`SystemState`](crate::system::SystemState).
85///
86/// ## Resources
87///
88/// Worlds can also store [`Resource`]s,
89/// which are unique instances of a given type that don't belong to a specific Entity.
90/// There are also *non send resources*, which can only be accessed on the main thread.
91/// See [`Resource`] for usage.
92pub struct World {
93 id: WorldId,
94 pub(crate) entities: Entities,
95 pub(crate) allocator: EntityAllocator,
96 pub(crate) components: Components,
97 pub(crate) component_ids: ComponentIds,
98 pub(crate) archetypes: Archetypes,
99 pub(crate) storages: Storages,
100 pub(crate) bundles: Bundles,
101 pub(crate) observers: Observers,
102 pub(crate) removed_components: RemovedComponentMessages,
103 pub(crate) change_tick: AtomicU32,
104 pub(crate) last_change_tick: Tick,
105 pub(crate) last_check_tick: Tick,
106 pub(crate) last_trigger_id: u32,
107 pub(crate) command_queue: RawCommandQueue,
108}
109
110impl Default for World {
111 fn default() -> Self {
112 let mut world = Self {
113 id: WorldId::new().expect("More `bevy` `World`s have been created than is supported"),
114 entities: Entities::new(),
115 allocator: EntityAllocator::default(),
116 components: Default::default(),
117 archetypes: Archetypes::new(),
118 storages: Default::default(),
119 bundles: Default::default(),
120 observers: Observers::default(),
121 removed_components: Default::default(),
122 // Default value is `1`, and `last_change_tick`s default to `0`, such that changes
123 // are detected on first system runs and for direct world queries.
124 change_tick: AtomicU32::new(1),
125 last_change_tick: Tick::new(0),
126 last_check_tick: Tick::new(0),
127 last_trigger_id: 0,
128 command_queue: RawCommandQueue::new(),
129 component_ids: ComponentIds::default(),
130 };
131 world.bootstrap();
132 world
133 }
134}
135
136impl Drop for World {
137 fn drop(&mut self) {
138 // SAFETY: Not passing a pointer so the argument is always valid
139 unsafe { self.command_queue.apply_or_drop_queued(None) };
140 // SAFETY: Pointers in internal command queue are only invalidated here
141 drop(unsafe { Box::from_raw(self.command_queue.bytes.as_ptr()) });
142 // SAFETY: Pointers in internal command queue are only invalidated here
143 drop(unsafe { Box::from_raw(self.command_queue.cursor.as_ptr()) });
144 // SAFETY: Pointers in internal command queue are only invalidated here
145 drop(unsafe { Box::from_raw(self.command_queue.panic_recovery.as_ptr()) });
146 }
147}
148
149impl World {
150 /// This performs initialization that _must_ happen for every [`World`] immediately upon creation (such as claiming specific component ids).
151 /// This _must_ be run as part of constructing a [`World`], before it is returned to the caller.
152 #[inline]
153 fn bootstrap(&mut self) {
154 // The order that we register these events is vital to ensure that the constants are correct!
155 let on_add = self.register_event_key::<Add>();
156 assert_eq!(ADD, on_add);
157
158 let on_insert = self.register_event_key::<Insert>();
159 assert_eq!(INSERT, on_insert);
160
161 let on_replace = self.register_event_key::<Replace>();
162 assert_eq!(REPLACE, on_replace);
163
164 let on_remove = self.register_event_key::<Remove>();
165 assert_eq!(REMOVE, on_remove);
166
167 let on_despawn = self.register_event_key::<Despawn>();
168 assert_eq!(DESPAWN, on_despawn);
169
170 // This sets up `Disabled` as a disabling component, via the FromWorld impl
171 self.init_resource::<DefaultQueryFilters>();
172 }
173 /// Creates a new empty [`World`].
174 ///
175 /// # Panics
176 ///
177 /// If [`usize::MAX`] [`World`]s have been created.
178 /// This guarantee allows System Parameters to safely uniquely identify a [`World`],
179 /// since its [`WorldId`] is unique
180 #[inline]
181 pub fn new() -> World {
182 World::default()
183 }
184
185 /// Retrieves this [`World`]'s unique ID
186 #[inline]
187 pub fn id(&self) -> WorldId {
188 self.id
189 }
190
191 /// Creates a new [`UnsafeWorldCell`] view with complete read+write access.
192 #[inline]
193 pub fn as_unsafe_world_cell(&mut self) -> UnsafeWorldCell<'_> {
194 UnsafeWorldCell::new_mutable(self)
195 }
196
197 /// Creates a new [`UnsafeWorldCell`] view with only read access to everything.
198 #[inline]
199 pub fn as_unsafe_world_cell_readonly(&self) -> UnsafeWorldCell<'_> {
200 UnsafeWorldCell::new_readonly(self)
201 }
202
203 /// Retrieves this world's [`Entities`] collection.
204 #[inline]
205 pub fn entities(&self) -> &Entities {
206 &self.entities
207 }
208
209 /// Retrieves this world's [`EntityAllocator`] collection.
210 #[inline]
211 pub fn entities_allocator(&self) -> &EntityAllocator {
212 &self.allocator
213 }
214
215 /// Retrieves this world's [`EntityAllocator`] collection mutably.
216 #[inline]
217 pub fn entities_allocator_mut(&mut self) -> &mut EntityAllocator {
218 &mut self.allocator
219 }
220
221 /// Retrieves this world's [`Entities`] collection mutably.
222 ///
223 /// # Safety
224 /// Mutable reference must not be used to put the [`Entities`] data
225 /// in an invalid state for this [`World`]
226 #[inline]
227 pub unsafe fn entities_mut(&mut self) -> &mut Entities {
228 &mut self.entities
229 }
230
231 /// Retrieves the number of [`Entities`] in the world.
232 ///
233 /// This is helpful as a diagnostic, but it can also be used effectively in tests.
234 #[inline]
235 pub fn entity_count(&self) -> u32 {
236 self.entities.count_spawned()
237 }
238
239 /// Retrieves this world's [`Archetypes`] collection.
240 #[inline]
241 pub fn archetypes(&self) -> &Archetypes {
242 &self.archetypes
243 }
244
245 /// Retrieves this world's [`Components`] collection.
246 #[inline]
247 pub fn components(&self) -> &Components {
248 &self.components
249 }
250
251 /// Prepares a [`ComponentsQueuedRegistrator`] for the world.
252 /// **NOTE:** [`ComponentsQueuedRegistrator`] is easily misused.
253 /// See its docs for important notes on when and how it should be used.
254 #[inline]
255 pub fn components_queue(&self) -> ComponentsQueuedRegistrator<'_> {
256 // SAFETY: These are from the same world.
257 unsafe { ComponentsQueuedRegistrator::new(&self.components, &self.component_ids) }
258 }
259
260 /// Prepares a [`ComponentsRegistrator`] for the world.
261 #[inline]
262 pub fn components_registrator(&mut self) -> ComponentsRegistrator<'_> {
263 // SAFETY: These are from the same world.
264 unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) }
265 }
266
267 /// Retrieves this world's [`Storages`] collection.
268 #[inline]
269 pub fn storages(&self) -> &Storages {
270 &self.storages
271 }
272
273 /// Retrieves this world's [`Bundles`] collection.
274 #[inline]
275 pub fn bundles(&self) -> &Bundles {
276 &self.bundles
277 }
278
279 /// Retrieves this world's [`RemovedComponentMessages`] collection
280 #[inline]
281 pub fn removed_components(&self) -> &RemovedComponentMessages {
282 &self.removed_components
283 }
284
285 /// Retrieves this world's [`Observers`] list
286 #[inline]
287 pub fn observers(&self) -> &Observers {
288 &self.observers
289 }
290
291 /// Creates a new [`Commands`] instance that writes to the world's command queue
292 /// Use [`World::flush`] to apply all queued commands
293 #[inline]
294 pub fn commands(&mut self) -> Commands<'_, '_> {
295 // SAFETY: command_queue is stored on world and always valid while the world exists
296 unsafe {
297 Commands::new_raw_from_entities(
298 self.command_queue.clone(),
299 &self.allocator,
300 &self.entities,
301 )
302 }
303 }
304
305 /// Registers a new [`Component`] type and returns the [`ComponentId`] created for it.
306 ///
307 /// # Usage Notes
308 /// In most cases, you don't need to call this method directly since component registration
309 /// happens automatically during system initialization.
310 pub fn register_component<T: Component>(&mut self) -> ComponentId {
311 self.components_registrator().register_component::<T>()
312 }
313
314 /// Registers a component type as "disabling",
315 /// using [default query filters](DefaultQueryFilters) to exclude entities with the component from queries.
316 pub fn register_disabling_component<C: Component>(&mut self) {
317 let component_id = self.register_component::<C>();
318 let mut dqf = self.resource_mut::<DefaultQueryFilters>();
319 dqf.register_disabling_component(component_id);
320 }
321
322 /// Returns a mutable reference to the [`ComponentHooks`] for a [`Component`] type.
323 ///
324 /// Will panic if `T` exists in any archetypes.
325 #[must_use]
326 pub fn register_component_hooks<T: Component>(&mut self) -> &mut ComponentHooks {
327 let index = self.register_component::<T>();
328 assert!(!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>());
329 // SAFETY: We just created this component
330 unsafe { self.components.get_hooks_mut(index).debug_checked_unwrap() }
331 }
332
333 /// Returns a mutable reference to the [`ComponentHooks`] for a [`Component`] with the given id if it exists.
334 ///
335 /// Will panic if `id` exists in any archetypes.
336 pub fn register_component_hooks_by_id(
337 &mut self,
338 id: ComponentId,
339 ) -> Option<&mut ComponentHooks> {
340 assert!(!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");
341 self.components.get_hooks_mut(id)
342 }
343
344 /// Registers the given component `R` as a [required component] for `T`.
345 ///
346 /// When `T` is added to an entity, `R` and its own required components will also be added
347 /// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.
348 /// If a custom constructor is desired, use [`World::register_required_components_with`] instead.
349 ///
350 /// For the non-panicking version, see [`World::try_register_required_components`].
351 ///
352 /// Note that requirements must currently be registered before `T` is inserted into the world
353 /// for the first time. This limitation may be fixed in the future.
354 ///
355 /// [required component]: Component#required-components
356 ///
357 /// # Panics
358 ///
359 /// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added
360 /// on an entity before the registration.
361 ///
362 /// Indirect requirements through other components are allowed. In those cases, any existing requirements
363 /// will only be overwritten if the new requirement is more specific.
364 ///
365 /// # Example
366 ///
367 /// ```
368 /// # use bevy_ecs::prelude::*;
369 /// #[derive(Component)]
370 /// struct A;
371 ///
372 /// #[derive(Component, Default, PartialEq, Eq, Debug)]
373 /// struct B(usize);
374 ///
375 /// #[derive(Component, Default, PartialEq, Eq, Debug)]
376 /// struct C(u32);
377 ///
378 /// # let mut world = World::default();
379 /// // Register B as required by A and C as required by B.
380 /// world.register_required_components::<A, B>();
381 /// world.register_required_components::<B, C>();
382 ///
383 /// // This will implicitly also insert B and C with their Default constructors.
384 /// let id = world.spawn(A).id();
385 /// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
386 /// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());
387 /// ```
388 pub fn register_required_components<T: Component, R: Component + Default>(&mut self) {
389 self.try_register_required_components::<T, R>().unwrap();
390 }
391
392 /// Registers the given component `R` as a [required component] for `T`.
393 ///
394 /// When `T` is added to an entity, `R` and its own required components will also be added
395 /// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.
396 /// If a [`Default`] constructor is desired, use [`World::register_required_components`] instead.
397 ///
398 /// For the non-panicking version, see [`World::try_register_required_components_with`].
399 ///
400 /// Note that requirements must currently be registered before `T` is inserted into the world
401 /// for the first time. This limitation may be fixed in the future.
402 ///
403 /// [required component]: Component#required-components
404 ///
405 /// # Panics
406 ///
407 /// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added
408 /// on an entity before the registration.
409 ///
410 /// Indirect requirements through other components are allowed. In those cases, any existing requirements
411 /// will only be overwritten if the new requirement is more specific.
412 ///
413 /// # Example
414 ///
415 /// ```
416 /// # use bevy_ecs::prelude::*;
417 /// #[derive(Component)]
418 /// struct A;
419 ///
420 /// #[derive(Component, Default, PartialEq, Eq, Debug)]
421 /// struct B(usize);
422 ///
423 /// #[derive(Component, PartialEq, Eq, Debug)]
424 /// struct C(u32);
425 ///
426 /// # let mut world = World::default();
427 /// // Register B and C as required by A and C as required by B.
428 /// // A requiring C directly will overwrite the indirect requirement through B.
429 /// world.register_required_components::<A, B>();
430 /// world.register_required_components_with::<B, C>(|| C(1));
431 /// world.register_required_components_with::<A, C>(|| C(2));
432 ///
433 /// // This will implicitly also insert B with its Default constructor and C
434 /// // with the custom constructor defined by A.
435 /// let id = world.spawn(A).id();
436 /// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
437 /// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());
438 /// ```
439 pub fn register_required_components_with<T: Component, R: Component>(
440 &mut self,
441 constructor: fn() -> R,
442 ) {
443 self.try_register_required_components_with::<T, R>(constructor)
444 .unwrap();
445 }
446
447 /// Tries to register the given component `R` as a [required component] for `T`.
448 ///
449 /// When `T` is added to an entity, `R` and its own required components will also be added
450 /// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.
451 /// If a custom constructor is desired, use [`World::register_required_components_with`] instead.
452 ///
453 /// For the panicking version, see [`World::register_required_components`].
454 ///
455 /// Note that requirements must currently be registered before `T` is inserted into the world
456 /// for the first time. This limitation may be fixed in the future.
457 ///
458 /// [required component]: Component#required-components
459 ///
460 /// # Errors
461 ///
462 /// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added
463 /// on an entity before the registration.
464 ///
465 /// Indirect requirements through other components are allowed. In those cases, any existing requirements
466 /// will only be overwritten if the new requirement is more specific.
467 ///
468 /// # Example
469 ///
470 /// ```
471 /// # use bevy_ecs::prelude::*;
472 /// #[derive(Component)]
473 /// struct A;
474 ///
475 /// #[derive(Component, Default, PartialEq, Eq, Debug)]
476 /// struct B(usize);
477 ///
478 /// #[derive(Component, Default, PartialEq, Eq, Debug)]
479 /// struct C(u32);
480 ///
481 /// # let mut world = World::default();
482 /// // Register B as required by A and C as required by B.
483 /// world.register_required_components::<A, B>();
484 /// world.register_required_components::<B, C>();
485 ///
486 /// // Duplicate registration! This will fail.
487 /// assert!(world.try_register_required_components::<A, B>().is_err());
488 ///
489 /// // This will implicitly also insert B and C with their Default constructors.
490 /// let id = world.spawn(A).id();
491 /// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
492 /// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());
493 /// ```
494 pub fn try_register_required_components<T: Component, R: Component + Default>(
495 &mut self,
496 ) -> Result<(), RequiredComponentsError> {
497 self.try_register_required_components_with::<T, R>(R::default)
498 }
499
500 /// Tries to register the given component `R` as a [required component] for `T`.
501 ///
502 /// When `T` is added to an entity, `R` and its own required components will also be added
503 /// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.
504 /// If a [`Default`] constructor is desired, use [`World::register_required_components`] instead.
505 ///
506 /// For the panicking version, see [`World::register_required_components_with`].
507 ///
508 /// Note that requirements must currently be registered before `T` is inserted into the world
509 /// for the first time. This limitation may be fixed in the future.
510 ///
511 /// [required component]: Component#required-components
512 ///
513 /// # Errors
514 ///
515 /// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added
516 /// on an entity before the registration.
517 ///
518 /// Indirect requirements through other components are allowed. In those cases, any existing requirements
519 /// will only be overwritten if the new requirement is more specific.
520 ///
521 /// # Example
522 ///
523 /// ```
524 /// # use bevy_ecs::prelude::*;
525 /// #[derive(Component)]
526 /// struct A;
527 ///
528 /// #[derive(Component, Default, PartialEq, Eq, Debug)]
529 /// struct B(usize);
530 ///
531 /// #[derive(Component, PartialEq, Eq, Debug)]
532 /// struct C(u32);
533 ///
534 /// # let mut world = World::default();
535 /// // Register B and C as required by A and C as required by B.
536 /// // A requiring C directly will overwrite the indirect requirement through B.
537 /// world.register_required_components::<A, B>();
538 /// world.register_required_components_with::<B, C>(|| C(1));
539 /// world.register_required_components_with::<A, C>(|| C(2));
540 ///
541 /// // Duplicate registration! Even if the constructors were different, this would fail.
542 /// assert!(world.try_register_required_components_with::<B, C>(|| C(1)).is_err());
543 ///
544 /// // This will implicitly also insert B with its Default constructor and C
545 /// // with the custom constructor defined by A.
546 /// let id = world.spawn(A).id();
547 /// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
548 /// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());
549 /// ```
550 pub fn try_register_required_components_with<T: Component, R: Component>(
551 &mut self,
552 constructor: fn() -> R,
553 ) -> Result<(), RequiredComponentsError> {
554 let requiree = self.register_component::<T>();
555
556 // TODO: Remove this panic and update archetype edges accordingly when required components are added
557 if self.archetypes().component_index().contains_key(&requiree) {
558 return Err(RequiredComponentsError::ArchetypeExists(requiree));
559 }
560
561 let required = self.register_component::<R>();
562
563 // SAFETY: We just created the `required` and `requiree` components.
564 unsafe {
565 self.components
566 .register_required_components::<R>(requiree, required, constructor)
567 }
568 }
569
570 /// Retrieves the [required components](RequiredComponents) for the given component type, if it exists.
571 pub fn get_required_components<C: Component>(&self) -> Option<&RequiredComponents> {
572 let id = self.components().valid_component_id::<C>()?;
573 let component_info = self.components().get_info(id)?;
574 Some(component_info.required_components())
575 }
576
577 /// Retrieves the [required components](RequiredComponents) for the component of the given [`ComponentId`], if it exists.
578 pub fn get_required_components_by_id(&self, id: ComponentId) -> Option<&RequiredComponents> {
579 let component_info = self.components().get_info(id)?;
580 Some(component_info.required_components())
581 }
582
583 /// Registers a new [`Component`] type and returns the [`ComponentId`] created for it.
584 ///
585 /// This method differs from [`World::register_component`] in that it uses a [`ComponentDescriptor`]
586 /// to register the new component type instead of statically available type information. This
587 /// enables the dynamic registration of new component definitions at runtime for advanced use cases.
588 ///
589 /// While the option to register a component from a descriptor is useful in type-erased
590 /// contexts, the standard [`World::register_component`] function should always be used instead
591 /// when type information is available at compile time.
592 pub fn register_component_with_descriptor(
593 &mut self,
594 descriptor: ComponentDescriptor,
595 ) -> ComponentId {
596 self.components_registrator()
597 .register_component_with_descriptor(descriptor)
598 }
599
600 /// Returns the [`ComponentId`] of the given [`Component`] type `T`.
601 ///
602 /// The returned `ComponentId` is specific to the `World` instance
603 /// it was retrieved from and should not be used with another `World` instance.
604 ///
605 /// Returns [`None`] if the `Component` type has not yet been initialized within
606 /// the `World` using [`World::register_component`].
607 ///
608 /// ```
609 /// use bevy_ecs::prelude::*;
610 ///
611 /// let mut world = World::new();
612 ///
613 /// #[derive(Component)]
614 /// struct ComponentA;
615 ///
616 /// let component_a_id = world.register_component::<ComponentA>();
617 ///
618 /// assert_eq!(component_a_id, world.component_id::<ComponentA>().unwrap())
619 /// ```
620 ///
621 /// # See also
622 ///
623 /// * [`ComponentIdFor`](crate::component::ComponentIdFor)
624 /// * [`Components::component_id()`]
625 /// * [`Components::get_id()`]
626 #[inline]
627 pub fn component_id<T: Component>(&self) -> Option<ComponentId> {
628 self.components.component_id::<T>()
629 }
630
631 /// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.
632 ///
633 /// The [`Resource`] doesn't have a value in the [`World`], it's only registered. If you want
634 /// to insert the [`Resource`] in the [`World`], use [`World::init_resource`] or
635 /// [`World::insert_resource`] instead.
636 pub fn register_resource<R: Resource>(&mut self) -> ComponentId {
637 self.components_registrator().register_resource::<R>()
638 }
639
640 /// Returns the [`ComponentId`] of the given [`Resource`] type `T`.
641 ///
642 /// The returned [`ComponentId`] is specific to the [`World`] instance it was retrieved from
643 /// and should not be used with another [`World`] instance.
644 ///
645 /// Returns [`None`] if the [`Resource`] type has not yet been initialized within the
646 /// [`World`] using [`World::register_resource`], [`World::init_resource`] or [`World::insert_resource`].
647 pub fn resource_id<T: Resource>(&self) -> Option<ComponentId> {
648 self.components.get_resource_id(TypeId::of::<T>())
649 }
650
651 /// Returns [`EntityRef`]s that expose read-only operations for the given
652 /// `entities`. This will panic if any of the given entities do not exist. Use
653 /// [`World::get_entity`] if you want to check for entity existence instead
654 /// of implicitly panicking.
655 ///
656 /// This function supports fetching a single entity or multiple entities:
657 /// - Pass an [`Entity`] to receive a single [`EntityRef`].
658 /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].
659 /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.
660 ///
661 /// # Panics
662 ///
663 /// If any of the given `entities` do not exist in the world.
664 ///
665 /// # Examples
666 ///
667 /// ## Single [`Entity`]
668 ///
669 /// ```
670 /// # use bevy_ecs::prelude::*;
671 /// #[derive(Component)]
672 /// struct Position {
673 /// x: f32,
674 /// y: f32,
675 /// }
676 ///
677 /// let mut world = World::new();
678 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
679 ///
680 /// let position = world.entity(entity).get::<Position>().unwrap();
681 /// assert_eq!(position.x, 0.0);
682 /// ```
683 ///
684 /// ## Array of [`Entity`]s
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 e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();
696 /// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();
697 ///
698 /// let [e1_ref, e2_ref] = world.entity([e1, e2]);
699 /// let e1_position = e1_ref.get::<Position>().unwrap();
700 /// assert_eq!(e1_position.x, 0.0);
701 /// let e2_position = e2_ref.get::<Position>().unwrap();
702 /// assert_eq!(e2_position.x, 1.0);
703 /// ```
704 ///
705 /// ## Slice of [`Entity`]s
706 ///
707 /// ```
708 /// # use bevy_ecs::prelude::*;
709 /// #[derive(Component)]
710 /// struct Position {
711 /// x: f32,
712 /// y: f32,
713 /// }
714 ///
715 /// let mut world = World::new();
716 /// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
717 /// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
718 /// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
719 ///
720 /// let ids = vec![e1, e2, e3];
721 /// for eref in world.entity(&ids[..]) {
722 /// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);
723 /// }
724 /// ```
725 ///
726 /// ## [`EntityHashSet`](crate::entity::EntityHashSet)
727 ///
728 /// ```
729 /// # use bevy_ecs::{prelude::*, entity::EntityHashSet};
730 /// #[derive(Component)]
731 /// struct Position {
732 /// x: f32,
733 /// y: f32,
734 /// }
735 ///
736 /// let mut world = World::new();
737 /// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
738 /// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
739 /// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
740 ///
741 /// let ids = EntityHashSet::from_iter([e1, e2, e3]);
742 /// for (_id, eref) in world.entity(&ids) {
743 /// assert_eq!(eref.get::<Position>().unwrap().y, 1.0);
744 /// }
745 /// ```
746 ///
747 /// [`EntityHashSet`]: crate::entity::EntityHashSet
748 #[inline]
749 #[track_caller]
750 pub fn entity<F: WorldEntityFetch>(&self, entities: F) -> F::Ref<'_> {
751 match self.get_entity(entities) {
752 Ok(res) => res,
753 Err(err) => panic!("{err}"),
754 }
755 }
756
757 /// Returns [`EntityMut`]s that expose read and write operations for the
758 /// given `entities`. This will panic if any of the given entities do not
759 /// exist. Use [`World::get_entity_mut`] if you want to check for entity
760 /// existence instead of implicitly panicking.
761 ///
762 /// This function supports fetching a single entity or multiple entities:
763 /// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].
764 /// - This reference type allows for structural changes to the entity,
765 /// such as adding or removing components, or despawning the entity.
766 /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
767 /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
768 /// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
769 /// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).
770 ///
771 /// In order to perform structural changes on the returned entity reference,
772 /// such as adding or removing components, or despawning the entity, only a
773 /// single [`Entity`] can be passed to this function. Allowing multiple
774 /// entities at the same time with structural access would lead to undefined
775 /// behavior, so [`EntityMut`] is returned when requesting multiple entities.
776 ///
777 /// # Panics
778 ///
779 /// If any of the given `entities` do not exist in the world.
780 ///
781 /// # Examples
782 ///
783 /// ## Single [`Entity`]
784 ///
785 /// ```
786 /// # use bevy_ecs::prelude::*;
787 /// #[derive(Component)]
788 /// struct Position {
789 /// x: f32,
790 /// y: f32,
791 /// }
792 ///
793 /// let mut world = World::new();
794 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
795 ///
796 /// let mut entity_mut = world.entity_mut(entity);
797 /// let mut position = entity_mut.get_mut::<Position>().unwrap();
798 /// position.y = 1.0;
799 /// assert_eq!(position.x, 0.0);
800 /// entity_mut.despawn();
801 /// # assert!(world.get_entity_mut(entity).is_err());
802 /// ```
803 ///
804 /// ## Array of [`Entity`]s
805 ///
806 /// ```
807 /// # use bevy_ecs::prelude::*;
808 /// #[derive(Component)]
809 /// struct Position {
810 /// x: f32,
811 /// y: f32,
812 /// }
813 ///
814 /// let mut world = World::new();
815 /// let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();
816 /// let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();
817 ///
818 /// let [mut e1_ref, mut e2_ref] = world.entity_mut([e1, e2]);
819 /// let mut e1_position = e1_ref.get_mut::<Position>().unwrap();
820 /// e1_position.x = 1.0;
821 /// assert_eq!(e1_position.x, 1.0);
822 /// let mut e2_position = e2_ref.get_mut::<Position>().unwrap();
823 /// e2_position.x = 2.0;
824 /// assert_eq!(e2_position.x, 2.0);
825 /// ```
826 ///
827 /// ## Slice of [`Entity`]s
828 ///
829 /// ```
830 /// # use bevy_ecs::prelude::*;
831 /// #[derive(Component)]
832 /// struct Position {
833 /// x: f32,
834 /// y: f32,
835 /// }
836 ///
837 /// let mut world = World::new();
838 /// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
839 /// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
840 /// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
841 ///
842 /// let ids = vec![e1, e2, e3];
843 /// for mut eref in world.entity_mut(&ids[..]) {
844 /// let mut pos = eref.get_mut::<Position>().unwrap();
845 /// pos.y = 2.0;
846 /// assert_eq!(pos.y, 2.0);
847 /// }
848 /// ```
849 ///
850 /// ## [`EntityHashSet`](crate::entity::EntityHashSet)
851 ///
852 /// ```
853 /// # use bevy_ecs::{prelude::*, entity::EntityHashSet};
854 /// #[derive(Component)]
855 /// struct Position {
856 /// x: f32,
857 /// y: f32,
858 /// }
859 ///
860 /// let mut world = World::new();
861 /// let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
862 /// let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
863 /// let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
864 ///
865 /// let ids = EntityHashSet::from_iter([e1, e2, e3]);
866 /// for (_id, mut eref) in world.entity_mut(&ids) {
867 /// let mut pos = eref.get_mut::<Position>().unwrap();
868 /// pos.y = 2.0;
869 /// assert_eq!(pos.y, 2.0);
870 /// }
871 /// ```
872 ///
873 /// [`EntityHashSet`]: crate::entity::EntityHashSet
874 #[inline]
875 #[track_caller]
876 pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::Mut<'_> {
877 #[inline(never)]
878 #[cold]
879 #[track_caller]
880 fn panic_on_err(e: EntityMutableFetchError) -> ! {
881 panic!("{e}");
882 }
883
884 match self.get_entity_mut(entities) {
885 Ok(fetched) => fetched,
886 Err(e) => panic_on_err(e),
887 }
888 }
889
890 /// Returns the components of an [`Entity`] through [`ComponentInfo`].
891 #[inline]
892 pub fn inspect_entity(
893 &self,
894 entity: Entity,
895 ) -> Result<impl Iterator<Item = &ComponentInfo>, EntityNotSpawnedError> {
896 let entity_location = self.entities().get_spawned(entity)?;
897
898 let archetype = self
899 .archetypes()
900 .get(entity_location.archetype_id)
901 .expect("ArchetypeId was retrieved from an EntityLocation and should correspond to an Archetype");
902
903 Ok(archetype
904 .iter_components()
905 .filter_map(|id| self.components().get_info(id)))
906 }
907
908 /// Returns [`EntityRef`]s that expose read-only operations for the given
909 /// `entities`, returning [`Err`] if any of the given entities do not exist.
910 /// Instead of immediately unwrapping the value returned from this function,
911 /// prefer [`World::entity`].
912 ///
913 /// This function supports fetching a single entity or multiple entities:
914 /// - Pass an [`Entity`] to receive a single [`EntityRef`].
915 /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].
916 /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.
917 /// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
918 /// [`EntityHashMap<EntityRef>`](crate::entity::EntityHashMap).
919 ///
920 /// # Errors
921 ///
922 /// If any of the given `entities` do not exist in the world, the first
923 /// [`Entity`] found to be missing will return an [`EntityNotSpawnedError`].
924 ///
925 /// # Examples
926 ///
927 /// For examples, see [`World::entity`].
928 ///
929 /// [`EntityHashSet`]: crate::entity::EntityHashSet
930 #[inline]
931 pub fn get_entity<F: WorldEntityFetch>(
932 &self,
933 entities: F,
934 ) -> Result<F::Ref<'_>, EntityNotSpawnedError> {
935 let cell = self.as_unsafe_world_cell_readonly();
936 // SAFETY: `&self` gives read access to the entire world, and prevents mutable access.
937 unsafe { entities.fetch_ref(cell) }
938 }
939
940 /// Returns [`EntityMut`]s that expose read and write operations for the
941 /// given `entities`, returning [`Err`] if any of the given entities do not
942 /// exist. Instead of immediately unwrapping the value returned from this
943 /// function, prefer [`World::entity_mut`].
944 ///
945 /// This function supports fetching a single entity or multiple entities:
946 /// - Pass an [`Entity`] to receive a single [`EntityWorldMut`].
947 /// - This reference type allows for structural changes to the entity,
948 /// such as adding or removing components, or despawning the entity.
949 /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
950 /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
951 /// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
952 /// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).
953 ///
954 /// In order to perform structural changes on the returned entity reference,
955 /// such as adding or removing components, or despawning the entity, only a
956 /// single [`Entity`] can be passed to this function. Allowing multiple
957 /// entities at the same time with structural access would lead to undefined
958 /// behavior, so [`EntityMut`] is returned when requesting multiple entities.
959 ///
960 /// # Errors
961 ///
962 /// - Returns [`EntityMutableFetchError::NotSpawned`] if any of the given `entities` do not exist in the world.
963 /// - Only the first entity found to be missing will be returned.
964 /// - Returns [`EntityMutableFetchError::AliasedMutability`] if the same entity is requested multiple times.
965 ///
966 /// # Examples
967 ///
968 /// For examples, see [`World::entity_mut`].
969 ///
970 /// [`EntityHashSet`]: crate::entity::EntityHashSet
971 #[inline]
972 pub fn get_entity_mut<F: WorldEntityFetch>(
973 &mut self,
974 entities: F,
975 ) -> Result<F::Mut<'_>, EntityMutableFetchError> {
976 let cell = self.as_unsafe_world_cell();
977 // SAFETY: `&mut self` gives mutable access to the entire world,
978 // and prevents any other access to the world.
979 unsafe { entities.fetch_mut(cell) }
980 }
981
982 /// Simultaneously provides access to entity data and a command queue, which
983 /// will be applied when the world is next flushed.
984 ///
985 /// This allows using borrowed entity data to construct commands where the
986 /// borrow checker would otherwise prevent it.
987 ///
988 /// See [`DeferredWorld::entities_and_commands`] for the deferred version.
989 ///
990 /// # Example
991 ///
992 /// ```rust
993 /// # use bevy_ecs::{prelude::*, world::DeferredWorld};
994 /// #[derive(Component)]
995 /// struct Targets(Vec<Entity>);
996 /// #[derive(Component)]
997 /// struct TargetedBy(Entity);
998 ///
999 /// let mut world: World = // ...
1000 /// # World::new();
1001 /// # let e1 = world.spawn_empty().id();
1002 /// # let e2 = world.spawn_empty().id();
1003 /// # let eid = world.spawn(Targets(vec![e1, e2])).id();
1004 /// let (entities, mut commands) = world.entities_and_commands();
1005 ///
1006 /// let entity = entities.get(eid).unwrap();
1007 /// for &target in entity.get::<Targets>().unwrap().0.iter() {
1008 /// commands.entity(target).insert(TargetedBy(eid));
1009 /// }
1010 /// # world.flush();
1011 /// # assert_eq!(world.get::<TargetedBy>(e1).unwrap().0, eid);
1012 /// # assert_eq!(world.get::<TargetedBy>(e2).unwrap().0, eid);
1013 /// ```
1014 pub fn entities_and_commands(&mut self) -> (EntityFetcher<'_>, Commands<'_, '_>) {
1015 let cell = self.as_unsafe_world_cell();
1016 // SAFETY: `&mut self` gives mutable access to the entire world, and prevents simultaneous access.
1017 let fetcher = unsafe { EntityFetcher::new(cell) };
1018 // SAFETY:
1019 // - `&mut self` gives mutable access to the entire world, and prevents simultaneous access.
1020 // - Command queue access does not conflict with entity access.
1021 let raw_queue = unsafe { cell.get_raw_command_queue() };
1022 // SAFETY: `&mut self` ensures the commands does not outlive the world.
1023 let commands = unsafe {
1024 Commands::new_raw_from_entities(raw_queue, cell.entities_allocator(), cell.entities())
1025 };
1026
1027 (fetcher, commands)
1028 }
1029
1030 /// Spawns the bundle on the valid but not spawned entity.
1031 /// If the entity can not be spawned for any reason, returns an error.
1032 ///
1033 /// If it succeeds, this declares the entity to have this bundle.
1034 ///
1035 /// In general, you should prefer [`spawn`](Self::spawn).
1036 /// Spawn internally calls this method, but it takes care of finding a suitable [`Entity`] for you.
1037 /// This is made available for advanced use, which you can see at [`EntityAllocator::alloc`].
1038 ///
1039 /// # Risk
1040 ///
1041 /// It is possible to spawn an `entity` that has not been allocated yet;
1042 /// 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.
1043 /// This would cause a panic.
1044 ///
1045 /// Manual spawning is a powerful tool, but must be used carefully.
1046 ///
1047 /// # Example
1048 ///
1049 /// Currently, this is primarily used to spawn entities that come from [`EntityAllocator::alloc`].
1050 /// See that for an example.
1051 #[track_caller]
1052 pub fn spawn_at<B: Bundle>(
1053 &mut self,
1054 entity: Entity,
1055 bundle: B,
1056 ) -> Result<EntityWorldMut<'_>, SpawnError> {
1057 move_as_ptr!(bundle);
1058 self.spawn_at_with_caller(entity, bundle, MaybeLocation::caller())
1059 }
1060
1061 pub(crate) fn spawn_at_with_caller<B: Bundle>(
1062 &mut self,
1063 entity: Entity,
1064 bundle: MovingPtr<'_, B>,
1065 caller: MaybeLocation,
1066 ) -> Result<EntityWorldMut<'_>, SpawnError> {
1067 self.entities.check_can_spawn_at(entity)?;
1068 Ok(self.spawn_at_unchecked(entity, bundle, caller))
1069 }
1070
1071 /// Spawns `bundle` on `entity`.
1072 ///
1073 /// # Panics
1074 ///
1075 /// Panics if the entity index is already constructed
1076 pub(crate) fn spawn_at_unchecked<B: Bundle>(
1077 &mut self,
1078 entity: Entity,
1079 bundle: MovingPtr<'_, B>,
1080 caller: MaybeLocation,
1081 ) -> EntityWorldMut<'_> {
1082 let change_tick = self.change_tick();
1083 let mut bundle_spawner = BundleSpawner::new::<B>(self, change_tick);
1084 let (bundle, entity_location) = bundle.partial_move(|bundle| {
1085 // SAFETY:
1086 // - `B` matches `bundle_spawner`'s type
1087 // - `entity` is allocated but non-existent
1088 // - `B::Effect` is unconstrained, and `B::apply_effect` is called exactly once on the bundle after this call.
1089 // - This function ensures that the value pointed to by `bundle` must not be accessed for anything afterwards by consuming
1090 // the `MovingPtr`. The value is otherwise only used to call `apply_effect` within this function, and the safety invariants
1091 // of `DynamicBundle` ensure that only the elements that have not been moved out of by this call are accessed.
1092 unsafe { bundle_spawner.spawn_at::<B>(entity, bundle, caller) }
1093 });
1094
1095 let mut entity_location = Some(entity_location);
1096
1097 // SAFETY: command_queue is not referenced anywhere else
1098 if !unsafe { self.command_queue.is_empty() } {
1099 self.flush();
1100 entity_location = self
1101 .entities()
1102 .get(entity)
1103 .expect("For this to fail, a queued command would need to despawn the entity.");
1104 }
1105
1106 // SAFETY: entity and location are valid, as they were just created above
1107 let mut entity = unsafe { EntityWorldMut::new(self, entity, entity_location) };
1108 // SAFETY:
1109 // - This is called exactly once after `get_components` has been called in `spawn_non_existent`.
1110 // - `bundle` had it's `get_components` function called exactly once inside `spawn_non_existent`.
1111 unsafe { B::apply_effect(bundle, &mut entity) };
1112 entity
1113 }
1114
1115 /// A faster version of [`spawn_at`](Self::spawn_at) for the empty bundle.
1116 #[track_caller]
1117 pub fn spawn_empty_at(&mut self, entity: Entity) -> Result<EntityWorldMut<'_>, SpawnError> {
1118 self.spawn_empty_at_with_caller(entity, MaybeLocation::caller())
1119 }
1120
1121 pub(crate) fn spawn_empty_at_with_caller(
1122 &mut self,
1123 entity: Entity,
1124 caller: MaybeLocation,
1125 ) -> Result<EntityWorldMut<'_>, SpawnError> {
1126 self.entities.check_can_spawn_at(entity)?;
1127 Ok(self.spawn_empty_at_unchecked(entity, caller))
1128 }
1129
1130 /// A faster version of [`spawn_at_unchecked`](Self::spawn_at_unchecked) for the empty bundle.
1131 ///
1132 /// # Panics
1133 ///
1134 /// Panics if the entity index is already spawned
1135 pub(crate) fn spawn_empty_at_unchecked(
1136 &mut self,
1137 entity: Entity,
1138 caller: MaybeLocation,
1139 ) -> EntityWorldMut<'_> {
1140 // SAFETY: Locations are immediately made valid
1141 unsafe {
1142 let archetype = self.archetypes.empty_mut();
1143 // PERF: consider avoiding allocating entities in the empty archetype unless needed
1144 let table_row = self.storages.tables[archetype.table_id()].allocate(entity);
1145 // SAFETY: no components are allocated by archetype.allocate() because the archetype is
1146 // empty
1147 let location = archetype.allocate(entity, table_row);
1148 let change_tick = self.change_tick();
1149 let was_at = self.entities.set_location(entity.index(), Some(location));
1150 assert!(
1151 was_at.is_none(),
1152 "Attempting to construct an empty entity, but it was already constructed."
1153 );
1154 self.entities
1155 .mark_spawned_or_despawned(entity.index(), caller, change_tick);
1156
1157 EntityWorldMut::new(self, entity, Some(location))
1158 }
1159 }
1160
1161 /// Spawns a new [`Entity`] with a given [`Bundle`] of [components](`Component`) and returns
1162 /// a corresponding [`EntityWorldMut`], which can be used to add components to the entity or
1163 /// retrieve its id. In case large batches of entities need to be spawned, consider using
1164 /// [`World::spawn_batch`] instead.
1165 ///
1166 /// ```
1167 /// use bevy_ecs::{bundle::Bundle, component::Component, world::World};
1168 ///
1169 /// #[derive(Component)]
1170 /// struct Position {
1171 /// x: f32,
1172 /// y: f32,
1173 /// }
1174 ///
1175 /// #[derive(Component)]
1176 /// struct Velocity {
1177 /// x: f32,
1178 /// y: f32,
1179 /// };
1180 ///
1181 /// #[derive(Component)]
1182 /// struct Name(&'static str);
1183 ///
1184 /// #[derive(Bundle)]
1185 /// struct PhysicsBundle {
1186 /// position: Position,
1187 /// velocity: Velocity,
1188 /// }
1189 ///
1190 /// let mut world = World::new();
1191 ///
1192 /// // `spawn` can accept a single component:
1193 /// world.spawn(Position { x: 0.0, y: 0.0 });
1194 ///
1195 /// // It can also accept a tuple of components:
1196 /// world.spawn((
1197 /// Position { x: 0.0, y: 0.0 },
1198 /// Velocity { x: 1.0, y: 1.0 },
1199 /// ));
1200 ///
1201 /// // Or it can accept a pre-defined Bundle of components:
1202 /// world.spawn(PhysicsBundle {
1203 /// position: Position { x: 2.0, y: 2.0 },
1204 /// velocity: Velocity { x: 0.0, y: 4.0 },
1205 /// });
1206 ///
1207 /// let entity = world
1208 /// // Tuples can also mix Bundles and Components
1209 /// .spawn((
1210 /// PhysicsBundle {
1211 /// position: Position { x: 2.0, y: 2.0 },
1212 /// velocity: Velocity { x: 0.0, y: 4.0 },
1213 /// },
1214 /// Name("Elaina Proctor"),
1215 /// ))
1216 /// // Calling id() will return the unique identifier for the spawned entity
1217 /// .id();
1218 /// let position = world.entity(entity).get::<Position>().unwrap();
1219 /// assert_eq!(position.x, 2.0);
1220 /// ```
1221 #[track_caller]
1222 pub fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityWorldMut<'_> {
1223 move_as_ptr!(bundle);
1224 self.spawn_with_caller(bundle, MaybeLocation::caller())
1225 }
1226
1227 pub(crate) fn spawn_with_caller<B: Bundle>(
1228 &mut self,
1229 bundle: MovingPtr<'_, B>,
1230 caller: MaybeLocation,
1231 ) -> EntityWorldMut<'_> {
1232 let entity = self.allocator.alloc();
1233 // This was just spawned from null, so it shouldn't panic.
1234 self.spawn_at_unchecked(entity, bundle, caller)
1235 }
1236
1237 /// Spawns a new [`Entity`] and returns a corresponding [`EntityWorldMut`], which can be used
1238 /// to add components to the entity or retrieve its id.
1239 ///
1240 /// ```
1241 /// use bevy_ecs::{component::Component, world::World};
1242 ///
1243 /// #[derive(Component)]
1244 /// struct Position {
1245 /// x: f32,
1246 /// y: f32,
1247 /// }
1248 /// #[derive(Component)]
1249 /// struct Label(&'static str);
1250 /// #[derive(Component)]
1251 /// struct Num(u32);
1252 ///
1253 /// let mut world = World::new();
1254 /// let entity = world.spawn_empty()
1255 /// .insert(Position { x: 0.0, y: 0.0 }) // add a single component
1256 /// .insert((Num(1), Label("hello"))) // add a bundle of components
1257 /// .id();
1258 ///
1259 /// let position = world.entity(entity).get::<Position>().unwrap();
1260 /// assert_eq!(position.x, 0.0);
1261 /// ```
1262 #[track_caller]
1263 pub fn spawn_empty(&mut self) -> EntityWorldMut<'_> {
1264 self.spawn_empty_with_caller(MaybeLocation::caller())
1265 }
1266
1267 pub(crate) fn spawn_empty_with_caller(&mut self, caller: MaybeLocation) -> EntityWorldMut<'_> {
1268 let entity = self.allocator.alloc();
1269 // This was just spawned from null, so it shouldn't panic.
1270 self.spawn_empty_at_unchecked(entity, caller)
1271 }
1272
1273 /// Spawns a batch of entities with the same component [`Bundle`] type. Takes a given
1274 /// [`Bundle`] iterator and returns a corresponding [`Entity`] iterator.
1275 /// This is more efficient than spawning entities and adding components to them individually
1276 /// using [`World::spawn`], but it is limited to spawning entities with the same [`Bundle`]
1277 /// type, whereas spawning individually is more flexible.
1278 ///
1279 /// ```
1280 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1281 ///
1282 /// #[derive(Component)]
1283 /// struct Str(&'static str);
1284 /// #[derive(Component)]
1285 /// struct Num(u32);
1286 ///
1287 /// let mut world = World::new();
1288 /// let entities = world.spawn_batch(vec![
1289 /// (Str("a"), Num(0)), // the first entity
1290 /// (Str("b"), Num(1)), // the second entity
1291 /// ]).collect::<Vec<Entity>>();
1292 ///
1293 /// assert_eq!(entities.len(), 2);
1294 /// ```
1295 #[track_caller]
1296 pub fn spawn_batch<I>(&mut self, iter: I) -> SpawnBatchIter<'_, I::IntoIter>
1297 where
1298 I: IntoIterator,
1299 I::Item: Bundle<Effect: NoBundleEffect>,
1300 {
1301 SpawnBatchIter::new(self, iter.into_iter(), MaybeLocation::caller())
1302 }
1303
1304 /// Retrieves a reference to the given `entity`'s [`Component`] of the given type.
1305 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
1306 /// ```
1307 /// use bevy_ecs::{component::Component, world::World};
1308 ///
1309 /// #[derive(Component)]
1310 /// struct Position {
1311 /// x: f32,
1312 /// y: f32,
1313 /// }
1314 ///
1315 /// let mut world = World::new();
1316 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
1317 /// let position = world.get::<Position>(entity).unwrap();
1318 /// assert_eq!(position.x, 0.0);
1319 /// ```
1320 #[inline]
1321 pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {
1322 self.get_entity(entity).ok()?.get()
1323 }
1324
1325 /// Retrieves a mutable reference to the given `entity`'s [`Component`] of the given type.
1326 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
1327 /// ```
1328 /// use bevy_ecs::{component::Component, world::World};
1329 ///
1330 /// #[derive(Component)]
1331 /// struct Position {
1332 /// x: f32,
1333 /// y: f32,
1334 /// }
1335 ///
1336 /// let mut world = World::new();
1337 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
1338 /// let mut position = world.get_mut::<Position>(entity).unwrap();
1339 /// position.x = 1.0;
1340 /// ```
1341 #[inline]
1342 pub fn get_mut<T: Component<Mutability = Mutable>>(
1343 &mut self,
1344 entity: Entity,
1345 ) -> Option<Mut<'_, T>> {
1346 self.get_entity_mut(entity).ok()?.into_mut()
1347 }
1348
1349 /// Temporarily removes a [`Component`] `T` from the provided [`Entity`] and
1350 /// runs the provided closure on it, returning the result if `T` was available.
1351 /// This will trigger the `Remove` and `Replace` component hooks without
1352 /// causing an archetype move.
1353 ///
1354 /// This is most useful with immutable components, where removal and reinsertion
1355 /// is the only way to modify a value.
1356 ///
1357 /// If you do not need to ensure the above hooks are triggered, and your component
1358 /// is mutable, prefer using [`get_mut`](World::get_mut).
1359 ///
1360 /// # Examples
1361 ///
1362 /// ```rust
1363 /// # use bevy_ecs::prelude::*;
1364 /// #
1365 /// #[derive(Component, PartialEq, Eq, Debug)]
1366 /// #[component(immutable)]
1367 /// struct Foo(bool);
1368 ///
1369 /// # let mut world = World::default();
1370 /// # world.register_component::<Foo>();
1371 /// #
1372 /// # let entity = world.spawn(Foo(false)).id();
1373 /// #
1374 /// world.modify_component(entity, |foo: &mut Foo| {
1375 /// foo.0 = true;
1376 /// });
1377 /// #
1378 /// # assert_eq!(world.get::<Foo>(entity), Some(&Foo(true)));
1379 /// ```
1380 #[inline]
1381 #[track_caller]
1382 pub fn modify_component<T: Component, R>(
1383 &mut self,
1384 entity: Entity,
1385 f: impl FnOnce(&mut T) -> R,
1386 ) -> Result<Option<R>, EntityMutableFetchError> {
1387 let mut world = DeferredWorld::from(&mut *self);
1388
1389 let result = world.modify_component_with_relationship_hook_mode(
1390 entity,
1391 RelationshipHookMode::Run,
1392 f,
1393 )?;
1394
1395 self.flush();
1396 Ok(result)
1397 }
1398
1399 /// Temporarily removes a [`Component`] identified by the provided
1400 /// [`ComponentId`] from the provided [`Entity`] and runs the provided
1401 /// closure on it, returning the result if the component was available.
1402 /// This will trigger the `Remove` and `Replace` component hooks without
1403 /// causing an archetype move.
1404 ///
1405 /// This is most useful with immutable components, where removal and reinsertion
1406 /// is the only way to modify a value.
1407 ///
1408 /// If you do not need to ensure the above hooks are triggered, and your component
1409 /// is mutable, prefer using [`get_mut_by_id`](World::get_mut_by_id).
1410 ///
1411 /// You should prefer the typed [`modify_component`](World::modify_component)
1412 /// whenever possible.
1413 #[inline]
1414 #[track_caller]
1415 pub fn modify_component_by_id<R>(
1416 &mut self,
1417 entity: Entity,
1418 component_id: ComponentId,
1419 f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,
1420 ) -> Result<Option<R>, EntityMutableFetchError> {
1421 let mut world = DeferredWorld::from(&mut *self);
1422
1423 let result = world.modify_component_by_id_with_relationship_hook_mode(
1424 entity,
1425 component_id,
1426 RelationshipHookMode::Run,
1427 f,
1428 )?;
1429
1430 self.flush();
1431 Ok(result)
1432 }
1433
1434 /// Despawns the given [`Entity`], if it exists.
1435 /// This will also remove all of the entity's [`Components`](Component).
1436 ///
1437 /// Returns `true` if the entity is successfully despawned and `false` if
1438 /// the entity does not exist.
1439 /// This counts despawning a not constructed entity as a success, and frees it to the allocator.
1440 /// See [entity](crate::entity) module docs for more about construction.
1441 ///
1442 /// # Note
1443 ///
1444 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
1445 /// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1446 ///
1447 /// ```
1448 /// use bevy_ecs::{component::Component, world::World};
1449 ///
1450 /// #[derive(Component)]
1451 /// struct Position {
1452 /// x: f32,
1453 /// y: f32,
1454 /// }
1455 ///
1456 /// let mut world = World::new();
1457 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
1458 /// assert!(world.despawn(entity));
1459 /// assert!(world.get_entity(entity).is_err());
1460 /// assert!(world.get::<Position>(entity).is_none());
1461 /// ```
1462 #[track_caller]
1463 #[inline]
1464 pub fn despawn(&mut self, entity: Entity) -> bool {
1465 if let Err(error) = self.despawn_with_caller(entity, MaybeLocation::caller()) {
1466 warn!("{error}");
1467 false
1468 } else {
1469 true
1470 }
1471 }
1472
1473 /// Despawns the given `entity`, if it exists. This will also remove all of the entity's
1474 /// [`Components`](Component).
1475 ///
1476 /// Returns an [`EntityDespawnError`] if the entity is not spawned to be despawned.
1477 ///
1478 /// # Note
1479 ///
1480 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
1481 /// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1482 #[track_caller]
1483 #[inline]
1484 pub fn try_despawn(&mut self, entity: Entity) -> Result<(), EntityDespawnError> {
1485 self.despawn_with_caller(entity, MaybeLocation::caller())
1486 }
1487
1488 #[inline]
1489 pub(crate) fn despawn_with_caller(
1490 &mut self,
1491 entity: Entity,
1492 caller: MaybeLocation,
1493 ) -> Result<(), EntityDespawnError> {
1494 match self.get_entity_mut(entity) {
1495 Ok(entity) => {
1496 entity.despawn_with_caller(caller);
1497 Ok(())
1498 }
1499 // Only one entity.
1500 Err(EntityMutableFetchError::AliasedMutability(_)) => unreachable!(),
1501 Err(EntityMutableFetchError::NotSpawned(err)) => Err(EntityDespawnError(err)),
1502 }
1503 }
1504
1505 /// Performs [`try_despawn_no_free`](Self::try_despawn_no_free), warning on errors.
1506 /// See that method for more information.
1507 #[track_caller]
1508 #[inline]
1509 pub fn despawn_no_free(&mut self, entity: Entity) -> Option<Entity> {
1510 match self.despawn_no_free_with_caller(entity, MaybeLocation::caller()) {
1511 Ok(entity) => Some(entity),
1512 Err(error) => {
1513 warn!("{error}");
1514 None
1515 }
1516 }
1517 }
1518
1519 /// Despawns the given `entity`, if it exists.
1520 /// This will also remove all of the entity's [`Component`]s.
1521 ///
1522 /// The *only* difference between this and [despawning](Self::despawn) an entity is that this does not release the `entity` to be reused.
1523 /// 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.
1524 /// In general, [`despawn`](Self::despawn) should be used instead, which automatically allows the row to be reused.
1525 ///
1526 /// Returns the new [`Entity`] if of the despawned [`EntityIndex`](crate::entity::EntityIndex), which should eventually either be re-spawned or freed to the allocator.
1527 /// Returns an [`EntityDespawnError`] if the entity is not spawned.
1528 ///
1529 /// # Note
1530 ///
1531 /// This will also *despawn* the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
1532 /// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1533 ///
1534 /// # Example
1535 ///
1536 /// There is no simple example in which this would be practical, but one use for this is a custom entity allocator.
1537 /// Despawning internally calls this and frees the entity id to Bevy's default entity allocator.
1538 /// The same principal can be used to create custom allocators with additional properties.
1539 /// For example, this could be used to make an allocator that yields groups of consecutive [`EntityIndex`](crate::entity::EntityIndex)s, etc.
1540 /// See [`EntityAllocator::alloc`] for more on this.
1541 #[track_caller]
1542 #[inline]
1543 pub fn try_despawn_no_free(&mut self, entity: Entity) -> Result<Entity, EntityDespawnError> {
1544 self.despawn_no_free_with_caller(entity, MaybeLocation::caller())
1545 }
1546
1547 #[inline]
1548 pub(crate) fn despawn_no_free_with_caller(
1549 &mut self,
1550 entity: Entity,
1551 caller: MaybeLocation,
1552 ) -> Result<Entity, EntityDespawnError> {
1553 let mut entity = self.get_entity_mut(entity).map_err(|err| match err {
1554 EntityMutableFetchError::NotSpawned(err) => err,
1555 // Only one entity.
1556 EntityMutableFetchError::AliasedMutability(_) => unreachable!(),
1557 })?;
1558 entity.despawn_no_free_with_caller(caller);
1559 Ok(entity.id())
1560 }
1561
1562 /// Clears the internal component tracker state.
1563 ///
1564 /// The world maintains some internal state about changed and removed components. This state
1565 /// is used by [`RemovedComponents`] to provide access to the entities that had a specific type
1566 /// of component removed since last tick.
1567 ///
1568 /// The state is also used for change detection when accessing components and resources outside
1569 /// of a system, for example via [`World::get_mut()`] or [`World::get_resource_mut()`].
1570 ///
1571 /// By clearing this internal state, the world "forgets" about those changes, allowing a new round
1572 /// of detection to be recorded.
1573 ///
1574 /// When using `bevy_ecs` as part of the full Bevy engine, this method is called automatically
1575 /// by `bevy_app::App::update` and `bevy_app::SubApp::update`, so you don't need to call it manually.
1576 /// When using `bevy_ecs` as a separate standalone crate however, you do need to call this manually.
1577 ///
1578 /// ```
1579 /// # use bevy_ecs::prelude::*;
1580 /// # #[derive(Component, Default)]
1581 /// # struct Transform;
1582 /// // a whole new world
1583 /// let mut world = World::new();
1584 ///
1585 /// // you changed it
1586 /// let entity = world.spawn(Transform::default()).id();
1587 ///
1588 /// // change is detected
1589 /// let transform = world.get_mut::<Transform>(entity).unwrap();
1590 /// assert!(transform.is_changed());
1591 ///
1592 /// // update the last change tick
1593 /// world.clear_trackers();
1594 ///
1595 /// // change is no longer detected
1596 /// let transform = world.get_mut::<Transform>(entity).unwrap();
1597 /// assert!(!transform.is_changed());
1598 /// ```
1599 ///
1600 /// [`RemovedComponents`]: crate::lifecycle::RemovedComponents
1601 pub fn clear_trackers(&mut self) {
1602 self.removed_components.update();
1603 self.last_change_tick = self.increment_change_tick();
1604 }
1605
1606 /// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently
1607 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1608 /// ```
1609 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1610 ///
1611 /// #[derive(Component, Debug, PartialEq)]
1612 /// struct Position {
1613 /// x: f32,
1614 /// y: f32,
1615 /// }
1616 ///
1617 /// #[derive(Component)]
1618 /// struct Velocity {
1619 /// x: f32,
1620 /// y: f32,
1621 /// }
1622 ///
1623 /// let mut world = World::new();
1624 /// let entities = world.spawn_batch(vec![
1625 /// (Position { x: 0.0, y: 0.0}, Velocity { x: 1.0, y: 0.0 }),
1626 /// (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }),
1627 /// ]).collect::<Vec<Entity>>();
1628 ///
1629 /// let mut query = world.query::<(&mut Position, &Velocity)>();
1630 /// for (mut position, velocity) in query.iter_mut(&mut world) {
1631 /// position.x += velocity.x;
1632 /// position.y += velocity.y;
1633 /// }
1634 ///
1635 /// assert_eq!(world.get::<Position>(entities[0]).unwrap(), &Position { x: 1.0, y: 0.0 });
1636 /// assert_eq!(world.get::<Position>(entities[1]).unwrap(), &Position { x: 0.0, y: 1.0 });
1637 /// ```
1638 ///
1639 /// To iterate over entities in a deterministic order,
1640 /// sort the results of the query using the desired component as a key.
1641 /// Note that this requires fetching the whole result set from the query
1642 /// and allocation of a [`Vec`] to store it.
1643 ///
1644 /// ```
1645 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1646 ///
1647 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Debug)]
1648 /// struct Order(i32);
1649 /// #[derive(Component, PartialEq, Debug)]
1650 /// struct Label(&'static str);
1651 ///
1652 /// let mut world = World::new();
1653 /// let a = world.spawn((Order(2), Label("second"))).id();
1654 /// let b = world.spawn((Order(3), Label("third"))).id();
1655 /// let c = world.spawn((Order(1), Label("first"))).id();
1656 /// let mut entities = world.query::<(Entity, &Order, &Label)>()
1657 /// .iter(&world)
1658 /// .collect::<Vec<_>>();
1659 /// // Sort the query results by their `Order` component before comparing
1660 /// // to expected results. Query iteration order should not be relied on.
1661 /// entities.sort_by_key(|e| e.1);
1662 /// assert_eq!(entities, vec![
1663 /// (c, &Order(1), &Label("first")),
1664 /// (a, &Order(2), &Label("second")),
1665 /// (b, &Order(3), &Label("third")),
1666 /// ]);
1667 /// ```
1668 #[inline]
1669 pub fn query<D: QueryData>(&mut self) -> QueryState<D, ()> {
1670 self.query_filtered::<D, ()>()
1671 }
1672
1673 /// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently
1674 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1675 /// ```
1676 /// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};
1677 ///
1678 /// #[derive(Component)]
1679 /// struct A;
1680 /// #[derive(Component)]
1681 /// struct B;
1682 ///
1683 /// let mut world = World::new();
1684 /// let e1 = world.spawn(A).id();
1685 /// let e2 = world.spawn((A, B)).id();
1686 ///
1687 /// let mut query = world.query_filtered::<Entity, With<B>>();
1688 /// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();
1689 ///
1690 /// assert_eq!(matching_entities, vec![e2]);
1691 /// ```
1692 #[inline]
1693 pub fn query_filtered<D: QueryData, F: QueryFilter>(&mut self) -> QueryState<D, F> {
1694 QueryState::new(self)
1695 }
1696
1697 /// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently
1698 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1699 /// ```
1700 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1701 ///
1702 /// #[derive(Component, Debug, PartialEq)]
1703 /// struct Position {
1704 /// x: f32,
1705 /// y: f32,
1706 /// }
1707 ///
1708 /// let mut world = World::new();
1709 /// world.spawn_batch(vec![
1710 /// Position { x: 0.0, y: 0.0 },
1711 /// Position { x: 1.0, y: 1.0 },
1712 /// ]);
1713 ///
1714 /// fn get_positions(world: &World) -> Vec<(Entity, &Position)> {
1715 /// let mut query = world.try_query::<(Entity, &Position)>().unwrap();
1716 /// query.iter(world).collect()
1717 /// }
1718 ///
1719 /// let positions = get_positions(&world);
1720 ///
1721 /// assert_eq!(world.get::<Position>(positions[0].0).unwrap(), positions[0].1);
1722 /// assert_eq!(world.get::<Position>(positions[1].0).unwrap(), positions[1].1);
1723 /// ```
1724 ///
1725 /// Requires only an immutable world reference, but may fail if, for example,
1726 /// the components that make up this query have not been registered into the world.
1727 /// ```
1728 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1729 ///
1730 /// #[derive(Component)]
1731 /// struct A;
1732 ///
1733 /// let mut world = World::new();
1734 ///
1735 /// let none_query = world.try_query::<&A>();
1736 /// assert!(none_query.is_none());
1737 ///
1738 /// world.register_component::<A>();
1739 ///
1740 /// let some_query = world.try_query::<&A>();
1741 /// assert!(some_query.is_some());
1742 /// ```
1743 #[inline]
1744 pub fn try_query<D: QueryData>(&self) -> Option<QueryState<D, ()>> {
1745 self.try_query_filtered::<D, ()>()
1746 }
1747
1748 /// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently
1749 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1750 /// ```
1751 /// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};
1752 ///
1753 /// #[derive(Component)]
1754 /// struct A;
1755 /// #[derive(Component)]
1756 /// struct B;
1757 ///
1758 /// let mut world = World::new();
1759 /// let e1 = world.spawn(A).id();
1760 /// let e2 = world.spawn((A, B)).id();
1761 ///
1762 /// let mut query = world.try_query_filtered::<Entity, With<B>>().unwrap();
1763 /// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();
1764 ///
1765 /// assert_eq!(matching_entities, vec![e2]);
1766 /// ```
1767 ///
1768 /// Requires only an immutable world reference, but may fail if, for example,
1769 /// the components that make up this query have not been registered into the world.
1770 #[inline]
1771 pub fn try_query_filtered<D: QueryData, F: QueryFilter>(&self) -> Option<QueryState<D, F>> {
1772 QueryState::try_new(self)
1773 }
1774
1775 /// Returns an iterator of entities that had components of type `T` removed
1776 /// since the last call to [`World::clear_trackers`].
1777 pub fn removed<T: Component>(&self) -> impl Iterator<Item = Entity> + '_ {
1778 self.components
1779 .get_valid_id(TypeId::of::<T>())
1780 .map(|component_id| self.removed_with_id(component_id))
1781 .into_iter()
1782 .flatten()
1783 }
1784
1785 /// Returns an iterator of entities that had components with the given `component_id` removed
1786 /// since the last call to [`World::clear_trackers`].
1787 pub fn removed_with_id(&self, component_id: ComponentId) -> impl Iterator<Item = Entity> + '_ {
1788 self.removed_components
1789 .get(component_id)
1790 .map(|removed| removed.iter_current_update_messages().cloned())
1791 .into_iter()
1792 .flatten()
1793 .map(Into::into)
1794 }
1795
1796 /// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.
1797 ///
1798 /// This enables the dynamic registration of new [`Resource`] definitions at runtime for
1799 /// advanced use cases.
1800 ///
1801 /// # Note
1802 ///
1803 /// Registering a [`Resource`] does not insert it into [`World`]. For insertion, you could use
1804 /// [`World::insert_resource_by_id`].
1805 pub fn register_resource_with_descriptor(
1806 &mut self,
1807 descriptor: ComponentDescriptor,
1808 ) -> ComponentId {
1809 self.components_registrator()
1810 .register_resource_with_descriptor(descriptor)
1811 }
1812
1813 /// Initializes a new resource and returns the [`ComponentId`] created for it.
1814 ///
1815 /// If the resource already exists, nothing happens.
1816 ///
1817 /// The value given by the [`FromWorld::from_world`] method will be used.
1818 /// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],
1819 /// and those default values will be here instead.
1820 #[inline]
1821 #[track_caller]
1822 pub fn init_resource<R: Resource + FromWorld>(&mut self) -> ComponentId {
1823 let caller = MaybeLocation::caller();
1824 let component_id = self.components_registrator().register_resource::<R>();
1825 if self
1826 .storages
1827 .resources
1828 .get(component_id)
1829 .is_none_or(|data| !data.is_present())
1830 {
1831 let value = R::from_world(self);
1832 OwningPtr::make(value, |ptr| {
1833 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1834 unsafe {
1835 self.insert_resource_by_id(component_id, ptr, caller);
1836 }
1837 });
1838 }
1839 component_id
1840 }
1841
1842 /// Inserts a new resource with the given `value`.
1843 ///
1844 /// Resources are "unique" data of a given type.
1845 /// If you insert a resource of a type that already exists,
1846 /// you will overwrite any existing data.
1847 #[inline]
1848 #[track_caller]
1849 pub fn insert_resource<R: Resource>(&mut self, value: R) {
1850 self.insert_resource_with_caller(value, MaybeLocation::caller());
1851 }
1852
1853 /// Split into a new function so we can pass the calling location into the function when using
1854 /// as a command.
1855 #[inline]
1856 pub(crate) fn insert_resource_with_caller<R: Resource>(
1857 &mut self,
1858 value: R,
1859 caller: MaybeLocation,
1860 ) {
1861 let component_id = self.components_registrator().register_resource::<R>();
1862 OwningPtr::make(value, |ptr| {
1863 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1864 unsafe {
1865 self.insert_resource_by_id(component_id, ptr, caller);
1866 }
1867 });
1868 }
1869
1870 /// Initializes a new non-send resource and returns the [`ComponentId`] created for it.
1871 ///
1872 /// If the resource already exists, nothing happens.
1873 ///
1874 /// The value given by the [`FromWorld::from_world`] method will be used.
1875 /// Note that any resource with the `Default` trait automatically implements `FromWorld`,
1876 /// and those default values will be here instead.
1877 ///
1878 /// # Panics
1879 ///
1880 /// Panics if called from a thread other than the main thread.
1881 #[inline]
1882 #[track_caller]
1883 pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> ComponentId {
1884 let caller = MaybeLocation::caller();
1885 let component_id = self.components_registrator().register_non_send::<R>();
1886 if self
1887 .storages
1888 .non_send_resources
1889 .get(component_id)
1890 .is_none_or(|data| !data.is_present())
1891 {
1892 let value = R::from_world(self);
1893 OwningPtr::make(value, |ptr| {
1894 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1895 unsafe {
1896 self.insert_non_send_by_id(component_id, ptr, caller);
1897 }
1898 });
1899 }
1900 component_id
1901 }
1902
1903 /// Inserts a new non-send resource with the given `value`.
1904 ///
1905 /// `NonSend` resources cannot be sent across threads,
1906 /// and do not need the `Send + Sync` bounds.
1907 /// Systems with `NonSend` resources are always scheduled on the main thread.
1908 ///
1909 /// # Panics
1910 /// If a value is already present, this function will panic if called
1911 /// from a different thread than where the original value was inserted from.
1912 #[inline]
1913 #[track_caller]
1914 pub fn insert_non_send_resource<R: 'static>(&mut self, value: R) {
1915 let caller = MaybeLocation::caller();
1916 let component_id = self.components_registrator().register_non_send::<R>();
1917 OwningPtr::make(value, |ptr| {
1918 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1919 unsafe {
1920 self.insert_non_send_by_id(component_id, ptr, caller);
1921 }
1922 });
1923 }
1924
1925 /// Removes the resource of a given type and returns it, if it exists. Otherwise returns `None`.
1926 #[inline]
1927 pub fn remove_resource<R: Resource>(&mut self) -> Option<R> {
1928 let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;
1929 let (ptr, _, _) = self.storages.resources.get_mut(component_id)?.remove()?;
1930 // SAFETY: `component_id` was gotten via looking up the `R` type
1931 unsafe { Some(ptr.read::<R>()) }
1932 }
1933
1934 /// Removes a `!Send` resource from the world and returns it, if present.
1935 ///
1936 /// `NonSend` resources cannot be sent across threads,
1937 /// and do not need the `Send + Sync` bounds.
1938 /// Systems with `NonSend` resources are always scheduled on the main thread.
1939 ///
1940 /// Returns `None` if a value was not previously present.
1941 ///
1942 /// # Panics
1943 /// If a value is present, this function will panic if called from a different
1944 /// thread than where the value was inserted from.
1945 #[inline]
1946 pub fn remove_non_send_resource<R: 'static>(&mut self) -> Option<R> {
1947 let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;
1948 let (ptr, _, _) = self
1949 .storages
1950 .non_send_resources
1951 .get_mut(component_id)?
1952 .remove()?;
1953 // SAFETY: `component_id` was gotten via looking up the `R` type
1954 unsafe { Some(ptr.read::<R>()) }
1955 }
1956
1957 /// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.
1958 #[inline]
1959 pub fn contains_resource<R: Resource>(&self) -> bool {
1960 self.components
1961 .get_valid_resource_id(TypeId::of::<R>())
1962 .and_then(|component_id| self.storages.resources.get(component_id))
1963 .is_some_and(ResourceData::is_present)
1964 }
1965
1966 /// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.
1967 #[inline]
1968 pub fn contains_resource_by_id(&self, component_id: ComponentId) -> bool {
1969 self.storages
1970 .resources
1971 .get(component_id)
1972 .is_some_and(ResourceData::is_present)
1973 }
1974
1975 /// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.
1976 #[inline]
1977 pub fn contains_non_send<R: 'static>(&self) -> bool {
1978 self.components
1979 .get_valid_resource_id(TypeId::of::<R>())
1980 .and_then(|component_id| self.storages.non_send_resources.get(component_id))
1981 .is_some_and(ResourceData::is_present)
1982 }
1983
1984 /// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.
1985 #[inline]
1986 pub fn contains_non_send_by_id(&self, component_id: ComponentId) -> bool {
1987 self.storages
1988 .non_send_resources
1989 .get(component_id)
1990 .is_some_and(ResourceData::is_present)
1991 }
1992
1993 /// Returns `true` if a resource of type `R` exists and was added since the world's
1994 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
1995 ///
1996 /// This means that:
1997 /// - When called from an exclusive system, this will check for additions since the system last ran.
1998 /// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]
1999 /// was called.
2000 pub fn is_resource_added<R: Resource>(&self) -> bool {
2001 self.components
2002 .get_valid_resource_id(TypeId::of::<R>())
2003 .is_some_and(|component_id| self.is_resource_added_by_id(component_id))
2004 }
2005
2006 /// Returns `true` if a resource with id `component_id` exists and was added since the world's
2007 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
2008 ///
2009 /// This means that:
2010 /// - When called from an exclusive system, this will check for additions since the system last ran.
2011 /// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]
2012 /// was called.
2013 pub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool {
2014 self.storages
2015 .resources
2016 .get(component_id)
2017 .is_some_and(|resource| {
2018 resource.get_ticks().is_some_and(|ticks| {
2019 ticks.is_added(self.last_change_tick(), self.read_change_tick())
2020 })
2021 })
2022 }
2023
2024 /// Returns `true` if a resource of type `R` exists and was modified since the world's
2025 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
2026 ///
2027 /// This means that:
2028 /// - When called from an exclusive system, this will check for changes since the system last ran.
2029 /// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]
2030 /// was called.
2031 pub fn is_resource_changed<R: Resource>(&self) -> bool {
2032 self.components
2033 .get_valid_resource_id(TypeId::of::<R>())
2034 .is_some_and(|component_id| self.is_resource_changed_by_id(component_id))
2035 }
2036
2037 /// Returns `true` if a resource with id `component_id` exists and was modified since the world's
2038 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
2039 ///
2040 /// This means that:
2041 /// - When called from an exclusive system, this will check for changes since the system last ran.
2042 /// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]
2043 /// was called.
2044 pub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool {
2045 self.storages
2046 .resources
2047 .get(component_id)
2048 .is_some_and(|resource| {
2049 resource.get_ticks().is_some_and(|ticks| {
2050 ticks.is_changed(self.last_change_tick(), self.read_change_tick())
2051 })
2052 })
2053 }
2054
2055 /// Retrieves the change ticks for the given resource.
2056 pub fn get_resource_change_ticks<R: Resource>(&self) -> Option<ComponentTicks> {
2057 self.components
2058 .get_valid_resource_id(TypeId::of::<R>())
2059 .and_then(|component_id| self.get_resource_change_ticks_by_id(component_id))
2060 }
2061
2062 /// Retrieves the change ticks for the given [`ComponentId`].
2063 ///
2064 /// **You should prefer to use the typed API [`World::get_resource_change_ticks`] where possible.**
2065 pub fn get_resource_change_ticks_by_id(
2066 &self,
2067 component_id: ComponentId,
2068 ) -> Option<ComponentTicks> {
2069 self.storages
2070 .resources
2071 .get(component_id)
2072 .and_then(ResourceData::get_ticks)
2073 }
2074
2075 /// Gets a reference to the resource of the given type
2076 ///
2077 /// # Panics
2078 ///
2079 /// Panics if the resource does not exist.
2080 /// Use [`get_resource`](World::get_resource) instead if you want to handle this case.
2081 ///
2082 /// If you want to instead insert a value if the resource does not exist,
2083 /// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
2084 #[inline]
2085 #[track_caller]
2086 pub fn resource<R: Resource>(&self) -> &R {
2087 match self.get_resource() {
2088 Some(x) => x,
2089 None => panic!(
2090 "Requested resource {} does not exist in the `World`.
2091 Did you forget to add it using `app.insert_resource` / `app.init_resource`?
2092 Resources are also implicitly added via `app.add_message`,
2093 and can be added by plugins.",
2094 DebugName::type_name::<R>()
2095 ),
2096 }
2097 }
2098
2099 /// Gets a reference to the resource of the given type
2100 ///
2101 /// # Panics
2102 ///
2103 /// Panics if the resource does not exist.
2104 /// Use [`get_resource_ref`](World::get_resource_ref) instead if you want to handle this case.
2105 ///
2106 /// If you want to instead insert a value if the resource does not exist,
2107 /// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
2108 #[inline]
2109 #[track_caller]
2110 pub fn resource_ref<R: Resource>(&self) -> Ref<'_, R> {
2111 match self.get_resource_ref() {
2112 Some(x) => x,
2113 None => panic!(
2114 "Requested resource {} does not exist in the `World`.
2115 Did you forget to add it using `app.insert_resource` / `app.init_resource`?
2116 Resources are also implicitly added via `app.add_message`,
2117 and can be added by plugins.",
2118 DebugName::type_name::<R>()
2119 ),
2120 }
2121 }
2122
2123 /// Gets a mutable reference to the resource of the given type
2124 ///
2125 /// # Panics
2126 ///
2127 /// Panics if the resource does not exist.
2128 /// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.
2129 ///
2130 /// If you want to instead insert a value if the resource does not exist,
2131 /// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
2132 #[inline]
2133 #[track_caller]
2134 pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {
2135 match self.get_resource_mut() {
2136 Some(x) => x,
2137 None => panic!(
2138 "Requested resource {} does not exist in the `World`.
2139 Did you forget to add it using `app.insert_resource` / `app.init_resource`?
2140 Resources are also implicitly added via `app.add_message`,
2141 and can be added by plugins.",
2142 DebugName::type_name::<R>()
2143 ),
2144 }
2145 }
2146
2147 /// Gets a reference to the resource of the given type if it exists
2148 #[inline]
2149 pub fn get_resource<R: Resource>(&self) -> Option<&R> {
2150 // SAFETY:
2151 // - `as_unsafe_world_cell_readonly` gives permission to access everything immutably
2152 // - `&self` ensures nothing in world is borrowed mutably
2153 unsafe { self.as_unsafe_world_cell_readonly().get_resource() }
2154 }
2155
2156 /// Gets a reference including change detection to the resource of the given type if it exists.
2157 #[inline]
2158 pub fn get_resource_ref<R: Resource>(&self) -> Option<Ref<'_, R>> {
2159 // SAFETY:
2160 // - `as_unsafe_world_cell_readonly` gives permission to access everything immutably
2161 // - `&self` ensures nothing in world is borrowed mutably
2162 unsafe { self.as_unsafe_world_cell_readonly().get_resource_ref() }
2163 }
2164
2165 /// Gets a mutable reference to the resource of the given type if it exists
2166 #[inline]
2167 pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {
2168 // SAFETY:
2169 // - `as_unsafe_world_cell` gives permission to access everything mutably
2170 // - `&mut self` ensures nothing in world is borrowed
2171 unsafe { self.as_unsafe_world_cell().get_resource_mut() }
2172 }
2173
2174 /// Gets a mutable reference to the resource of type `T` if it exists,
2175 /// otherwise inserts the resource using the result of calling `func`.
2176 ///
2177 /// # Example
2178 ///
2179 /// ```
2180 /// # use bevy_ecs::prelude::*;
2181 /// #
2182 /// #[derive(Resource)]
2183 /// struct MyResource(i32);
2184 ///
2185 /// # let mut world = World::new();
2186 /// let my_res = world.get_resource_or_insert_with(|| MyResource(10));
2187 /// assert_eq!(my_res.0, 10);
2188 /// ```
2189 #[inline]
2190 #[track_caller]
2191 pub fn get_resource_or_insert_with<R: Resource>(
2192 &mut self,
2193 func: impl FnOnce() -> R,
2194 ) -> Mut<'_, R> {
2195 let caller = MaybeLocation::caller();
2196 let change_tick = self.change_tick();
2197 let last_change_tick = self.last_change_tick();
2198
2199 let component_id = self.components_registrator().register_resource::<R>();
2200 let data = self.initialize_resource_internal(component_id);
2201 if !data.is_present() {
2202 OwningPtr::make(func(), |ptr| {
2203 // SAFETY: component_id was just initialized and corresponds to resource of type R.
2204 unsafe {
2205 data.insert(ptr, change_tick, caller);
2206 }
2207 });
2208 }
2209
2210 // SAFETY: The resource must be present, as we would have inserted it if it was empty.
2211 let data = unsafe {
2212 data.get_mut(last_change_tick, change_tick)
2213 .debug_checked_unwrap()
2214 };
2215 // SAFETY: The underlying type of the resource is `R`.
2216 unsafe { data.with_type::<R>() }
2217 }
2218
2219 /// Gets a mutable reference to the resource of type `T` if it exists,
2220 /// otherwise initializes the resource by calling its [`FromWorld`]
2221 /// implementation.
2222 ///
2223 /// # Example
2224 ///
2225 /// ```
2226 /// # use bevy_ecs::prelude::*;
2227 /// #
2228 /// #[derive(Resource)]
2229 /// struct Foo(i32);
2230 ///
2231 /// impl Default for Foo {
2232 /// fn default() -> Self {
2233 /// Self(15)
2234 /// }
2235 /// }
2236 ///
2237 /// #[derive(Resource)]
2238 /// struct MyResource(i32);
2239 ///
2240 /// impl FromWorld for MyResource {
2241 /// fn from_world(world: &mut World) -> Self {
2242 /// let foo = world.get_resource_or_init::<Foo>();
2243 /// Self(foo.0 * 2)
2244 /// }
2245 /// }
2246 ///
2247 /// # let mut world = World::new();
2248 /// let my_res = world.get_resource_or_init::<MyResource>();
2249 /// assert_eq!(my_res.0, 30);
2250 /// ```
2251 #[track_caller]
2252 pub fn get_resource_or_init<R: Resource + FromWorld>(&mut self) -> Mut<'_, R> {
2253 let caller = MaybeLocation::caller();
2254 let change_tick = self.change_tick();
2255 let last_change_tick = self.last_change_tick();
2256
2257 let component_id = self.components_registrator().register_resource::<R>();
2258 if self
2259 .storages
2260 .resources
2261 .get(component_id)
2262 .is_none_or(|data| !data.is_present())
2263 {
2264 let value = R::from_world(self);
2265 OwningPtr::make(value, |ptr| {
2266 // SAFETY: component_id was just initialized and corresponds to resource of type R.
2267 unsafe {
2268 self.insert_resource_by_id(component_id, ptr, caller);
2269 }
2270 });
2271 }
2272
2273 // SAFETY: The resource was just initialized if it was empty.
2274 let data = unsafe {
2275 self.storages
2276 .resources
2277 .get_mut(component_id)
2278 .debug_checked_unwrap()
2279 };
2280 // SAFETY: The resource must be present, as we would have inserted it if it was empty.
2281 let data = unsafe {
2282 data.get_mut(last_change_tick, change_tick)
2283 .debug_checked_unwrap()
2284 };
2285 // SAFETY: The underlying type of the resource is `R`.
2286 unsafe { data.with_type::<R>() }
2287 }
2288
2289 /// Gets an immutable reference to the non-send resource of the given type, if it exists.
2290 ///
2291 /// # Panics
2292 ///
2293 /// Panics if the resource does not exist.
2294 /// Use [`get_non_send_resource`](World::get_non_send_resource) instead if you want to handle this case.
2295 ///
2296 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2297 #[inline]
2298 #[track_caller]
2299 pub fn non_send_resource<R: 'static>(&self) -> &R {
2300 match self.get_non_send_resource() {
2301 Some(x) => x,
2302 None => panic!(
2303 "Requested non-send resource {} does not exist in the `World`.
2304 Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?
2305 Non-send resources can also be added by plugins.",
2306 DebugName::type_name::<R>()
2307 ),
2308 }
2309 }
2310
2311 /// Gets a mutable reference to the non-send resource of the given type, if it exists.
2312 ///
2313 /// # Panics
2314 ///
2315 /// Panics if the resource does not exist.
2316 /// Use [`get_non_send_resource_mut`](World::get_non_send_resource_mut) instead if you want to handle this case.
2317 ///
2318 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2319 #[inline]
2320 #[track_caller]
2321 pub fn non_send_resource_mut<R: 'static>(&mut self) -> Mut<'_, R> {
2322 match self.get_non_send_resource_mut() {
2323 Some(x) => x,
2324 None => panic!(
2325 "Requested non-send resource {} does not exist in the `World`.
2326 Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?
2327 Non-send resources can also be added by plugins.",
2328 DebugName::type_name::<R>()
2329 ),
2330 }
2331 }
2332
2333 /// Gets a reference to the non-send resource of the given type, if it exists.
2334 /// Otherwise returns `None`.
2335 ///
2336 /// # Panics
2337 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2338 #[inline]
2339 pub fn get_non_send_resource<R: 'static>(&self) -> Option<&R> {
2340 // SAFETY:
2341 // - `as_unsafe_world_cell_readonly` gives permission to access the entire world immutably
2342 // - `&self` ensures that there are no mutable borrows of world data
2343 unsafe { self.as_unsafe_world_cell_readonly().get_non_send_resource() }
2344 }
2345
2346 /// Gets a mutable reference to the non-send resource of the given type, if it exists.
2347 /// Otherwise returns `None`.
2348 ///
2349 /// # Panics
2350 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2351 #[inline]
2352 pub fn get_non_send_resource_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {
2353 // SAFETY:
2354 // - `as_unsafe_world_cell` gives permission to access the entire world mutably
2355 // - `&mut self` ensures that there are no borrows of world data
2356 unsafe { self.as_unsafe_world_cell().get_non_send_resource_mut() }
2357 }
2358
2359 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2360 /// adds the `Bundle` of components to each `Entity`.
2361 /// This is faster than doing equivalent operations one-by-one.
2362 ///
2363 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2364 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2365 ///
2366 /// This will overwrite any previous values of components shared by the `Bundle`.
2367 /// See [`World::insert_batch_if_new`] to keep the old values instead.
2368 ///
2369 /// # Panics
2370 ///
2371 /// This function will panic if any of the associated entities do not exist.
2372 ///
2373 /// For the fallible version, see [`World::try_insert_batch`].
2374 #[track_caller]
2375 pub fn insert_batch<I, B>(&mut self, batch: I)
2376 where
2377 I: IntoIterator,
2378 I::IntoIter: Iterator<Item = (Entity, B)>,
2379 B: Bundle<Effect: NoBundleEffect>,
2380 {
2381 self.insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller());
2382 }
2383
2384 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2385 /// adds the `Bundle` of components to each `Entity` without overwriting.
2386 /// This is faster than doing equivalent operations one-by-one.
2387 ///
2388 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2389 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2390 ///
2391 /// This is the same as [`World::insert_batch`], but in case of duplicate
2392 /// components it will leave the old values instead of replacing them with new ones.
2393 ///
2394 /// # Panics
2395 ///
2396 /// This function will panic if any of the associated entities do not exist.
2397 ///
2398 /// For the fallible version, see [`World::try_insert_batch_if_new`].
2399 #[track_caller]
2400 pub fn insert_batch_if_new<I, B>(&mut self, batch: I)
2401 where
2402 I: IntoIterator,
2403 I::IntoIter: Iterator<Item = (Entity, B)>,
2404 B: Bundle<Effect: NoBundleEffect>,
2405 {
2406 self.insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller());
2407 }
2408
2409 /// Split into a new function so we can differentiate the calling location.
2410 ///
2411 /// This can be called by:
2412 /// - [`World::insert_batch`]
2413 /// - [`World::insert_batch_if_new`]
2414 #[inline]
2415 pub(crate) fn insert_batch_with_caller<I, B>(
2416 &mut self,
2417 batch: I,
2418 insert_mode: InsertMode,
2419 caller: MaybeLocation,
2420 ) where
2421 I: IntoIterator,
2422 I::IntoIter: Iterator<Item = (Entity, B)>,
2423 B: Bundle<Effect: NoBundleEffect>,
2424 {
2425 struct InserterArchetypeCache<'w> {
2426 inserter: BundleInserter<'w>,
2427 archetype_id: ArchetypeId,
2428 }
2429
2430 let change_tick = self.change_tick();
2431 let bundle_id = self.register_bundle_info::<B>();
2432
2433 let mut batch_iter = batch.into_iter();
2434
2435 if let Some((first_entity, first_bundle)) = batch_iter.next() {
2436 match self.entities().get_spawned(first_entity) {
2437 Err(err) => {
2438 panic!("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>());
2439 }
2440 Ok(first_location) => {
2441 let mut cache = InserterArchetypeCache {
2442 // SAFETY: we initialized this bundle_id in `register_info`
2443 inserter: unsafe {
2444 BundleInserter::new_with_id(
2445 self,
2446 first_location.archetype_id,
2447 bundle_id,
2448 change_tick,
2449 )
2450 },
2451 archetype_id: first_location.archetype_id,
2452 };
2453 move_as_ptr!(first_bundle);
2454 // SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter
2455 unsafe {
2456 cache.inserter.insert(
2457 first_entity,
2458 first_location,
2459 first_bundle,
2460 insert_mode,
2461 caller,
2462 RelationshipHookMode::Run,
2463 )
2464 };
2465
2466 for (entity, bundle) in batch_iter {
2467 match cache.inserter.entities().get_spawned(entity) {
2468 Ok(location) => {
2469 if location.archetype_id != cache.archetype_id {
2470 cache = InserterArchetypeCache {
2471 // SAFETY: we initialized this bundle_id in `register_info`
2472 inserter: unsafe {
2473 BundleInserter::new_with_id(
2474 self,
2475 location.archetype_id,
2476 bundle_id,
2477 change_tick,
2478 )
2479 },
2480 archetype_id: location.archetype_id,
2481 }
2482 }
2483 move_as_ptr!(bundle);
2484 // SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter
2485 unsafe {
2486 cache.inserter.insert(
2487 entity,
2488 location,
2489 bundle,
2490 insert_mode,
2491 caller,
2492 RelationshipHookMode::Run,
2493 )
2494 };
2495 }
2496 Err(err) => {
2497 panic!("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>());
2498 }
2499 }
2500 }
2501 }
2502 }
2503 }
2504 }
2505
2506 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2507 /// adds the `Bundle` of components to each `Entity`.
2508 /// This is faster than doing equivalent operations one-by-one.
2509 ///
2510 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2511 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2512 ///
2513 /// This will overwrite any previous values of components shared by the `Bundle`.
2514 /// See [`World::try_insert_batch_if_new`] to keep the old values instead.
2515 ///
2516 /// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.
2517 ///
2518 /// For the panicking version, see [`World::insert_batch`].
2519 #[track_caller]
2520 pub fn try_insert_batch<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>
2521 where
2522 I: IntoIterator,
2523 I::IntoIter: Iterator<Item = (Entity, B)>,
2524 B: Bundle<Effect: NoBundleEffect>,
2525 {
2526 self.try_insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller())
2527 }
2528 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2529 /// adds the `Bundle` of components to each `Entity` without overwriting.
2530 /// This is faster than doing equivalent operations one-by-one.
2531 ///
2532 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2533 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2534 ///
2535 /// This is the same as [`World::try_insert_batch`], but in case of duplicate
2536 /// components it will leave the old values instead of replacing them with new ones.
2537 ///
2538 /// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.
2539 ///
2540 /// For the panicking version, see [`World::insert_batch_if_new`].
2541 #[track_caller]
2542 pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>
2543 where
2544 I: IntoIterator,
2545 I::IntoIter: Iterator<Item = (Entity, B)>,
2546 B: Bundle<Effect: NoBundleEffect>,
2547 {
2548 self.try_insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller())
2549 }
2550
2551 /// Split into a new function so we can differentiate the calling location.
2552 ///
2553 /// This can be called by:
2554 /// - [`World::try_insert_batch`]
2555 /// - [`World::try_insert_batch_if_new`]
2556 /// - [`Commands::insert_batch`]
2557 /// - [`Commands::insert_batch_if_new`]
2558 /// - [`Commands::try_insert_batch`]
2559 /// - [`Commands::try_insert_batch_if_new`]
2560 #[inline]
2561 pub(crate) fn try_insert_batch_with_caller<I, B>(
2562 &mut self,
2563 batch: I,
2564 insert_mode: InsertMode,
2565 caller: MaybeLocation,
2566 ) -> Result<(), TryInsertBatchError>
2567 where
2568 I: IntoIterator,
2569 I::IntoIter: Iterator<Item = (Entity, B)>,
2570 B: Bundle<Effect: NoBundleEffect>,
2571 {
2572 struct InserterArchetypeCache<'w> {
2573 inserter: BundleInserter<'w>,
2574 archetype_id: ArchetypeId,
2575 }
2576
2577 let change_tick = self.change_tick();
2578 let bundle_id = self.register_bundle_info::<B>();
2579
2580 let mut invalid_entities = Vec::<Entity>::new();
2581 let mut batch_iter = batch.into_iter();
2582
2583 // We need to find the first valid entity so we can initialize the bundle inserter.
2584 // This differs from `insert_batch_with_caller` because that method can just panic
2585 // if the first entity is invalid, whereas this method needs to keep going.
2586 let cache = loop {
2587 if let Some((first_entity, first_bundle)) = batch_iter.next() {
2588 if let Ok(first_location) = self.entities().get_spawned(first_entity) {
2589 let mut cache = InserterArchetypeCache {
2590 // SAFETY: we initialized this bundle_id in `register_bundle_info`
2591 inserter: unsafe {
2592 BundleInserter::new_with_id(
2593 self,
2594 first_location.archetype_id,
2595 bundle_id,
2596 change_tick,
2597 )
2598 },
2599 archetype_id: first_location.archetype_id,
2600 };
2601
2602 move_as_ptr!(first_bundle);
2603 // SAFETY:
2604 // - `entity` is valid, `location` matches entity, bundle matches inserter
2605 // - `apply_effect` is never called on this bundle.
2606 // - `first_bundle` is not be accessed or dropped after this.
2607 unsafe {
2608 cache.inserter.insert(
2609 first_entity,
2610 first_location,
2611 first_bundle,
2612 insert_mode,
2613 caller,
2614 RelationshipHookMode::Run,
2615 )
2616 };
2617 break Some(cache);
2618 }
2619 invalid_entities.push(first_entity);
2620 } else {
2621 // We reached the end of the entities the caller provided and none were valid.
2622 break None;
2623 }
2624 };
2625
2626 if let Some(mut cache) = cache {
2627 for (entity, bundle) in batch_iter {
2628 if let Ok(location) = cache.inserter.entities().get_spawned(entity) {
2629 if location.archetype_id != cache.archetype_id {
2630 cache = InserterArchetypeCache {
2631 // SAFETY: we initialized this bundle_id in `register_info`
2632 inserter: unsafe {
2633 BundleInserter::new_with_id(
2634 self,
2635 location.archetype_id,
2636 bundle_id,
2637 change_tick,
2638 )
2639 },
2640 archetype_id: location.archetype_id,
2641 }
2642 }
2643
2644 move_as_ptr!(bundle);
2645 // SAFETY:
2646 // - `entity` is valid, `location` matches entity, bundle matches inserter
2647 // - `apply_effect` is never called on this bundle.
2648 // - `bundle` is not be accessed or dropped after this.
2649 unsafe {
2650 cache.inserter.insert(
2651 entity,
2652 location,
2653 bundle,
2654 insert_mode,
2655 caller,
2656 RelationshipHookMode::Run,
2657 )
2658 };
2659 } else {
2660 invalid_entities.push(entity);
2661 }
2662 }
2663 }
2664
2665 if invalid_entities.is_empty() {
2666 Ok(())
2667 } else {
2668 Err(TryInsertBatchError {
2669 bundle_type: DebugName::type_name::<B>(),
2670 entities: invalid_entities,
2671 })
2672 }
2673 }
2674
2675 /// Temporarily removes the requested resource from this [`World`], runs custom user code,
2676 /// then re-adds the resource before returning.
2677 ///
2678 /// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].
2679 /// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).
2680 ///
2681 /// # Panics
2682 ///
2683 /// Panics if the resource does not exist.
2684 /// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.
2685 ///
2686 /// # Example
2687 /// ```
2688 /// use bevy_ecs::prelude::*;
2689 /// #[derive(Resource)]
2690 /// struct A(u32);
2691 /// #[derive(Component)]
2692 /// struct B(u32);
2693 /// let mut world = World::new();
2694 /// world.insert_resource(A(1));
2695 /// let entity = world.spawn(B(1)).id();
2696 ///
2697 /// world.resource_scope(|world, mut a: Mut<A>| {
2698 /// let b = world.get_mut::<B>(entity).unwrap();
2699 /// a.0 += b.0;
2700 /// });
2701 /// assert_eq!(world.get_resource::<A>().unwrap().0, 2);
2702 /// ```
2703 #[track_caller]
2704 pub fn resource_scope<R: Resource, U>(&mut self, f: impl FnOnce(&mut World, Mut<R>) -> U) -> U {
2705 self.try_resource_scope(f)
2706 .unwrap_or_else(|| panic!("resource does not exist: {}", DebugName::type_name::<R>()))
2707 }
2708
2709 /// Temporarily removes the requested resource from this [`World`] if it exists, runs custom user code,
2710 /// then re-adds the resource before returning. Returns `None` if the resource does not exist in this [`World`].
2711 ///
2712 /// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].
2713 /// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).
2714 ///
2715 /// See also [`resource_scope`](Self::resource_scope).
2716 pub fn try_resource_scope<R: Resource, U>(
2717 &mut self,
2718 f: impl FnOnce(&mut World, Mut<R>) -> U,
2719 ) -> Option<U> {
2720 let last_change_tick = self.last_change_tick();
2721 let change_tick = self.change_tick();
2722
2723 let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;
2724 let (ptr, ticks, caller) = self.storages.resources.get_mut(component_id)?.remove()?;
2725
2726 // Read the value onto the stack to avoid potential mut aliasing.
2727 // SAFETY: `ptr` was obtained from the TypeId of `R`.
2728 let value = unsafe { ptr.read::<R>() };
2729
2730 // type used to manage reinserting the resource at the end of the scope. use of a drop impl means that
2731 // the resource is inserted even if the user-provided closure unwinds.
2732 // this facilitates localized panic recovery and makes app shutdown in response to a panic more graceful
2733 // by avoiding knock-on errors.
2734 struct ReinsertGuard<'a, R> {
2735 world: &'a mut World,
2736 component_id: ComponentId,
2737 value: ManuallyDrop<R>,
2738 ticks: ComponentTicks,
2739 caller: MaybeLocation,
2740 was_successful: &'a mut bool,
2741 }
2742 impl<R> Drop for ReinsertGuard<'_, R> {
2743 fn drop(&mut self) {
2744 // take ownership of the value first so it'll get dropped if we return early
2745 // SAFETY: drop semantics ensure that `self.value` will never be accessed again after this call
2746 let value = unsafe { ManuallyDrop::take(&mut self.value) };
2747
2748 let Some(resource_data) = self.world.storages.resources.get_mut(self.component_id)
2749 else {
2750 return;
2751 };
2752
2753 // in debug mode, raise a panic if user code re-inserted a resource of this type within the scope.
2754 // resource insertion usually indicates a logic error in user code, which is useful to catch at dev time,
2755 // however it does not inherently lead to corrupted state, so we avoid introducing an unnecessary crash
2756 // for production builds.
2757 if resource_data.is_present() {
2758 #[cfg(debug_assertions)]
2759 {
2760 // if we're already panicking, log an error instead of panicking, as double-panics result in an abort
2761 #[cfg(feature = "std")]
2762 if std::thread::panicking() {
2763 log::error!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\
2764 In release builds, the value inserted will be overwritten at the end of the scope.",
2765 DebugName::type_name::<R>());
2766 // return early to maintain consistent behavior with non-panicking calls in debug builds
2767 return;
2768 }
2769
2770 panic!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\
2771 In release builds, the value inserted will be overwritten at the end of the scope.",
2772 DebugName::type_name::<R>());
2773 }
2774 #[cfg(not(debug_assertions))]
2775 {
2776 #[cold]
2777 #[inline(never)]
2778 fn warn_reinsert(resource_name: &str) {
2779 warn!(
2780 "Resource `{resource_name}` was inserted during a call to World::resource_scope: the inserted value will be overwritten.",
2781 );
2782 }
2783
2784 warn_reinsert(&DebugName::type_name::<R>());
2785 }
2786 }
2787
2788 OwningPtr::make(value, |ptr| {
2789 // SAFETY: ptr is of type `R`, which corresponds to the same component ID used to retrieve the resource data.
2790 unsafe {
2791 resource_data.insert_with_ticks(ptr, self.ticks, self.caller);
2792 }
2793 });
2794
2795 *self.was_successful = true;
2796 }
2797 }
2798
2799 // used to track whether the guard's drop impl was able to successfully reinsert the value into the world.
2800 // an alternative way to track success would be to have a separate `guard.apply()` method used
2801 // in the happy path -- however this would require two code paths for panicking vs regular control flow
2802 // which would have suboptimal codegen. `resource_scope` is a widely used primitive, both throughout the
2803 // engine and in user code, so this measure is likely worth it.
2804 let mut was_successful = false;
2805 let result = {
2806 let mut guard = ReinsertGuard {
2807 world: self,
2808 component_id,
2809 value: ManuallyDrop::new(value),
2810 ticks,
2811 caller,
2812 was_successful: &mut was_successful,
2813 };
2814
2815 let value_mut = Mut {
2816 value: &mut *guard.value,
2817 ticks: ComponentTicksMut {
2818 added: &mut guard.ticks.added,
2819 changed: &mut guard.ticks.changed,
2820 changed_by: guard.caller.as_mut(),
2821 last_run: last_change_tick,
2822 this_run: change_tick,
2823 },
2824 };
2825
2826 f(guard.world, value_mut)
2827
2828 // guard's drop impl runs here
2829 };
2830
2831 was_successful.then_some(result)
2832 }
2833
2834 /// Writes a [`Message`].
2835 /// This method returns the [`MessageId`] of the written `message`,
2836 /// or [`None`] if the `message` could not be written.
2837 #[inline]
2838 pub fn write_message<M: Message>(&mut self, message: M) -> Option<MessageId<M>> {
2839 self.write_message_batch(core::iter::once(message))?.next()
2840 }
2841
2842 /// Writes the default value of the [`Message`] of type `M`.
2843 /// This method returns the [`MessageId`] of the written message,
2844 /// or [`None`] if the `event` could not be written.
2845 #[inline]
2846 pub fn write_message_default<M: Message + Default>(&mut self) -> Option<MessageId<M>> {
2847 self.write_message(M::default())
2848 }
2849
2850 /// Writes a batch of [`Message`]s from an iterator.
2851 /// This method returns the [IDs](`MessageId`) of the written `messages`,
2852 /// or [`None`] if the `events` could not be written.
2853 #[inline]
2854 pub fn write_message_batch<M: Message>(
2855 &mut self,
2856 messages: impl IntoIterator<Item = M>,
2857 ) -> Option<WriteBatchIds<M>> {
2858 let Some(mut events_resource) = self.get_resource_mut::<Messages<M>>() else {
2859 log::error!(
2860 "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 ",
2861 DebugName::type_name::<M>()
2862 );
2863 return None;
2864 };
2865 Some(events_resource.write_batch(messages))
2866 }
2867
2868 /// Inserts a new resource with the given `value`. Will replace the value if it already existed.
2869 ///
2870 /// **You should prefer to use the typed API [`World::insert_resource`] where possible and only
2871 /// use this in cases where the actual types are not known at compile time.**
2872 ///
2873 /// # Safety
2874 /// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.
2875 #[inline]
2876 #[track_caller]
2877 pub unsafe fn insert_resource_by_id(
2878 &mut self,
2879 component_id: ComponentId,
2880 value: OwningPtr<'_>,
2881 caller: MaybeLocation,
2882 ) {
2883 let change_tick = self.change_tick();
2884
2885 let resource = self.initialize_resource_internal(component_id);
2886 // SAFETY: `value` is valid for `component_id`, ensured by caller
2887 unsafe {
2888 resource.insert(value, change_tick, caller);
2889 }
2890 }
2891
2892 /// Inserts a new `!Send` resource with the given `value`. Will replace the value if it already
2893 /// existed.
2894 ///
2895 /// **You should prefer to use the typed API [`World::insert_non_send_resource`] where possible and only
2896 /// use this in cases where the actual types are not known at compile time.**
2897 ///
2898 /// # Panics
2899 /// If a value is already present, this function will panic if not called from the same
2900 /// thread that the original value was inserted from.
2901 ///
2902 /// # Safety
2903 /// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.
2904 #[inline]
2905 #[track_caller]
2906 pub unsafe fn insert_non_send_by_id(
2907 &mut self,
2908 component_id: ComponentId,
2909 value: OwningPtr<'_>,
2910 caller: MaybeLocation,
2911 ) {
2912 let change_tick = self.change_tick();
2913
2914 let resource = self.initialize_non_send_internal(component_id);
2915 // SAFETY: `value` is valid for `component_id`, ensured by caller
2916 unsafe {
2917 resource.insert(value, change_tick, caller);
2918 }
2919 }
2920
2921 /// # Panics
2922 /// Panics if `component_id` is not registered as a `Send` component type in this `World`
2923 #[inline]
2924 pub(crate) fn initialize_resource_internal(
2925 &mut self,
2926 component_id: ComponentId,
2927 ) -> &mut ResourceData<true> {
2928 self.flush_components();
2929 self.storages
2930 .resources
2931 .initialize_with(component_id, &self.components)
2932 }
2933
2934 /// # Panics
2935 /// Panics if `component_id` is not registered in this world
2936 #[inline]
2937 pub(crate) fn initialize_non_send_internal(
2938 &mut self,
2939 component_id: ComponentId,
2940 ) -> &mut ResourceData<false> {
2941 self.flush_components();
2942 self.storages
2943 .non_send_resources
2944 .initialize_with(component_id, &self.components)
2945 }
2946
2947 /// Applies any commands in the world's internal [`CommandQueue`].
2948 /// This does not apply commands from any systems, only those stored in the world.
2949 ///
2950 /// # Panics
2951 /// This will panic if any of the queued commands are [`spawn`](Commands::spawn).
2952 /// If this is possible, you should instead use [`flush`](Self::flush).
2953 pub(crate) fn flush_commands(&mut self) {
2954 // SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`
2955 if !unsafe { self.command_queue.is_empty() } {
2956 // SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`
2957 unsafe {
2958 self.command_queue
2959 .clone()
2960 .apply_or_drop_queued(Some(self.into()));
2961 };
2962 }
2963 }
2964
2965 /// Applies any queued component registration.
2966 /// For spawning vanilla rust component types and resources, this is not strictly necessary.
2967 /// However, flushing components can make information available more quickly, and can have performance benefits.
2968 /// Additionally, for components and resources registered dynamically through a raw descriptor or similar,
2969 /// this is the only way to complete their registration.
2970 pub(crate) fn flush_components(&mut self) {
2971 self.components_registrator().apply_queued_registrations();
2972 }
2973
2974 /// Flushes queued entities and commands.
2975 ///
2976 /// Queued entities will be spawned, and then commands will be applied.
2977 #[inline]
2978 #[track_caller]
2979 pub fn flush(&mut self) {
2980 self.flush_components();
2981 self.flush_commands();
2982 }
2983
2984 /// Increments the world's current change tick and returns the old value.
2985 ///
2986 /// If you need to call this method, but do not have `&mut` access to the world,
2987 /// consider using [`as_unsafe_world_cell_readonly`](Self::as_unsafe_world_cell_readonly)
2988 /// to obtain an [`UnsafeWorldCell`] and calling [`increment_change_tick`](UnsafeWorldCell::increment_change_tick) on that.
2989 /// Note that this *can* be done in safe code, despite the name of the type.
2990 #[inline]
2991 pub fn increment_change_tick(&mut self) -> Tick {
2992 let change_tick = self.change_tick.get_mut();
2993 let prev_tick = *change_tick;
2994 *change_tick = change_tick.wrapping_add(1);
2995 Tick::new(prev_tick)
2996 }
2997
2998 /// Reads the current change tick of this world.
2999 ///
3000 /// If you have exclusive (`&mut`) access to the world, consider using [`change_tick()`](Self::change_tick),
3001 /// which is more efficient since it does not require atomic synchronization.
3002 #[inline]
3003 pub fn read_change_tick(&self) -> Tick {
3004 let tick = self.change_tick.load(Ordering::Acquire);
3005 Tick::new(tick)
3006 }
3007
3008 /// Reads the current change tick of this world.
3009 ///
3010 /// This does the same thing as [`read_change_tick()`](Self::read_change_tick), only this method
3011 /// is more efficient since it does not require atomic synchronization.
3012 #[inline]
3013 pub fn change_tick(&mut self) -> Tick {
3014 let tick = *self.change_tick.get_mut();
3015 Tick::new(tick)
3016 }
3017
3018 /// When called from within an exclusive system (a [`System`] that takes `&mut World` as its first
3019 /// parameter), this method returns the [`Tick`] indicating the last time the exclusive system was run.
3020 ///
3021 /// Otherwise, this returns the `Tick` indicating the last time that [`World::clear_trackers`] was called.
3022 ///
3023 /// [`System`]: crate::system::System
3024 #[inline]
3025 pub fn last_change_tick(&self) -> Tick {
3026 self.last_change_tick
3027 }
3028
3029 /// Returns the id of the last ECS event that was fired.
3030 /// Used internally to ensure observers don't trigger multiple times for the same event.
3031 #[inline]
3032 pub(crate) fn last_trigger_id(&self) -> u32 {
3033 self.last_trigger_id
3034 }
3035
3036 /// Sets [`World::last_change_tick()`] to the specified value during a scope.
3037 /// When the scope terminates, it will return to its old value.
3038 ///
3039 /// This is useful if you need a region of code to be able to react to earlier changes made in the same system.
3040 ///
3041 /// # Examples
3042 ///
3043 /// ```
3044 /// # use bevy_ecs::prelude::*;
3045 /// // This function runs an update loop repeatedly, allowing each iteration of the loop
3046 /// // to react to changes made in the previous loop iteration.
3047 /// fn update_loop(
3048 /// world: &mut World,
3049 /// mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,
3050 /// ) {
3051 /// let mut last_change_tick = world.last_change_tick();
3052 ///
3053 /// // Repeatedly run the update function until it requests a break.
3054 /// loop {
3055 /// let control_flow = world.last_change_tick_scope(last_change_tick, |world| {
3056 /// // Increment the change tick so we can detect changes from the previous update.
3057 /// last_change_tick = world.change_tick();
3058 /// world.increment_change_tick();
3059 ///
3060 /// // Update once.
3061 /// update_fn(world)
3062 /// });
3063 ///
3064 /// // End the loop when the closure returns `ControlFlow::Break`.
3065 /// if control_flow.is_break() {
3066 /// break;
3067 /// }
3068 /// }
3069 /// }
3070 /// #
3071 /// # #[derive(Resource)] struct Count(u32);
3072 /// # let mut world = World::new();
3073 /// # world.insert_resource(Count(0));
3074 /// # let saved_last_tick = world.last_change_tick();
3075 /// # let mut num_updates = 0;
3076 /// # update_loop(&mut world, |world| {
3077 /// # let mut c = world.resource_mut::<Count>();
3078 /// # match c.0 {
3079 /// # 0 => {
3080 /// # assert_eq!(num_updates, 0);
3081 /// # assert!(c.is_added());
3082 /// # c.0 = 1;
3083 /// # }
3084 /// # 1 => {
3085 /// # assert_eq!(num_updates, 1);
3086 /// # assert!(!c.is_added());
3087 /// # assert!(c.is_changed());
3088 /// # c.0 = 2;
3089 /// # }
3090 /// # 2 if c.is_changed() => {
3091 /// # assert_eq!(num_updates, 2);
3092 /// # assert!(!c.is_added());
3093 /// # }
3094 /// # 2 => {
3095 /// # assert_eq!(num_updates, 3);
3096 /// # assert!(!c.is_changed());
3097 /// # world.remove_resource::<Count>();
3098 /// # world.insert_resource(Count(3));
3099 /// # }
3100 /// # 3 if c.is_changed() => {
3101 /// # assert_eq!(num_updates, 4);
3102 /// # assert!(c.is_added());
3103 /// # }
3104 /// # 3 => {
3105 /// # assert_eq!(num_updates, 5);
3106 /// # assert!(!c.is_added());
3107 /// # c.0 = 4;
3108 /// # return std::ops::ControlFlow::Break(());
3109 /// # }
3110 /// # _ => unreachable!(),
3111 /// # }
3112 /// # num_updates += 1;
3113 /// # std::ops::ControlFlow::Continue(())
3114 /// # });
3115 /// # assert_eq!(num_updates, 5);
3116 /// # assert_eq!(world.resource::<Count>().0, 4);
3117 /// # assert_eq!(world.last_change_tick(), saved_last_tick);
3118 /// ```
3119 pub fn last_change_tick_scope<T>(
3120 &mut self,
3121 last_change_tick: Tick,
3122 f: impl FnOnce(&mut World) -> T,
3123 ) -> T {
3124 struct LastTickGuard<'a> {
3125 world: &'a mut World,
3126 last_tick: Tick,
3127 }
3128
3129 // By setting the change tick in the drop impl, we ensure that
3130 // the change tick gets reset even if a panic occurs during the scope.
3131 impl Drop for LastTickGuard<'_> {
3132 fn drop(&mut self) {
3133 self.world.last_change_tick = self.last_tick;
3134 }
3135 }
3136
3137 let guard = LastTickGuard {
3138 last_tick: self.last_change_tick,
3139 world: self,
3140 };
3141
3142 guard.world.last_change_tick = last_change_tick;
3143
3144 f(guard.world)
3145 }
3146
3147 /// Iterates all component change ticks and clamps any older than [`MAX_CHANGE_AGE`](crate::change_detection::MAX_CHANGE_AGE).
3148 /// This also triggers [`CheckChangeTicks`] observers and returns the same event here.
3149 ///
3150 /// Calling this method prevents [`Tick`]s overflowing and thus prevents false positives when comparing them.
3151 ///
3152 /// **Note:** Does nothing and returns `None` if the [`World`] counter has not been incremented at least [`CHECK_TICK_THRESHOLD`]
3153 /// times since the previous pass.
3154 // TODO: benchmark and optimize
3155 pub fn check_change_ticks(&mut self) -> Option<CheckChangeTicks> {
3156 let change_tick = self.change_tick();
3157 if change_tick.relative_to(self.last_check_tick).get() < CHECK_TICK_THRESHOLD {
3158 return None;
3159 }
3160
3161 let check = CheckChangeTicks(change_tick);
3162
3163 let Storages {
3164 ref mut tables,
3165 ref mut sparse_sets,
3166 ref mut resources,
3167 ref mut non_send_resources,
3168 } = self.storages;
3169
3170 #[cfg(feature = "trace")]
3171 let _span = tracing::info_span!("check component ticks").entered();
3172 tables.check_change_ticks(check);
3173 sparse_sets.check_change_ticks(check);
3174 resources.check_change_ticks(check);
3175 non_send_resources.check_change_ticks(check);
3176 self.entities.check_change_ticks(check);
3177
3178 if let Some(mut schedules) = self.get_resource_mut::<Schedules>() {
3179 schedules.check_change_ticks(check);
3180 }
3181
3182 self.trigger(check);
3183 self.flush();
3184
3185 self.last_check_tick = change_tick;
3186
3187 Some(check)
3188 }
3189
3190 /// Runs both [`clear_entities`](Self::clear_entities) and [`clear_resources`](Self::clear_resources),
3191 /// invalidating all [`Entity`] and resource fetches such as [`Res`](crate::system::Res), [`ResMut`](crate::system::ResMut)
3192 pub fn clear_all(&mut self) {
3193 self.clear_entities();
3194 self.clear_resources();
3195 }
3196
3197 /// Despawns all entities in this [`World`].
3198 pub fn clear_entities(&mut self) {
3199 self.storages.tables.clear();
3200 self.storages.sparse_sets.clear_entities();
3201 self.archetypes.clear_entities();
3202 self.entities.clear();
3203 self.allocator.restart();
3204 }
3205
3206 /// Clears all resources in this [`World`].
3207 ///
3208 /// **Note:** Any resource fetch to this [`World`] will fail unless they are re-initialized,
3209 /// including engine-internal resources that are only initialized on app/world construction.
3210 ///
3211 /// This can easily cause systems expecting certain resources to immediately start panicking.
3212 /// Use with caution.
3213 pub fn clear_resources(&mut self) {
3214 self.storages.resources.clear();
3215 self.storages.non_send_resources.clear();
3216 }
3217
3218 /// Registers all of the components in the given [`Bundle`] and returns both the component
3219 /// ids and the bundle id.
3220 ///
3221 /// This is largely equivalent to calling [`register_component`](Self::register_component) on each
3222 /// component in the bundle.
3223 #[inline]
3224 pub fn register_bundle<B: Bundle>(&mut self) -> &BundleInfo {
3225 let id = self.register_bundle_info::<B>();
3226
3227 // SAFETY: We just initialized the bundle so its id should definitely be valid.
3228 unsafe { self.bundles.get(id).debug_checked_unwrap() }
3229 }
3230
3231 pub(crate) fn register_bundle_info<B: Bundle>(&mut self) -> BundleId {
3232 // SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.
3233 let mut registrator =
3234 unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };
3235
3236 // SAFETY: `registrator`, `self.storages` and `self.bundles` all come from this world.
3237 unsafe {
3238 self.bundles
3239 .register_info::<B>(&mut registrator, &mut self.storages)
3240 }
3241 }
3242
3243 pub(crate) fn register_contributed_bundle_info<B: Bundle>(&mut self) -> BundleId {
3244 // SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.
3245 let mut registrator =
3246 unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };
3247
3248 // SAFETY: `registrator`, `self.bundles` and `self.storages` are all from this world.
3249 unsafe {
3250 self.bundles
3251 .register_contributed_bundle_info::<B>(&mut registrator, &mut self.storages)
3252 }
3253 }
3254
3255 /// Registers the given [`ComponentId`]s as a dynamic bundle and returns both the required component ids and the bundle id.
3256 ///
3257 /// Note that the components need to be registered first, this function only creates a bundle combining them. Components
3258 /// can be registered with [`World::register_component`]/[`_with_descriptor`](World::register_component_with_descriptor).
3259 ///
3260 /// **You should prefer to use the typed API [`World::register_bundle`] where possible and only use this in cases where
3261 /// not all of the actual types are known at compile time.**
3262 ///
3263 /// # Panics
3264 /// This function will panic if any of the provided component ids do not belong to a component known to this [`World`].
3265 #[inline]
3266 pub fn register_dynamic_bundle(&mut self, component_ids: &[ComponentId]) -> &BundleInfo {
3267 let id =
3268 self.bundles
3269 .init_dynamic_info(&mut self.storages, &self.components, component_ids);
3270 // SAFETY: We just initialized the bundle so its id should definitely be valid.
3271 unsafe { self.bundles.get(id).debug_checked_unwrap() }
3272 }
3273
3274 /// Convenience method for accessing the world's default error handler,
3275 /// which can be overwritten with [`DefaultErrorHandler`].
3276 #[inline]
3277 pub fn default_error_handler(&self) -> ErrorHandler {
3278 self.get_resource::<DefaultErrorHandler>()
3279 .copied()
3280 .unwrap_or_default()
3281 .0
3282 }
3283}
3284
3285impl World {
3286 /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
3287 /// The returned pointer must not be used to modify the resource, and must not be
3288 /// dereferenced after the immutable borrow of the [`World`] ends.
3289 ///
3290 /// **You should prefer to use the typed API [`World::get_resource`] where possible and only
3291 /// use this in cases where the actual types are not known at compile time.**
3292 #[inline]
3293 pub fn get_resource_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
3294 // SAFETY:
3295 // - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably
3296 // - `&self` ensures there are no mutable borrows on world data
3297 unsafe {
3298 self.as_unsafe_world_cell_readonly()
3299 .get_resource_by_id(component_id)
3300 }
3301 }
3302
3303 /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
3304 /// The returned pointer may be used to modify the resource, as long as the mutable borrow
3305 /// of the [`World`] is still valid.
3306 ///
3307 /// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only
3308 /// use this in cases where the actual types are not known at compile time.**
3309 #[inline]
3310 pub fn get_resource_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
3311 // SAFETY:
3312 // - `&mut self` ensures that all accessed data is unaliased
3313 // - `as_unsafe_world_cell` provides mutable permission to the whole world
3314 unsafe {
3315 self.as_unsafe_world_cell()
3316 .get_resource_mut_by_id(component_id)
3317 }
3318 }
3319
3320 /// Iterates over all resources in the world.
3321 ///
3322 /// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading the contents
3323 /// of each resource will require the use of unsafe code.
3324 ///
3325 /// # Examples
3326 ///
3327 /// ## Printing the size of all resources
3328 ///
3329 /// ```
3330 /// # use bevy_ecs::prelude::*;
3331 /// # #[derive(Resource)]
3332 /// # struct A(u32);
3333 /// # #[derive(Resource)]
3334 /// # struct B(u32);
3335 /// #
3336 /// # let mut world = World::new();
3337 /// # world.remove_resource::<bevy_ecs::entity_disabling::DefaultQueryFilters>();
3338 /// # world.insert_resource(A(1));
3339 /// # world.insert_resource(B(2));
3340 /// let mut total = 0;
3341 /// for (info, _) in world.iter_resources() {
3342 /// println!("Resource: {}", info.name());
3343 /// println!("Size: {} bytes", info.layout().size());
3344 /// total += info.layout().size();
3345 /// }
3346 /// println!("Total size: {} bytes", total);
3347 /// # assert_eq!(total, size_of::<A>() + size_of::<B>());
3348 /// ```
3349 ///
3350 /// ## Dynamically running closures for resources matching specific `TypeId`s
3351 ///
3352 /// ```
3353 /// # use bevy_ecs::prelude::*;
3354 /// # use std::collections::HashMap;
3355 /// # use std::any::TypeId;
3356 /// # use bevy_ptr::Ptr;
3357 /// # #[derive(Resource)]
3358 /// # struct A(u32);
3359 /// # #[derive(Resource)]
3360 /// # struct B(u32);
3361 /// #
3362 /// # let mut world = World::new();
3363 /// # world.insert_resource(A(1));
3364 /// # world.insert_resource(B(2));
3365 /// #
3366 /// // In this example, `A` and `B` are resources. We deliberately do not use the
3367 /// // `bevy_reflect` crate here to showcase the low-level [`Ptr`] usage. You should
3368 /// // probably use something like `ReflectFromPtr` in a real-world scenario.
3369 ///
3370 /// // Create the hash map that will store the closures for each resource type
3371 /// let mut closures: HashMap<TypeId, Box<dyn Fn(&Ptr<'_>)>> = HashMap::default();
3372 ///
3373 /// // Add closure for `A`
3374 /// closures.insert(TypeId::of::<A>(), Box::new(|ptr| {
3375 /// // SAFETY: We assert ptr is the same type of A with TypeId of A
3376 /// let a = unsafe { &ptr.deref::<A>() };
3377 /// # assert_eq!(a.0, 1);
3378 /// // ... do something with `a` here
3379 /// }));
3380 ///
3381 /// // Add closure for `B`
3382 /// closures.insert(TypeId::of::<B>(), Box::new(|ptr| {
3383 /// // SAFETY: We assert ptr is the same type of B with TypeId of B
3384 /// let b = unsafe { &ptr.deref::<B>() };
3385 /// # assert_eq!(b.0, 2);
3386 /// // ... do something with `b` here
3387 /// }));
3388 ///
3389 /// // Iterate all resources, in order to run the closures for each matching resource type
3390 /// for (info, ptr) in world.iter_resources() {
3391 /// let Some(type_id) = info.type_id() else {
3392 /// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources
3393 /// // dynamically inserted via a scripting language) in which case we can't match them.
3394 /// continue;
3395 /// };
3396 ///
3397 /// let Some(closure) = closures.get(&type_id) else {
3398 /// // No closure for this resource type, skip it.
3399 /// continue;
3400 /// };
3401 ///
3402 /// // Run the closure for the resource
3403 /// closure(&ptr);
3404 /// }
3405 /// ```
3406 #[inline]
3407 pub fn iter_resources(&self) -> impl Iterator<Item = (&ComponentInfo, Ptr<'_>)> {
3408 self.storages
3409 .resources
3410 .iter()
3411 .filter_map(|(component_id, data)| {
3412 // SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.
3413 let component_info = unsafe {
3414 self.components
3415 .get_info(component_id)
3416 .debug_checked_unwrap()
3417 };
3418 Some((component_info, data.get_data()?))
3419 })
3420 }
3421
3422 /// Mutably iterates over all resources in the world.
3423 ///
3424 /// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading from or writing
3425 /// to the contents of each resource will require the use of unsafe code.
3426 ///
3427 /// # Example
3428 ///
3429 /// ```
3430 /// # use bevy_ecs::prelude::*;
3431 /// # use bevy_ecs::change_detection::MutUntyped;
3432 /// # use std::collections::HashMap;
3433 /// # use std::any::TypeId;
3434 /// # #[derive(Resource)]
3435 /// # struct A(u32);
3436 /// # #[derive(Resource)]
3437 /// # struct B(u32);
3438 /// #
3439 /// # let mut world = World::new();
3440 /// # world.insert_resource(A(1));
3441 /// # world.insert_resource(B(2));
3442 /// #
3443 /// // In this example, `A` and `B` are resources. We deliberately do not use the
3444 /// // `bevy_reflect` crate here to showcase the low-level `MutUntyped` usage. You should
3445 /// // probably use something like `ReflectFromPtr` in a real-world scenario.
3446 ///
3447 /// // Create the hash map that will store the mutator closures for each resource type
3448 /// let mut mutators: HashMap<TypeId, Box<dyn Fn(&mut MutUntyped<'_>)>> = HashMap::default();
3449 ///
3450 /// // Add mutator closure for `A`
3451 /// mutators.insert(TypeId::of::<A>(), Box::new(|mut_untyped| {
3452 /// // Note: `MutUntyped::as_mut()` automatically marks the resource as changed
3453 /// // for ECS change detection, and gives us a `PtrMut` we can use to mutate the resource.
3454 /// // SAFETY: We assert ptr is the same type of A with TypeId of A
3455 /// let a = unsafe { &mut mut_untyped.as_mut().deref_mut::<A>() };
3456 /// # a.0 += 1;
3457 /// // ... mutate `a` here
3458 /// }));
3459 ///
3460 /// // Add mutator closure for `B`
3461 /// mutators.insert(TypeId::of::<B>(), Box::new(|mut_untyped| {
3462 /// // SAFETY: We assert ptr is the same type of B with TypeId of B
3463 /// let b = unsafe { &mut mut_untyped.as_mut().deref_mut::<B>() };
3464 /// # b.0 += 1;
3465 /// // ... mutate `b` here
3466 /// }));
3467 ///
3468 /// // Iterate all resources, in order to run the mutator closures for each matching resource type
3469 /// for (info, mut mut_untyped) in world.iter_resources_mut() {
3470 /// let Some(type_id) = info.type_id() else {
3471 /// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources
3472 /// // dynamically inserted via a scripting language) in which case we can't match them.
3473 /// continue;
3474 /// };
3475 ///
3476 /// let Some(mutator) = mutators.get(&type_id) else {
3477 /// // No mutator closure for this resource type, skip it.
3478 /// continue;
3479 /// };
3480 ///
3481 /// // Run the mutator closure for the resource
3482 /// mutator(&mut mut_untyped);
3483 /// }
3484 /// # assert_eq!(world.resource::<A>().0, 2);
3485 /// # assert_eq!(world.resource::<B>().0, 3);
3486 /// ```
3487 #[inline]
3488 pub fn iter_resources_mut(&mut self) -> impl Iterator<Item = (&ComponentInfo, MutUntyped<'_>)> {
3489 self.storages
3490 .resources
3491 .iter()
3492 .filter_map(|(component_id, data)| {
3493 // SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.
3494 let component_info = unsafe {
3495 self.components
3496 .get_info(component_id)
3497 .debug_checked_unwrap()
3498 };
3499 let (ptr, ticks) = data.get_with_ticks()?;
3500
3501 // SAFETY:
3502 // - We have exclusive access to the world, so no other code can be aliasing the `ComponentTickCells`
3503 // - We only hold one `ComponentTicksMut` at a time, and we let go of it before getting the next one
3504 let ticks = unsafe {
3505 ComponentTicksMut::from_tick_cells(
3506 ticks,
3507 self.last_change_tick(),
3508 self.read_change_tick(),
3509 )
3510 };
3511
3512 let mut_untyped = MutUntyped {
3513 // SAFETY:
3514 // - We have exclusive access to the world, so no other code can be aliasing the `Ptr`
3515 // - We iterate one resource at a time, and we let go of each `PtrMut` before getting the next one
3516 value: unsafe { ptr.assert_unique() },
3517 ticks,
3518 };
3519
3520 Some((component_info, mut_untyped))
3521 })
3522 }
3523
3524 /// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.
3525 /// The returned pointer must not be used to modify the resource, and must not be
3526 /// dereferenced after the immutable borrow of the [`World`] ends.
3527 ///
3528 /// **You should prefer to use the typed API [`World::get_resource`] where possible and only
3529 /// use this in cases where the actual types are not known at compile time.**
3530 ///
3531 /// # Panics
3532 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3533 #[inline]
3534 pub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
3535 // SAFETY:
3536 // - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably
3537 // - `&self` ensures there are no mutable borrows on world data
3538 unsafe {
3539 self.as_unsafe_world_cell_readonly()
3540 .get_non_send_resource_by_id(component_id)
3541 }
3542 }
3543
3544 /// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.
3545 /// The returned pointer may be used to modify the resource, as long as the mutable borrow
3546 /// of the [`World`] is still valid.
3547 ///
3548 /// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only
3549 /// use this in cases where the actual types are not known at compile time.**
3550 ///
3551 /// # Panics
3552 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3553 #[inline]
3554 pub fn get_non_send_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
3555 // SAFETY:
3556 // - `&mut self` ensures that all accessed data is unaliased
3557 // - `as_unsafe_world_cell` provides mutable permission to the whole world
3558 unsafe {
3559 self.as_unsafe_world_cell()
3560 .get_non_send_resource_mut_by_id(component_id)
3561 }
3562 }
3563
3564 /// Removes the resource of a given type, if it exists. Otherwise returns `None`.
3565 ///
3566 /// **You should prefer to use the typed API [`World::remove_resource`] where possible and only
3567 /// use this in cases where the actual types are not known at compile time.**
3568 pub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> Option<()> {
3569 self.storages
3570 .resources
3571 .get_mut(component_id)?
3572 .remove_and_drop();
3573 Some(())
3574 }
3575
3576 /// Removes the resource of a given type, if it exists. Otherwise returns `None`.
3577 ///
3578 /// **You should prefer to use the typed API [`World::remove_resource`] where possible and only
3579 /// use this in cases where the actual types are not known at compile time.**
3580 ///
3581 /// # Panics
3582 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3583 pub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()> {
3584 self.storages
3585 .non_send_resources
3586 .get_mut(component_id)?
3587 .remove_and_drop();
3588 Some(())
3589 }
3590
3591 /// Retrieves an immutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
3592 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
3593 ///
3594 /// **You should prefer to use the typed API [`World::get_mut`] where possible and only
3595 /// use this in cases where the actual types are not known at compile time.**
3596 ///
3597 /// # Panics
3598 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3599 #[inline]
3600 pub fn get_by_id(&self, entity: Entity, component_id: ComponentId) -> Option<Ptr<'_>> {
3601 self.get_entity(entity).ok()?.get_by_id(component_id).ok()
3602 }
3603
3604 /// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
3605 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
3606 ///
3607 /// **You should prefer to use the typed API [`World::get_mut`] where possible and only
3608 /// use this in cases where the actual types are not known at compile time.**
3609 #[inline]
3610 pub fn get_mut_by_id(
3611 &mut self,
3612 entity: Entity,
3613 component_id: ComponentId,
3614 ) -> Option<MutUntyped<'_>> {
3615 self.get_entity_mut(entity)
3616 .ok()?
3617 .into_mut_by_id(component_id)
3618 .ok()
3619 }
3620}
3621
3622// Schedule-related methods
3623impl World {
3624 /// Adds the specified [`Schedule`] to the world.
3625 /// If a schedule already exists with the same [label](Schedule::label), it will be replaced.
3626 ///
3627 /// The schedule can later be run
3628 /// by calling [`.run_schedule(label)`](Self::run_schedule) or by directly
3629 /// accessing the [`Schedules`] resource.
3630 ///
3631 /// The `Schedules` resource will be initialized if it does not already exist.
3632 ///
3633 /// An alternative to this is to call [`Schedules::add_systems()`] with some
3634 /// [`ScheduleLabel`] and let the schedule for that label be created if it
3635 /// does not already exist.
3636 pub fn add_schedule(&mut self, schedule: Schedule) {
3637 let mut schedules = self.get_resource_or_init::<Schedules>();
3638 schedules.insert(schedule);
3639 }
3640
3641 /// Temporarily removes the schedule associated with `label` from the world,
3642 /// runs user code, and finally re-adds the schedule.
3643 /// This returns a [`TryRunScheduleError`] if there is no schedule
3644 /// associated with `label`.
3645 ///
3646 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3647 /// and system state is cached.
3648 ///
3649 /// For simple cases where you just need to call the schedule once,
3650 /// consider using [`World::try_run_schedule`] instead.
3651 /// For other use cases, see the example on [`World::schedule_scope`].
3652 pub fn try_schedule_scope<R>(
3653 &mut self,
3654 label: impl ScheduleLabel,
3655 f: impl FnOnce(&mut World, &mut Schedule) -> R,
3656 ) -> Result<R, TryRunScheduleError> {
3657 let label = label.intern();
3658 let Some(mut schedule) = self
3659 .get_resource_mut::<Schedules>()
3660 .and_then(|mut s| s.remove(label))
3661 else {
3662 return Err(TryRunScheduleError(label));
3663 };
3664
3665 let value = f(self, &mut schedule);
3666
3667 let old = self.resource_mut::<Schedules>().insert(schedule);
3668 if old.is_some() {
3669 warn!("Schedule `{label:?}` was inserted during a call to `World::schedule_scope`: its value has been overwritten");
3670 }
3671
3672 Ok(value)
3673 }
3674
3675 /// Temporarily removes the schedule associated with `label` from the world,
3676 /// runs user code, and finally re-adds the schedule.
3677 ///
3678 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3679 /// and system state is cached.
3680 ///
3681 /// # Examples
3682 ///
3683 /// ```
3684 /// # use bevy_ecs::{prelude::*, schedule::ScheduleLabel};
3685 /// # #[derive(ScheduleLabel, Debug, Clone, Copy, PartialEq, Eq, Hash)]
3686 /// # pub struct MySchedule;
3687 /// # #[derive(Resource)]
3688 /// # struct Counter(usize);
3689 /// #
3690 /// # let mut world = World::new();
3691 /// # world.insert_resource(Counter(0));
3692 /// # let mut schedule = Schedule::new(MySchedule);
3693 /// # schedule.add_systems(tick_counter);
3694 /// # world.init_resource::<Schedules>();
3695 /// # world.add_schedule(schedule);
3696 /// # fn tick_counter(mut counter: ResMut<Counter>) { counter.0 += 1; }
3697 /// // Run the schedule five times.
3698 /// world.schedule_scope(MySchedule, |world, schedule| {
3699 /// for _ in 0..5 {
3700 /// schedule.run(world);
3701 /// }
3702 /// });
3703 /// # assert_eq!(world.resource::<Counter>().0, 5);
3704 /// ```
3705 ///
3706 /// For simple cases where you just need to call the schedule once,
3707 /// consider using [`World::run_schedule`] instead.
3708 ///
3709 /// # Panics
3710 ///
3711 /// If the requested schedule does not exist.
3712 pub fn schedule_scope<R>(
3713 &mut self,
3714 label: impl ScheduleLabel,
3715 f: impl FnOnce(&mut World, &mut Schedule) -> R,
3716 ) -> R {
3717 self.try_schedule_scope(label, f)
3718 .unwrap_or_else(|e| panic!("{e}"))
3719 }
3720
3721 /// Attempts to run the [`Schedule`] associated with the `label` a single time,
3722 /// and returns a [`TryRunScheduleError`] if the schedule does not exist.
3723 ///
3724 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3725 /// and system state is cached.
3726 ///
3727 /// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.
3728 pub fn try_run_schedule(
3729 &mut self,
3730 label: impl ScheduleLabel,
3731 ) -> Result<(), TryRunScheduleError> {
3732 self.try_schedule_scope(label, |world, sched| sched.run(world))
3733 }
3734
3735 /// Runs the [`Schedule`] associated with the `label` a single time.
3736 ///
3737 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3738 /// and system state is cached.
3739 ///
3740 /// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.
3741 /// This avoids the need to create a unique [`ScheduleLabel`].
3742 ///
3743 /// # Panics
3744 ///
3745 /// If the requested schedule does not exist.
3746 pub fn run_schedule(&mut self, label: impl ScheduleLabel) {
3747 self.schedule_scope(label, |world, sched| sched.run(world));
3748 }
3749
3750 /// Ignore system order ambiguities caused by conflicts on [`Component`]s of type `T`.
3751 pub fn allow_ambiguous_component<T: Component>(&mut self) {
3752 let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();
3753 schedules.allow_ambiguous_component::<T>(self);
3754 self.insert_resource(schedules);
3755 }
3756
3757 /// Ignore system order ambiguities caused by conflicts on [`Resource`]s of type `T`.
3758 pub fn allow_ambiguous_resource<T: Resource>(&mut self) {
3759 let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();
3760 schedules.allow_ambiguous_resource::<T>(self);
3761 self.insert_resource(schedules);
3762 }
3763}
3764
3765impl fmt::Debug for World {
3766 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3767 // SAFETY: `UnsafeWorldCell` requires that this must only access metadata.
3768 // Accessing any data stored in the world would be unsound.
3769 f.debug_struct("World")
3770 .field("id", &self.id)
3771 .field("entity_count", &self.entities.count_spawned())
3772 .field("archetype_count", &self.archetypes.len())
3773 .field("component_count", &self.components.len())
3774 .field("resource_count", &self.storages.resources.len())
3775 .finish()
3776 }
3777}
3778
3779// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread
3780unsafe impl Send for World {}
3781// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread
3782unsafe impl Sync for World {}
3783
3784/// Creates an instance of the type this trait is implemented for
3785/// using data from the supplied [`World`].
3786///
3787/// This can be helpful for complex initialization or context-aware defaults.
3788///
3789/// [`FromWorld`] is automatically implemented for any type implementing [`Default`]
3790/// and may also be derived for:
3791/// - any struct whose fields all implement `FromWorld`
3792/// - any enum where one variant has the attribute `#[from_world]`
3793///
3794/// ```rs
3795///
3796/// #[derive(Default)]
3797/// struct A;
3798///
3799/// #[derive(Default)]
3800/// struct B(Option<u32>)
3801///
3802/// struct C;
3803///
3804/// impl FromWorld for C {
3805/// fn from_world(_world: &mut World) -> Self {
3806/// Self
3807/// }
3808/// }
3809///
3810/// #[derive(FromWorld)]
3811/// struct D(A, B, C);
3812///
3813/// #[derive(FromWorld)]
3814/// enum E {
3815/// #[from_world]
3816/// F,
3817/// G
3818/// }
3819/// ```
3820pub trait FromWorld {
3821 /// Creates `Self` using data from the given [`World`].
3822 fn from_world(world: &mut World) -> Self;
3823}
3824
3825impl<T: Default> FromWorld for T {
3826 /// Creates `Self` using [`default()`](`Default::default`).
3827 #[track_caller]
3828 fn from_world(_world: &mut World) -> Self {
3829 T::default()
3830 }
3831}
3832
3833#[cfg(test)]
3834#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
3835mod tests {
3836 use super::{FromWorld, World};
3837 use crate::{
3838 change_detection::{DetectChangesMut, MaybeLocation},
3839 component::{ComponentCloneBehavior, ComponentDescriptor, ComponentInfo, StorageType},
3840 entity::EntityHashSet,
3841 entity_disabling::{DefaultQueryFilters, Disabled},
3842 ptr::OwningPtr,
3843 resource::Resource,
3844 world::{error::EntityMutableFetchError, DeferredWorld},
3845 };
3846 use alloc::{
3847 borrow::ToOwned,
3848 string::{String, ToString},
3849 sync::Arc,
3850 vec,
3851 vec::Vec,
3852 };
3853 use bevy_ecs_macros::Component;
3854 use bevy_platform::collections::HashSet;
3855 use bevy_utils::prelude::DebugName;
3856 use core::{
3857 any::TypeId,
3858 panic,
3859 sync::atomic::{AtomicBool, AtomicU32, Ordering},
3860 };
3861 use std::{println, sync::Mutex};
3862
3863 type ID = u8;
3864
3865 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
3866 enum DropLogItem {
3867 Create(ID),
3868 Drop(ID),
3869 }
3870
3871 #[derive(Component)]
3872 struct MayPanicInDrop {
3873 drop_log: Arc<Mutex<Vec<DropLogItem>>>,
3874 expected_panic_flag: Arc<AtomicBool>,
3875 should_panic: bool,
3876 id: u8,
3877 }
3878
3879 impl MayPanicInDrop {
3880 fn new(
3881 drop_log: &Arc<Mutex<Vec<DropLogItem>>>,
3882 expected_panic_flag: &Arc<AtomicBool>,
3883 should_panic: bool,
3884 id: u8,
3885 ) -> Self {
3886 println!("creating component with id {id}");
3887 drop_log.lock().unwrap().push(DropLogItem::Create(id));
3888
3889 Self {
3890 drop_log: Arc::clone(drop_log),
3891 expected_panic_flag: Arc::clone(expected_panic_flag),
3892 should_panic,
3893 id,
3894 }
3895 }
3896 }
3897
3898 impl Drop for MayPanicInDrop {
3899 fn drop(&mut self) {
3900 println!("dropping component with id {}", self.id);
3901
3902 {
3903 let mut drop_log = self.drop_log.lock().unwrap();
3904 drop_log.push(DropLogItem::Drop(self.id));
3905 // Don't keep the mutex while panicking, or we'll poison it.
3906 drop(drop_log);
3907 }
3908
3909 if self.should_panic {
3910 self.expected_panic_flag.store(true, Ordering::SeqCst);
3911 panic!("testing what happens on panic inside drop");
3912 }
3913 }
3914 }
3915
3916 struct DropTestHelper {
3917 drop_log: Arc<Mutex<Vec<DropLogItem>>>,
3918 /// Set to `true` right before we intentionally panic, so that if we get
3919 /// a panic, we know if it was intended or not.
3920 expected_panic_flag: Arc<AtomicBool>,
3921 }
3922
3923 impl DropTestHelper {
3924 pub fn new() -> Self {
3925 Self {
3926 drop_log: Arc::new(Mutex::new(Vec::<DropLogItem>::new())),
3927 expected_panic_flag: Arc::new(AtomicBool::new(false)),
3928 }
3929 }
3930
3931 pub fn make_component(&self, should_panic: bool, id: ID) -> MayPanicInDrop {
3932 MayPanicInDrop::new(&self.drop_log, &self.expected_panic_flag, should_panic, id)
3933 }
3934
3935 pub fn finish(self, panic_res: std::thread::Result<()>) -> Vec<DropLogItem> {
3936 let drop_log = self.drop_log.lock().unwrap();
3937 let expected_panic_flag = self.expected_panic_flag.load(Ordering::SeqCst);
3938
3939 if !expected_panic_flag {
3940 match panic_res {
3941 Ok(()) => panic!("Expected a panic but it didn't happen"),
3942 Err(e) => std::panic::resume_unwind(e),
3943 }
3944 }
3945
3946 drop_log.to_owned()
3947 }
3948 }
3949
3950 #[test]
3951 fn panic_while_overwriting_component() {
3952 let helper = DropTestHelper::new();
3953
3954 let res = std::panic::catch_unwind(|| {
3955 let mut world = World::new();
3956 world
3957 .spawn_empty()
3958 .insert(helper.make_component(true, 0))
3959 .insert(helper.make_component(false, 1));
3960
3961 println!("Done inserting! Dropping world...");
3962 });
3963
3964 let drop_log = helper.finish(res);
3965
3966 assert_eq!(
3967 &*drop_log,
3968 [
3969 DropLogItem::Create(0),
3970 DropLogItem::Create(1),
3971 DropLogItem::Drop(0),
3972 DropLogItem::Drop(1),
3973 ]
3974 );
3975 }
3976
3977 #[derive(Resource)]
3978 struct TestResource(u32);
3979
3980 #[derive(Resource)]
3981 struct TestResource2(String);
3982
3983 #[derive(Resource)]
3984 struct TestResource3;
3985
3986 #[test]
3987 fn get_resource_by_id() {
3988 let mut world = World::new();
3989 world.insert_resource(TestResource(42));
3990 let component_id = world
3991 .components()
3992 .get_valid_resource_id(TypeId::of::<TestResource>())
3993 .unwrap();
3994
3995 let resource = world.get_resource_by_id(component_id).unwrap();
3996 // SAFETY: `TestResource` is the correct resource type
3997 let resource = unsafe { resource.deref::<TestResource>() };
3998
3999 assert_eq!(resource.0, 42);
4000 }
4001
4002 #[test]
4003 fn get_resource_mut_by_id() {
4004 let mut world = World::new();
4005 world.insert_resource(TestResource(42));
4006 let component_id = world
4007 .components()
4008 .get_valid_resource_id(TypeId::of::<TestResource>())
4009 .unwrap();
4010
4011 {
4012 let mut resource = world.get_resource_mut_by_id(component_id).unwrap();
4013 resource.set_changed();
4014 // SAFETY: `TestResource` is the correct resource type
4015 let resource = unsafe { resource.into_inner().deref_mut::<TestResource>() };
4016 resource.0 = 43;
4017 }
4018
4019 let resource = world.get_resource_by_id(component_id).unwrap();
4020 // SAFETY: `TestResource` is the correct resource type
4021 let resource = unsafe { resource.deref::<TestResource>() };
4022
4023 assert_eq!(resource.0, 43);
4024 }
4025
4026 #[test]
4027 fn iter_resources() {
4028 let mut world = World::new();
4029 // Remove DefaultQueryFilters so it doesn't show up in the iterator
4030 world.remove_resource::<DefaultQueryFilters>();
4031 world.insert_resource(TestResource(42));
4032 world.insert_resource(TestResource2("Hello, world!".to_string()));
4033 world.insert_resource(TestResource3);
4034 world.remove_resource::<TestResource3>();
4035
4036 let mut iter = world.iter_resources();
4037
4038 let (info, ptr) = iter.next().unwrap();
4039 assert_eq!(info.name(), DebugName::type_name::<TestResource>());
4040 // SAFETY: We know that the resource is of type `TestResource`
4041 assert_eq!(unsafe { ptr.deref::<TestResource>().0 }, 42);
4042
4043 let (info, ptr) = iter.next().unwrap();
4044 assert_eq!(info.name(), DebugName::type_name::<TestResource2>());
4045 assert_eq!(
4046 // SAFETY: We know that the resource is of type `TestResource2`
4047 unsafe { &ptr.deref::<TestResource2>().0 },
4048 &"Hello, world!".to_string()
4049 );
4050
4051 assert!(iter.next().is_none());
4052 }
4053
4054 #[test]
4055 fn iter_resources_mut() {
4056 let mut world = World::new();
4057 // Remove DefaultQueryFilters so it doesn't show up in the iterator
4058 world.remove_resource::<DefaultQueryFilters>();
4059 world.insert_resource(TestResource(42));
4060 world.insert_resource(TestResource2("Hello, world!".to_string()));
4061 world.insert_resource(TestResource3);
4062 world.remove_resource::<TestResource3>();
4063
4064 let mut iter = world.iter_resources_mut();
4065
4066 let (info, mut mut_untyped) = iter.next().unwrap();
4067 assert_eq!(info.name(), DebugName::type_name::<TestResource>());
4068 // SAFETY: We know that the resource is of type `TestResource`
4069 unsafe {
4070 mut_untyped.as_mut().deref_mut::<TestResource>().0 = 43;
4071 };
4072
4073 let (info, mut mut_untyped) = iter.next().unwrap();
4074 assert_eq!(info.name(), DebugName::type_name::<TestResource2>());
4075 // SAFETY: We know that the resource is of type `TestResource2`
4076 unsafe {
4077 mut_untyped.as_mut().deref_mut::<TestResource2>().0 = "Hello, world?".to_string();
4078 };
4079
4080 assert!(iter.next().is_none());
4081 drop(iter);
4082
4083 assert_eq!(world.resource::<TestResource>().0, 43);
4084 assert_eq!(
4085 world.resource::<TestResource2>().0,
4086 "Hello, world?".to_string()
4087 );
4088 }
4089
4090 #[test]
4091 fn dynamic_resource() {
4092 let mut world = World::new();
4093
4094 let descriptor = ComponentDescriptor::new_resource::<TestResource>();
4095
4096 let component_id = world.register_resource_with_descriptor(descriptor);
4097
4098 let value = 0;
4099 OwningPtr::make(value, |ptr| {
4100 // SAFETY: value is valid for the layout of `TestResource`
4101 unsafe {
4102 world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());
4103 }
4104 });
4105
4106 // SAFETY: We know that the resource is of type `TestResource`
4107 let resource = unsafe {
4108 world
4109 .get_resource_by_id(component_id)
4110 .unwrap()
4111 .deref::<TestResource>()
4112 };
4113 assert_eq!(resource.0, 0);
4114
4115 assert!(world.remove_resource_by_id(component_id).is_some());
4116 }
4117
4118 #[test]
4119 fn custom_resource_with_layout() {
4120 static DROP_COUNT: AtomicU32 = AtomicU32::new(0);
4121
4122 let mut world = World::new();
4123
4124 // SAFETY: the drop function is valid for the layout and the data will be safe to access from any thread
4125 let descriptor = unsafe {
4126 ComponentDescriptor::new_with_layout(
4127 "Custom Test Component".to_string(),
4128 StorageType::Table,
4129 core::alloc::Layout::new::<[u8; 8]>(),
4130 Some(|ptr| {
4131 let data = ptr.read::<[u8; 8]>();
4132 assert_eq!(data, [0, 1, 2, 3, 4, 5, 6, 7]);
4133 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4134 }),
4135 true,
4136 ComponentCloneBehavior::Default,
4137 None,
4138 )
4139 };
4140
4141 let component_id = world.register_resource_with_descriptor(descriptor);
4142
4143 let value: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
4144 OwningPtr::make(value, |ptr| {
4145 // SAFETY: value is valid for the component layout
4146 unsafe {
4147 world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());
4148 }
4149 });
4150
4151 // SAFETY: [u8; 8] is the correct type for the resource
4152 let data = unsafe {
4153 world
4154 .get_resource_by_id(component_id)
4155 .unwrap()
4156 .deref::<[u8; 8]>()
4157 };
4158 assert_eq!(*data, [0, 1, 2, 3, 4, 5, 6, 7]);
4159
4160 assert!(world.remove_resource_by_id(component_id).is_some());
4161
4162 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
4163 }
4164
4165 #[derive(Resource)]
4166 struct TestFromWorld(u32);
4167 impl FromWorld for TestFromWorld {
4168 fn from_world(world: &mut World) -> Self {
4169 let b = world.resource::<TestResource>();
4170 Self(b.0)
4171 }
4172 }
4173
4174 #[test]
4175 fn init_resource_does_not_overwrite() {
4176 let mut world = World::new();
4177 world.insert_resource(TestResource(0));
4178 world.init_resource::<TestFromWorld>();
4179 world.insert_resource(TestResource(1));
4180 world.init_resource::<TestFromWorld>();
4181
4182 let resource = world.resource::<TestFromWorld>();
4183
4184 assert_eq!(resource.0, 0);
4185 }
4186
4187 #[test]
4188 fn init_non_send_resource_does_not_overwrite() {
4189 let mut world = World::new();
4190 world.insert_resource(TestResource(0));
4191 world.init_non_send_resource::<TestFromWorld>();
4192 world.insert_resource(TestResource(1));
4193 world.init_non_send_resource::<TestFromWorld>();
4194
4195 let resource = world.non_send_resource::<TestFromWorld>();
4196
4197 assert_eq!(resource.0, 0);
4198 }
4199
4200 #[derive(Component)]
4201 struct Foo;
4202
4203 #[derive(Component)]
4204 struct Bar;
4205
4206 #[derive(Component)]
4207 struct Baz;
4208
4209 #[test]
4210 fn inspect_entity_components() {
4211 let mut world = World::new();
4212 let ent0 = world.spawn((Foo, Bar, Baz)).id();
4213 let ent1 = world.spawn((Foo, Bar)).id();
4214 let ent2 = world.spawn((Bar, Baz)).id();
4215 let ent3 = world.spawn((Foo, Baz)).id();
4216 let ent4 = world.spawn(Foo).id();
4217 let ent5 = world.spawn(Bar).id();
4218 let ent6 = world.spawn(Baz).id();
4219
4220 fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {
4221 component_infos
4222 .into_iter()
4223 .map(ComponentInfo::type_id)
4224 .collect()
4225 }
4226
4227 let foo_id = TypeId::of::<Foo>();
4228 let bar_id = TypeId::of::<Bar>();
4229 let baz_id = TypeId::of::<Baz>();
4230 assert_eq!(
4231 to_type_ids(world.inspect_entity(ent0).unwrap().collect()),
4232 [Some(foo_id), Some(bar_id), Some(baz_id)]
4233 .into_iter()
4234 .collect::<HashSet<_>>()
4235 );
4236 assert_eq!(
4237 to_type_ids(world.inspect_entity(ent1).unwrap().collect()),
4238 [Some(foo_id), Some(bar_id)]
4239 .into_iter()
4240 .collect::<HashSet<_>>()
4241 );
4242 assert_eq!(
4243 to_type_ids(world.inspect_entity(ent2).unwrap().collect()),
4244 [Some(bar_id), Some(baz_id)]
4245 .into_iter()
4246 .collect::<HashSet<_>>()
4247 );
4248 assert_eq!(
4249 to_type_ids(world.inspect_entity(ent3).unwrap().collect()),
4250 [Some(foo_id), Some(baz_id)]
4251 .into_iter()
4252 .collect::<HashSet<_>>()
4253 );
4254 assert_eq!(
4255 to_type_ids(world.inspect_entity(ent4).unwrap().collect()),
4256 [Some(foo_id)].into_iter().collect::<HashSet<_>>()
4257 );
4258 assert_eq!(
4259 to_type_ids(world.inspect_entity(ent5).unwrap().collect()),
4260 [Some(bar_id)].into_iter().collect::<HashSet<_>>()
4261 );
4262 assert_eq!(
4263 to_type_ids(world.inspect_entity(ent6).unwrap().collect()),
4264 [Some(baz_id)].into_iter().collect::<HashSet<_>>()
4265 );
4266 }
4267
4268 #[test]
4269 fn spawn_empty_bundle() {
4270 let mut world = World::new();
4271 world.spawn(());
4272 }
4273
4274 #[test]
4275 fn get_entity() {
4276 let mut world = World::new();
4277
4278 let e1 = world.spawn_empty().id();
4279 let e2 = world.spawn_empty().id();
4280
4281 assert!(world.get_entity(e1).is_ok());
4282 assert!(world.get_entity([e1, e2]).is_ok());
4283 assert!(world
4284 .get_entity(&[e1, e2] /* this is an array not a slice */)
4285 .is_ok());
4286 assert!(world.get_entity(&vec![e1, e2][..]).is_ok());
4287 assert!(world
4288 .get_entity(&EntityHashSet::from_iter([e1, e2]))
4289 .is_ok());
4290
4291 world.entity_mut(e1).despawn();
4292
4293 assert_eq!(
4294 Err(e1),
4295 world.get_entity(e1).map(|_| {}).map_err(|e| e.entity())
4296 );
4297 assert_eq!(
4298 Err(e1),
4299 world
4300 .get_entity([e1, e2])
4301 .map(|_| {})
4302 .map_err(|e| e.entity())
4303 );
4304 assert_eq!(
4305 Err(e1),
4306 world
4307 .get_entity(&[e1, e2] /* this is an array not a slice */)
4308 .map(|_| {})
4309 .map_err(|e| e.entity())
4310 );
4311 assert_eq!(
4312 Err(e1),
4313 world
4314 .get_entity(&vec![e1, e2][..])
4315 .map(|_| {})
4316 .map_err(|e| e.entity())
4317 );
4318 assert_eq!(
4319 Err(e1),
4320 world
4321 .get_entity(&EntityHashSet::from_iter([e1, e2]))
4322 .map(|_| {})
4323 .map_err(|e| e.entity())
4324 );
4325 }
4326
4327 #[test]
4328 fn get_entity_mut() {
4329 let mut world = World::new();
4330
4331 let e1 = world.spawn_empty().id();
4332 let e2 = world.spawn_empty().id();
4333
4334 assert!(world.get_entity_mut(e1).is_ok());
4335 assert!(world.get_entity_mut([e1, e2]).is_ok());
4336 assert!(world
4337 .get_entity_mut(&[e1, e2] /* this is an array not a slice */)
4338 .is_ok());
4339 assert!(world.get_entity_mut(&vec![e1, e2][..]).is_ok());
4340 assert!(world
4341 .get_entity_mut(&EntityHashSet::from_iter([e1, e2]))
4342 .is_ok());
4343
4344 assert_eq!(
4345 Err(EntityMutableFetchError::AliasedMutability(e1)),
4346 world.get_entity_mut([e1, e2, e1]).map(|_| {})
4347 );
4348 assert_eq!(
4349 Err(EntityMutableFetchError::AliasedMutability(e1)),
4350 world
4351 .get_entity_mut(&[e1, e2, e1] /* this is an array not a slice */)
4352 .map(|_| {})
4353 );
4354 assert_eq!(
4355 Err(EntityMutableFetchError::AliasedMutability(e1)),
4356 world.get_entity_mut(&vec![e1, e2, e1][..]).map(|_| {})
4357 );
4358 // Aliased mutability isn't allowed by HashSets
4359 assert!(world
4360 .get_entity_mut(&EntityHashSet::from_iter([e1, e2, e1]))
4361 .is_ok());
4362
4363 world.entity_mut(e1).despawn();
4364 assert!(world.get_entity_mut(e2).is_ok());
4365
4366 assert!(matches!(
4367 world.get_entity_mut(e1).map(|_| {}),
4368 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1
4369 ));
4370 assert!(matches!(
4371 world.get_entity_mut([e1, e2]).map(|_| {}),
4372 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));
4373 assert!(matches!(
4374 world
4375 .get_entity_mut(&[e1, e2] /* this is an array not a slice */)
4376 .map(|_| {}),
4377 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));
4378 assert!(matches!(
4379 world.get_entity_mut(&vec![e1, e2][..]).map(|_| {}),
4380 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1,
4381 ));
4382 assert!(matches!(
4383 world
4384 .get_entity_mut(&EntityHashSet::from_iter([e1, e2]))
4385 .map(|_| {}),
4386 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));
4387 }
4388
4389 #[test]
4390 #[track_caller]
4391 fn entity_spawn_despawn_tracking() {
4392 use core::panic::Location;
4393
4394 let mut world = World::new();
4395 let entity = world.spawn_empty().id();
4396 assert_eq!(
4397 world.entities.entity_get_spawned_or_despawned_by(entity),
4398 MaybeLocation::new(Some(Location::caller()))
4399 );
4400 assert_eq!(
4401 world.entities.entity_get_spawn_or_despawn_tick(entity),
4402 Some(world.change_tick())
4403 );
4404 world.despawn(entity);
4405 assert_eq!(
4406 world.entities.entity_get_spawned_or_despawned_by(entity),
4407 MaybeLocation::new(Some(Location::caller()))
4408 );
4409 assert_eq!(
4410 world.entities.entity_get_spawn_or_despawn_tick(entity),
4411 Some(world.change_tick())
4412 );
4413 let new = world.spawn_empty().id();
4414 assert_eq!(entity.index(), new.index());
4415 assert_eq!(
4416 world.entities.entity_get_spawned_or_despawned_by(entity),
4417 MaybeLocation::new(None)
4418 );
4419 assert_eq!(
4420 world.entities.entity_get_spawn_or_despawn_tick(entity),
4421 None
4422 );
4423 world.despawn(new);
4424 assert_eq!(
4425 world.entities.entity_get_spawned_or_despawned_by(entity),
4426 MaybeLocation::new(None)
4427 );
4428 assert_eq!(
4429 world.entities.entity_get_spawn_or_despawn_tick(entity),
4430 None
4431 );
4432 }
4433
4434 #[test]
4435 fn new_world_has_disabling() {
4436 let mut world = World::new();
4437 world.spawn(Foo);
4438 world.spawn((Foo, Disabled));
4439 assert_eq!(1, world.query::<&Foo>().iter(&world).count());
4440
4441 // If we explicitly remove the resource, no entities should be filtered anymore
4442 world.remove_resource::<DefaultQueryFilters>();
4443 assert_eq!(2, world.query::<&Foo>().iter(&world).count());
4444 }
4445
4446 #[test]
4447 fn entities_and_commands() {
4448 #[derive(Component, PartialEq, Debug)]
4449 struct Foo(u32);
4450
4451 let mut world = World::new();
4452
4453 let eid = world.spawn(Foo(35)).id();
4454
4455 let (mut fetcher, mut commands) = world.entities_and_commands();
4456 let emut = fetcher.get_mut(eid).unwrap();
4457 commands.entity(eid).despawn();
4458 assert_eq!(emut.get::<Foo>().unwrap(), &Foo(35));
4459
4460 world.flush();
4461
4462 assert!(world.get_entity(eid).is_err());
4463 }
4464
4465 #[test]
4466 fn entities_and_commands_deferred() {
4467 #[derive(Component, PartialEq, Debug)]
4468 struct Foo(u32);
4469
4470 let mut world = World::new();
4471
4472 let eid = world.spawn(Foo(1)).id();
4473
4474 let mut dworld = DeferredWorld::from(&mut world);
4475
4476 let (mut fetcher, mut commands) = dworld.entities_and_commands();
4477 let emut = fetcher.get_mut(eid).unwrap();
4478 commands.entity(eid).despawn();
4479 assert_eq!(emut.get::<Foo>().unwrap(), &Foo(1));
4480
4481 world.flush();
4482
4483 assert!(world.get_entity(eid).is_err());
4484 }
4485}