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.entities().get_spawned(entity).ok();
1101 }
1102
1103 // SAFETY: The entity and location started as valid.
1104 // If they were changed by commands, the location was updated to match.
1105 let mut entity = unsafe { EntityWorldMut::new(self, entity, entity_location) };
1106 // SAFETY:
1107 // - This is called exactly once after `get_components` has been called in `spawn_non_existent`.
1108 // - `bundle` had it's `get_components` function called exactly once inside `spawn_non_existent`.
1109 unsafe { B::apply_effect(bundle, &mut entity) };
1110 entity
1111 }
1112
1113 /// A faster version of [`spawn_at`](Self::spawn_at) for the empty bundle.
1114 #[track_caller]
1115 pub fn spawn_empty_at(&mut self, entity: Entity) -> Result<EntityWorldMut<'_>, SpawnError> {
1116 self.spawn_empty_at_with_caller(entity, MaybeLocation::caller())
1117 }
1118
1119 pub(crate) fn spawn_empty_at_with_caller(
1120 &mut self,
1121 entity: Entity,
1122 caller: MaybeLocation,
1123 ) -> Result<EntityWorldMut<'_>, SpawnError> {
1124 self.entities.check_can_spawn_at(entity)?;
1125 Ok(self.spawn_empty_at_unchecked(entity, caller))
1126 }
1127
1128 /// A faster version of [`spawn_at_unchecked`](Self::spawn_at_unchecked) for the empty bundle.
1129 ///
1130 /// # Panics
1131 ///
1132 /// Panics if the entity index is already spawned
1133 pub(crate) fn spawn_empty_at_unchecked(
1134 &mut self,
1135 entity: Entity,
1136 caller: MaybeLocation,
1137 ) -> EntityWorldMut<'_> {
1138 // SAFETY: Locations are immediately made valid
1139 unsafe {
1140 let archetype = self.archetypes.empty_mut();
1141 // PERF: consider avoiding allocating entities in the empty archetype unless needed
1142 let table_row = self.storages.tables[archetype.table_id()].allocate(entity);
1143 // SAFETY: no components are allocated by archetype.allocate() because the archetype is
1144 // empty
1145 let location = archetype.allocate(entity, table_row);
1146 let change_tick = self.change_tick();
1147 let was_at = self.entities.set_location(entity.index(), Some(location));
1148 assert!(
1149 was_at.is_none(),
1150 "Attempting to construct an empty entity, but it was already constructed."
1151 );
1152 self.entities
1153 .mark_spawned_or_despawned(entity.index(), caller, change_tick);
1154
1155 EntityWorldMut::new(self, entity, Some(location))
1156 }
1157 }
1158
1159 /// Spawns a new [`Entity`] with a given [`Bundle`] of [components](`Component`) and returns
1160 /// a corresponding [`EntityWorldMut`], which can be used to add components to the entity or
1161 /// retrieve its id. In case large batches of entities need to be spawned, consider using
1162 /// [`World::spawn_batch`] instead.
1163 ///
1164 /// ```
1165 /// use bevy_ecs::{bundle::Bundle, component::Component, world::World};
1166 ///
1167 /// #[derive(Component)]
1168 /// struct Position {
1169 /// x: f32,
1170 /// y: f32,
1171 /// }
1172 ///
1173 /// #[derive(Component)]
1174 /// struct Velocity {
1175 /// x: f32,
1176 /// y: f32,
1177 /// };
1178 ///
1179 /// #[derive(Component)]
1180 /// struct Name(&'static str);
1181 ///
1182 /// #[derive(Bundle)]
1183 /// struct PhysicsBundle {
1184 /// position: Position,
1185 /// velocity: Velocity,
1186 /// }
1187 ///
1188 /// let mut world = World::new();
1189 ///
1190 /// // `spawn` can accept a single component:
1191 /// world.spawn(Position { x: 0.0, y: 0.0 });
1192 ///
1193 /// // It can also accept a tuple of components:
1194 /// world.spawn((
1195 /// Position { x: 0.0, y: 0.0 },
1196 /// Velocity { x: 1.0, y: 1.0 },
1197 /// ));
1198 ///
1199 /// // Or it can accept a pre-defined Bundle of components:
1200 /// world.spawn(PhysicsBundle {
1201 /// position: Position { x: 2.0, y: 2.0 },
1202 /// velocity: Velocity { x: 0.0, y: 4.0 },
1203 /// });
1204 ///
1205 /// let entity = world
1206 /// // Tuples can also mix Bundles and Components
1207 /// .spawn((
1208 /// PhysicsBundle {
1209 /// position: Position { x: 2.0, y: 2.0 },
1210 /// velocity: Velocity { x: 0.0, y: 4.0 },
1211 /// },
1212 /// Name("Elaina Proctor"),
1213 /// ))
1214 /// // Calling id() will return the unique identifier for the spawned entity
1215 /// .id();
1216 /// let position = world.entity(entity).get::<Position>().unwrap();
1217 /// assert_eq!(position.x, 2.0);
1218 /// ```
1219 #[track_caller]
1220 pub fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityWorldMut<'_> {
1221 move_as_ptr!(bundle);
1222 self.spawn_with_caller(bundle, MaybeLocation::caller())
1223 }
1224
1225 pub(crate) fn spawn_with_caller<B: Bundle>(
1226 &mut self,
1227 bundle: MovingPtr<'_, B>,
1228 caller: MaybeLocation,
1229 ) -> EntityWorldMut<'_> {
1230 let entity = self.allocator.alloc();
1231 // This was just spawned from null, so it shouldn't panic.
1232 self.spawn_at_unchecked(entity, bundle, caller)
1233 }
1234
1235 /// Spawns a new [`Entity`] and returns a corresponding [`EntityWorldMut`], which can be used
1236 /// to add components to the entity or retrieve its id.
1237 ///
1238 /// ```
1239 /// use bevy_ecs::{component::Component, world::World};
1240 ///
1241 /// #[derive(Component)]
1242 /// struct Position {
1243 /// x: f32,
1244 /// y: f32,
1245 /// }
1246 /// #[derive(Component)]
1247 /// struct Label(&'static str);
1248 /// #[derive(Component)]
1249 /// struct Num(u32);
1250 ///
1251 /// let mut world = World::new();
1252 /// let entity = world.spawn_empty()
1253 /// .insert(Position { x: 0.0, y: 0.0 }) // add a single component
1254 /// .insert((Num(1), Label("hello"))) // add a bundle of components
1255 /// .id();
1256 ///
1257 /// let position = world.entity(entity).get::<Position>().unwrap();
1258 /// assert_eq!(position.x, 0.0);
1259 /// ```
1260 #[track_caller]
1261 pub fn spawn_empty(&mut self) -> EntityWorldMut<'_> {
1262 self.spawn_empty_with_caller(MaybeLocation::caller())
1263 }
1264
1265 pub(crate) fn spawn_empty_with_caller(&mut self, caller: MaybeLocation) -> EntityWorldMut<'_> {
1266 let entity = self.allocator.alloc();
1267 // This was just spawned from null, so it shouldn't panic.
1268 self.spawn_empty_at_unchecked(entity, caller)
1269 }
1270
1271 /// Spawns a batch of entities with the same component [`Bundle`] type. Takes a given
1272 /// [`Bundle`] iterator and returns a corresponding [`Entity`] iterator.
1273 /// This is more efficient than spawning entities and adding components to them individually
1274 /// using [`World::spawn`], but it is limited to spawning entities with the same [`Bundle`]
1275 /// type, whereas spawning individually is more flexible.
1276 ///
1277 /// ```
1278 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1279 ///
1280 /// #[derive(Component)]
1281 /// struct Str(&'static str);
1282 /// #[derive(Component)]
1283 /// struct Num(u32);
1284 ///
1285 /// let mut world = World::new();
1286 /// let entities = world.spawn_batch(vec![
1287 /// (Str("a"), Num(0)), // the first entity
1288 /// (Str("b"), Num(1)), // the second entity
1289 /// ]).collect::<Vec<Entity>>();
1290 ///
1291 /// assert_eq!(entities.len(), 2);
1292 /// ```
1293 #[track_caller]
1294 pub fn spawn_batch<I>(&mut self, iter: I) -> SpawnBatchIter<'_, I::IntoIter>
1295 where
1296 I: IntoIterator,
1297 I::Item: Bundle<Effect: NoBundleEffect>,
1298 {
1299 SpawnBatchIter::new(self, iter.into_iter(), MaybeLocation::caller())
1300 }
1301
1302 /// Retrieves a reference to the given `entity`'s [`Component`] of the given type.
1303 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
1304 /// ```
1305 /// use bevy_ecs::{component::Component, world::World};
1306 ///
1307 /// #[derive(Component)]
1308 /// struct Position {
1309 /// x: f32,
1310 /// y: f32,
1311 /// }
1312 ///
1313 /// let mut world = World::new();
1314 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
1315 /// let position = world.get::<Position>(entity).unwrap();
1316 /// assert_eq!(position.x, 0.0);
1317 /// ```
1318 #[inline]
1319 pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {
1320 self.get_entity(entity).ok()?.get()
1321 }
1322
1323 /// Retrieves a mutable reference to the given `entity`'s [`Component`] of the given type.
1324 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
1325 /// ```
1326 /// use bevy_ecs::{component::Component, world::World};
1327 ///
1328 /// #[derive(Component)]
1329 /// struct Position {
1330 /// x: f32,
1331 /// y: f32,
1332 /// }
1333 ///
1334 /// let mut world = World::new();
1335 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
1336 /// let mut position = world.get_mut::<Position>(entity).unwrap();
1337 /// position.x = 1.0;
1338 /// ```
1339 #[inline]
1340 pub fn get_mut<T: Component<Mutability = Mutable>>(
1341 &mut self,
1342 entity: Entity,
1343 ) -> Option<Mut<'_, T>> {
1344 self.get_entity_mut(entity).ok()?.into_mut()
1345 }
1346
1347 /// Temporarily removes a [`Component`] `T` from the provided [`Entity`] and
1348 /// runs the provided closure on it, returning the result if `T` was available.
1349 /// This will trigger the `Remove` and `Replace` component hooks without
1350 /// causing an archetype move.
1351 ///
1352 /// This is most useful with immutable components, where removal and reinsertion
1353 /// is the only way to modify a value.
1354 ///
1355 /// If you do not need to ensure the above hooks are triggered, and your component
1356 /// is mutable, prefer using [`get_mut`](World::get_mut).
1357 ///
1358 /// # Examples
1359 ///
1360 /// ```rust
1361 /// # use bevy_ecs::prelude::*;
1362 /// #
1363 /// #[derive(Component, PartialEq, Eq, Debug)]
1364 /// #[component(immutable)]
1365 /// struct Foo(bool);
1366 ///
1367 /// # let mut world = World::default();
1368 /// # world.register_component::<Foo>();
1369 /// #
1370 /// # let entity = world.spawn(Foo(false)).id();
1371 /// #
1372 /// world.modify_component(entity, |foo: &mut Foo| {
1373 /// foo.0 = true;
1374 /// });
1375 /// #
1376 /// # assert_eq!(world.get::<Foo>(entity), Some(&Foo(true)));
1377 /// ```
1378 #[inline]
1379 #[track_caller]
1380 pub fn modify_component<T: Component, R>(
1381 &mut self,
1382 entity: Entity,
1383 f: impl FnOnce(&mut T) -> R,
1384 ) -> Result<Option<R>, EntityMutableFetchError> {
1385 let mut world = DeferredWorld::from(&mut *self);
1386
1387 let result = world.modify_component_with_relationship_hook_mode(
1388 entity,
1389 RelationshipHookMode::Run,
1390 f,
1391 )?;
1392
1393 self.flush();
1394 Ok(result)
1395 }
1396
1397 /// Temporarily removes a [`Component`] identified by the provided
1398 /// [`ComponentId`] from the provided [`Entity`] and runs the provided
1399 /// closure on it, returning the result if the component was available.
1400 /// This will trigger the `Remove` and `Replace` component hooks without
1401 /// causing an archetype move.
1402 ///
1403 /// This is most useful with immutable components, where removal and reinsertion
1404 /// is the only way to modify a value.
1405 ///
1406 /// If you do not need to ensure the above hooks are triggered, and your component
1407 /// is mutable, prefer using [`get_mut_by_id`](World::get_mut_by_id).
1408 ///
1409 /// You should prefer the typed [`modify_component`](World::modify_component)
1410 /// whenever possible.
1411 #[inline]
1412 #[track_caller]
1413 pub fn modify_component_by_id<R>(
1414 &mut self,
1415 entity: Entity,
1416 component_id: ComponentId,
1417 f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,
1418 ) -> Result<Option<R>, EntityMutableFetchError> {
1419 let mut world = DeferredWorld::from(&mut *self);
1420
1421 let result = world.modify_component_by_id_with_relationship_hook_mode(
1422 entity,
1423 component_id,
1424 RelationshipHookMode::Run,
1425 f,
1426 )?;
1427
1428 self.flush();
1429 Ok(result)
1430 }
1431
1432 /// Despawns the given [`Entity`], if it exists.
1433 /// This will also remove all of the entity's [`Components`](Component).
1434 ///
1435 /// Returns `true` if the entity is successfully despawned and `false` if
1436 /// the entity does not exist.
1437 /// This counts despawning a not constructed entity as a success, and frees it to the allocator.
1438 /// See [entity](crate::entity) module docs for more about construction.
1439 ///
1440 /// # Note
1441 ///
1442 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
1443 /// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1444 ///
1445 /// ```
1446 /// use bevy_ecs::{component::Component, world::World};
1447 ///
1448 /// #[derive(Component)]
1449 /// struct Position {
1450 /// x: f32,
1451 /// y: f32,
1452 /// }
1453 ///
1454 /// let mut world = World::new();
1455 /// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
1456 /// assert!(world.despawn(entity));
1457 /// assert!(world.get_entity(entity).is_err());
1458 /// assert!(world.get::<Position>(entity).is_none());
1459 /// ```
1460 #[track_caller]
1461 #[inline]
1462 pub fn despawn(&mut self, entity: Entity) -> bool {
1463 if let Err(error) = self.despawn_with_caller(entity, MaybeLocation::caller()) {
1464 warn!("{error}");
1465 false
1466 } else {
1467 true
1468 }
1469 }
1470
1471 /// Despawns the given `entity`, if it exists. This will also remove all of the entity's
1472 /// [`Components`](Component).
1473 ///
1474 /// Returns an [`EntityDespawnError`] if the entity is not spawned to be despawned.
1475 ///
1476 /// # Note
1477 ///
1478 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
1479 /// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1480 #[track_caller]
1481 #[inline]
1482 pub fn try_despawn(&mut self, entity: Entity) -> Result<(), EntityDespawnError> {
1483 self.despawn_with_caller(entity, MaybeLocation::caller())
1484 }
1485
1486 #[inline]
1487 pub(crate) fn despawn_with_caller(
1488 &mut self,
1489 entity: Entity,
1490 caller: MaybeLocation,
1491 ) -> Result<(), EntityDespawnError> {
1492 match self.get_entity_mut(entity) {
1493 Ok(entity) => {
1494 entity.despawn_with_caller(caller);
1495 Ok(())
1496 }
1497 // Only one entity.
1498 Err(EntityMutableFetchError::AliasedMutability(_)) => unreachable!(),
1499 Err(EntityMutableFetchError::NotSpawned(err)) => Err(EntityDespawnError(err)),
1500 }
1501 }
1502
1503 /// Performs [`try_despawn_no_free`](Self::try_despawn_no_free), warning on errors.
1504 /// See that method for more information.
1505 #[track_caller]
1506 #[inline]
1507 pub fn despawn_no_free(&mut self, entity: Entity) -> Option<Entity> {
1508 match self.despawn_no_free_with_caller(entity, MaybeLocation::caller()) {
1509 Ok(entity) => Some(entity),
1510 Err(error) => {
1511 warn!("{error}");
1512 None
1513 }
1514 }
1515 }
1516
1517 /// Despawns the given `entity`, if it exists.
1518 /// This will also remove all of the entity's [`Component`]s.
1519 ///
1520 /// The *only* difference between this and [despawning](Self::despawn) an entity is that this does not release the `entity` to be reused.
1521 /// 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.
1522 /// In general, [`despawn`](Self::despawn) should be used instead, which automatically allows the row to be reused.
1523 ///
1524 /// Returns the new [`Entity`] if of the despawned [`EntityIndex`](crate::entity::EntityIndex), which should eventually either be re-spawned or freed to the allocator.
1525 /// Returns an [`EntityDespawnError`] if the entity is not spawned.
1526 ///
1527 /// # Note
1528 ///
1529 /// This will also *despawn* the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
1530 /// to despawn descendants. For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1531 ///
1532 /// # Example
1533 ///
1534 /// There is no simple example in which this would be practical, but one use for this is a custom entity allocator.
1535 /// Despawning internally calls this and frees the entity id to Bevy's default entity allocator.
1536 /// The same principal can be used to create custom allocators with additional properties.
1537 /// For example, this could be used to make an allocator that yields groups of consecutive [`EntityIndex`](crate::entity::EntityIndex)s, etc.
1538 /// See [`EntityAllocator::alloc`] for more on this.
1539 #[track_caller]
1540 #[inline]
1541 pub fn try_despawn_no_free(&mut self, entity: Entity) -> Result<Entity, EntityDespawnError> {
1542 self.despawn_no_free_with_caller(entity, MaybeLocation::caller())
1543 }
1544
1545 #[inline]
1546 pub(crate) fn despawn_no_free_with_caller(
1547 &mut self,
1548 entity: Entity,
1549 caller: MaybeLocation,
1550 ) -> Result<Entity, EntityDespawnError> {
1551 let mut entity = self.get_entity_mut(entity).map_err(|err| match err {
1552 EntityMutableFetchError::NotSpawned(err) => err,
1553 // Only one entity.
1554 EntityMutableFetchError::AliasedMutability(_) => unreachable!(),
1555 })?;
1556 entity.despawn_no_free_with_caller(caller);
1557 Ok(entity.id())
1558 }
1559
1560 /// Clears the internal component tracker state.
1561 ///
1562 /// The world maintains some internal state about changed and removed components. This state
1563 /// is used by [`RemovedComponents`] to provide access to the entities that had a specific type
1564 /// of component removed since last tick.
1565 ///
1566 /// The state is also used for change detection when accessing components and resources outside
1567 /// of a system, for example via [`World::get_mut()`] or [`World::get_resource_mut()`].
1568 ///
1569 /// By clearing this internal state, the world "forgets" about those changes, allowing a new round
1570 /// of detection to be recorded.
1571 ///
1572 /// When using `bevy_ecs` as part of the full Bevy engine, this method is called automatically
1573 /// by `bevy_app::App::update` and `bevy_app::SubApp::update`, so you don't need to call it manually.
1574 /// When using `bevy_ecs` as a separate standalone crate however, you do need to call this manually.
1575 ///
1576 /// ```
1577 /// # use bevy_ecs::prelude::*;
1578 /// # #[derive(Component, Default)]
1579 /// # struct Transform;
1580 /// // a whole new world
1581 /// let mut world = World::new();
1582 ///
1583 /// // you changed it
1584 /// let entity = world.spawn(Transform::default()).id();
1585 ///
1586 /// // change is detected
1587 /// let transform = world.get_mut::<Transform>(entity).unwrap();
1588 /// assert!(transform.is_changed());
1589 ///
1590 /// // update the last change tick
1591 /// world.clear_trackers();
1592 ///
1593 /// // change is no longer detected
1594 /// let transform = world.get_mut::<Transform>(entity).unwrap();
1595 /// assert!(!transform.is_changed());
1596 /// ```
1597 ///
1598 /// [`RemovedComponents`]: crate::lifecycle::RemovedComponents
1599 pub fn clear_trackers(&mut self) {
1600 self.removed_components.update();
1601 self.last_change_tick = self.increment_change_tick();
1602 }
1603
1604 /// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently
1605 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1606 /// ```
1607 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1608 ///
1609 /// #[derive(Component, Debug, PartialEq)]
1610 /// struct Position {
1611 /// x: f32,
1612 /// y: f32,
1613 /// }
1614 ///
1615 /// #[derive(Component)]
1616 /// struct Velocity {
1617 /// x: f32,
1618 /// y: f32,
1619 /// }
1620 ///
1621 /// let mut world = World::new();
1622 /// let entities = world.spawn_batch(vec![
1623 /// (Position { x: 0.0, y: 0.0}, Velocity { x: 1.0, y: 0.0 }),
1624 /// (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }),
1625 /// ]).collect::<Vec<Entity>>();
1626 ///
1627 /// let mut query = world.query::<(&mut Position, &Velocity)>();
1628 /// for (mut position, velocity) in query.iter_mut(&mut world) {
1629 /// position.x += velocity.x;
1630 /// position.y += velocity.y;
1631 /// }
1632 ///
1633 /// assert_eq!(world.get::<Position>(entities[0]).unwrap(), &Position { x: 1.0, y: 0.0 });
1634 /// assert_eq!(world.get::<Position>(entities[1]).unwrap(), &Position { x: 0.0, y: 1.0 });
1635 /// ```
1636 ///
1637 /// To iterate over entities in a deterministic order,
1638 /// sort the results of the query using the desired component as a key.
1639 /// Note that this requires fetching the whole result set from the query
1640 /// and allocation of a [`Vec`] to store it.
1641 ///
1642 /// ```
1643 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1644 ///
1645 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Debug)]
1646 /// struct Order(i32);
1647 /// #[derive(Component, PartialEq, Debug)]
1648 /// struct Label(&'static str);
1649 ///
1650 /// let mut world = World::new();
1651 /// let a = world.spawn((Order(2), Label("second"))).id();
1652 /// let b = world.spawn((Order(3), Label("third"))).id();
1653 /// let c = world.spawn((Order(1), Label("first"))).id();
1654 /// let mut entities = world.query::<(Entity, &Order, &Label)>()
1655 /// .iter(&world)
1656 /// .collect::<Vec<_>>();
1657 /// // Sort the query results by their `Order` component before comparing
1658 /// // to expected results. Query iteration order should not be relied on.
1659 /// entities.sort_by_key(|e| e.1);
1660 /// assert_eq!(entities, vec![
1661 /// (c, &Order(1), &Label("first")),
1662 /// (a, &Order(2), &Label("second")),
1663 /// (b, &Order(3), &Label("third")),
1664 /// ]);
1665 /// ```
1666 #[inline]
1667 pub fn query<D: QueryData>(&mut self) -> QueryState<D, ()> {
1668 self.query_filtered::<D, ()>()
1669 }
1670
1671 /// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently
1672 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1673 /// ```
1674 /// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};
1675 ///
1676 /// #[derive(Component)]
1677 /// struct A;
1678 /// #[derive(Component)]
1679 /// struct B;
1680 ///
1681 /// let mut world = World::new();
1682 /// let e1 = world.spawn(A).id();
1683 /// let e2 = world.spawn((A, B)).id();
1684 ///
1685 /// let mut query = world.query_filtered::<Entity, With<B>>();
1686 /// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();
1687 ///
1688 /// assert_eq!(matching_entities, vec![e2]);
1689 /// ```
1690 #[inline]
1691 pub fn query_filtered<D: QueryData, F: QueryFilter>(&mut self) -> QueryState<D, F> {
1692 QueryState::new(self)
1693 }
1694
1695 /// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently
1696 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1697 /// ```
1698 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1699 ///
1700 /// #[derive(Component, Debug, PartialEq)]
1701 /// struct Position {
1702 /// x: f32,
1703 /// y: f32,
1704 /// }
1705 ///
1706 /// let mut world = World::new();
1707 /// world.spawn_batch(vec![
1708 /// Position { x: 0.0, y: 0.0 },
1709 /// Position { x: 1.0, y: 1.0 },
1710 /// ]);
1711 ///
1712 /// fn get_positions(world: &World) -> Vec<(Entity, &Position)> {
1713 /// let mut query = world.try_query::<(Entity, &Position)>().unwrap();
1714 /// query.iter(world).collect()
1715 /// }
1716 ///
1717 /// let positions = get_positions(&world);
1718 ///
1719 /// assert_eq!(world.get::<Position>(positions[0].0).unwrap(), positions[0].1);
1720 /// assert_eq!(world.get::<Position>(positions[1].0).unwrap(), positions[1].1);
1721 /// ```
1722 ///
1723 /// Requires only an immutable world reference, but may fail if, for example,
1724 /// the components that make up this query have not been registered into the world.
1725 /// ```
1726 /// use bevy_ecs::{component::Component, entity::Entity, world::World};
1727 ///
1728 /// #[derive(Component)]
1729 /// struct A;
1730 ///
1731 /// let mut world = World::new();
1732 ///
1733 /// let none_query = world.try_query::<&A>();
1734 /// assert!(none_query.is_none());
1735 ///
1736 /// world.register_component::<A>();
1737 ///
1738 /// let some_query = world.try_query::<&A>();
1739 /// assert!(some_query.is_some());
1740 /// ```
1741 #[inline]
1742 pub fn try_query<D: QueryData>(&self) -> Option<QueryState<D, ()>> {
1743 self.try_query_filtered::<D, ()>()
1744 }
1745
1746 /// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently
1747 /// run queries on the [`World`] by storing and reusing the [`QueryState`].
1748 /// ```
1749 /// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};
1750 ///
1751 /// #[derive(Component)]
1752 /// struct A;
1753 /// #[derive(Component)]
1754 /// struct B;
1755 ///
1756 /// let mut world = World::new();
1757 /// let e1 = world.spawn(A).id();
1758 /// let e2 = world.spawn((A, B)).id();
1759 ///
1760 /// let mut query = world.try_query_filtered::<Entity, With<B>>().unwrap();
1761 /// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();
1762 ///
1763 /// assert_eq!(matching_entities, vec![e2]);
1764 /// ```
1765 ///
1766 /// Requires only an immutable world reference, but may fail if, for example,
1767 /// the components that make up this query have not been registered into the world.
1768 #[inline]
1769 pub fn try_query_filtered<D: QueryData, F: QueryFilter>(&self) -> Option<QueryState<D, F>> {
1770 QueryState::try_new(self)
1771 }
1772
1773 /// Returns an iterator of entities that had components of type `T` removed
1774 /// since the last call to [`World::clear_trackers`].
1775 pub fn removed<T: Component>(&self) -> impl Iterator<Item = Entity> + '_ {
1776 self.components
1777 .get_valid_id(TypeId::of::<T>())
1778 .map(|component_id| self.removed_with_id(component_id))
1779 .into_iter()
1780 .flatten()
1781 }
1782
1783 /// Returns an iterator of entities that had components with the given `component_id` removed
1784 /// since the last call to [`World::clear_trackers`].
1785 pub fn removed_with_id(&self, component_id: ComponentId) -> impl Iterator<Item = Entity> + '_ {
1786 self.removed_components
1787 .get(component_id)
1788 .map(|removed| removed.iter_current_update_messages().cloned())
1789 .into_iter()
1790 .flatten()
1791 .map(Into::into)
1792 }
1793
1794 /// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.
1795 ///
1796 /// This enables the dynamic registration of new [`Resource`] definitions at runtime for
1797 /// advanced use cases.
1798 ///
1799 /// # Note
1800 ///
1801 /// Registering a [`Resource`] does not insert it into [`World`]. For insertion, you could use
1802 /// [`World::insert_resource_by_id`].
1803 pub fn register_resource_with_descriptor(
1804 &mut self,
1805 descriptor: ComponentDescriptor,
1806 ) -> ComponentId {
1807 self.components_registrator()
1808 .register_resource_with_descriptor(descriptor)
1809 }
1810
1811 /// Initializes a new resource and returns the [`ComponentId`] created for it.
1812 ///
1813 /// If the resource already exists, nothing happens.
1814 ///
1815 /// The value given by the [`FromWorld::from_world`] method will be used.
1816 /// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],
1817 /// and those default values will be here instead.
1818 #[inline]
1819 #[track_caller]
1820 pub fn init_resource<R: Resource + FromWorld>(&mut self) -> ComponentId {
1821 let caller = MaybeLocation::caller();
1822 let component_id = self.components_registrator().register_resource::<R>();
1823 if self
1824 .storages
1825 .resources
1826 .get(component_id)
1827 .is_none_or(|data| !data.is_present())
1828 {
1829 let value = R::from_world(self);
1830 OwningPtr::make(value, |ptr| {
1831 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1832 unsafe {
1833 self.insert_resource_by_id(component_id, ptr, caller);
1834 }
1835 });
1836 }
1837 component_id
1838 }
1839
1840 /// Inserts a new resource with the given `value`.
1841 ///
1842 /// Resources are "unique" data of a given type.
1843 /// If you insert a resource of a type that already exists,
1844 /// you will overwrite any existing data.
1845 #[inline]
1846 #[track_caller]
1847 pub fn insert_resource<R: Resource>(&mut self, value: R) {
1848 self.insert_resource_with_caller(value, MaybeLocation::caller());
1849 }
1850
1851 /// Split into a new function so we can pass the calling location into the function when using
1852 /// as a command.
1853 #[inline]
1854 pub(crate) fn insert_resource_with_caller<R: Resource>(
1855 &mut self,
1856 value: R,
1857 caller: MaybeLocation,
1858 ) {
1859 let component_id = self.components_registrator().register_resource::<R>();
1860 OwningPtr::make(value, |ptr| {
1861 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1862 unsafe {
1863 self.insert_resource_by_id(component_id, ptr, caller);
1864 }
1865 });
1866 }
1867
1868 /// Initializes a new non-send resource and returns the [`ComponentId`] created for it.
1869 ///
1870 /// If the resource already exists, nothing happens.
1871 ///
1872 /// The value given by the [`FromWorld::from_world`] method will be used.
1873 /// Note that any resource with the `Default` trait automatically implements `FromWorld`,
1874 /// and those default values will be here instead.
1875 ///
1876 /// # Panics
1877 ///
1878 /// Panics if called from a thread other than the main thread.
1879 #[inline]
1880 #[track_caller]
1881 pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> ComponentId {
1882 let caller = MaybeLocation::caller();
1883 let component_id = self.components_registrator().register_non_send::<R>();
1884 if self
1885 .storages
1886 .non_send_resources
1887 .get(component_id)
1888 .is_none_or(|data| !data.is_present())
1889 {
1890 let value = R::from_world(self);
1891 OwningPtr::make(value, |ptr| {
1892 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1893 unsafe {
1894 self.insert_non_send_by_id(component_id, ptr, caller);
1895 }
1896 });
1897 }
1898 component_id
1899 }
1900
1901 /// Inserts a new non-send resource with the given `value`.
1902 ///
1903 /// `NonSend` resources cannot be sent across threads,
1904 /// and do not need the `Send + Sync` bounds.
1905 /// Systems with `NonSend` resources are always scheduled on the main thread.
1906 ///
1907 /// # Panics
1908 /// If a value is already present, this function will panic if called
1909 /// from a different thread than where the original value was inserted from.
1910 #[inline]
1911 #[track_caller]
1912 pub fn insert_non_send_resource<R: 'static>(&mut self, value: R) {
1913 let caller = MaybeLocation::caller();
1914 let component_id = self.components_registrator().register_non_send::<R>();
1915 OwningPtr::make(value, |ptr| {
1916 // SAFETY: component_id was just initialized and corresponds to resource of type R.
1917 unsafe {
1918 self.insert_non_send_by_id(component_id, ptr, caller);
1919 }
1920 });
1921 }
1922
1923 /// Removes the resource of a given type and returns it, if it exists. Otherwise returns `None`.
1924 #[inline]
1925 pub fn remove_resource<R: Resource>(&mut self) -> Option<R> {
1926 let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;
1927 let (ptr, _, _) = self.storages.resources.get_mut(component_id)?.remove()?;
1928 // SAFETY: `component_id` was gotten via looking up the `R` type
1929 unsafe { Some(ptr.read::<R>()) }
1930 }
1931
1932 /// Removes a `!Send` resource from the world and returns it, if present.
1933 ///
1934 /// `NonSend` resources cannot be sent across threads,
1935 /// and do not need the `Send + Sync` bounds.
1936 /// Systems with `NonSend` resources are always scheduled on the main thread.
1937 ///
1938 /// Returns `None` if a value was not previously present.
1939 ///
1940 /// # Panics
1941 /// If a value is present, this function will panic if called from a different
1942 /// thread than where the value was inserted from.
1943 #[inline]
1944 pub fn remove_non_send_resource<R: 'static>(&mut self) -> Option<R> {
1945 let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;
1946 let (ptr, _, _) = self
1947 .storages
1948 .non_send_resources
1949 .get_mut(component_id)?
1950 .remove()?;
1951 // SAFETY: `component_id` was gotten via looking up the `R` type
1952 unsafe { Some(ptr.read::<R>()) }
1953 }
1954
1955 /// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.
1956 #[inline]
1957 pub fn contains_resource<R: Resource>(&self) -> bool {
1958 self.components
1959 .get_valid_resource_id(TypeId::of::<R>())
1960 .and_then(|component_id| self.storages.resources.get(component_id))
1961 .is_some_and(ResourceData::is_present)
1962 }
1963
1964 /// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.
1965 #[inline]
1966 pub fn contains_resource_by_id(&self, component_id: ComponentId) -> bool {
1967 self.storages
1968 .resources
1969 .get(component_id)
1970 .is_some_and(ResourceData::is_present)
1971 }
1972
1973 /// Returns `true` if a resource of type `R` exists. Otherwise returns `false`.
1974 #[inline]
1975 pub fn contains_non_send<R: 'static>(&self) -> bool {
1976 self.components
1977 .get_valid_resource_id(TypeId::of::<R>())
1978 .and_then(|component_id| self.storages.non_send_resources.get(component_id))
1979 .is_some_and(ResourceData::is_present)
1980 }
1981
1982 /// Returns `true` if a resource with provided `component_id` exists. Otherwise returns `false`.
1983 #[inline]
1984 pub fn contains_non_send_by_id(&self, component_id: ComponentId) -> bool {
1985 self.storages
1986 .non_send_resources
1987 .get(component_id)
1988 .is_some_and(ResourceData::is_present)
1989 }
1990
1991 /// Returns `true` if a resource of type `R` exists and was added since the world's
1992 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
1993 ///
1994 /// This means that:
1995 /// - When called from an exclusive system, this will check for additions since the system last ran.
1996 /// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]
1997 /// was called.
1998 pub fn is_resource_added<R: Resource>(&self) -> bool {
1999 self.components
2000 .get_valid_resource_id(TypeId::of::<R>())
2001 .is_some_and(|component_id| self.is_resource_added_by_id(component_id))
2002 }
2003
2004 /// Returns `true` if a resource with id `component_id` exists and was added since the world's
2005 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
2006 ///
2007 /// This means that:
2008 /// - When called from an exclusive system, this will check for additions since the system last ran.
2009 /// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]
2010 /// was called.
2011 pub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool {
2012 self.storages
2013 .resources
2014 .get(component_id)
2015 .is_some_and(|resource| {
2016 resource.get_ticks().is_some_and(|ticks| {
2017 ticks.is_added(self.last_change_tick(), self.read_change_tick())
2018 })
2019 })
2020 }
2021
2022 /// Returns `true` if a resource of type `R` exists and was modified since the world's
2023 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
2024 ///
2025 /// This means that:
2026 /// - When called from an exclusive system, this will check for changes since the system last ran.
2027 /// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]
2028 /// was called.
2029 pub fn is_resource_changed<R: Resource>(&self) -> bool {
2030 self.components
2031 .get_valid_resource_id(TypeId::of::<R>())
2032 .is_some_and(|component_id| self.is_resource_changed_by_id(component_id))
2033 }
2034
2035 /// Returns `true` if a resource with id `component_id` exists and was modified since the world's
2036 /// [`last_change_tick`](World::last_change_tick()). Otherwise, this returns `false`.
2037 ///
2038 /// This means that:
2039 /// - When called from an exclusive system, this will check for changes since the system last ran.
2040 /// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]
2041 /// was called.
2042 pub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool {
2043 self.storages
2044 .resources
2045 .get(component_id)
2046 .is_some_and(|resource| {
2047 resource.get_ticks().is_some_and(|ticks| {
2048 ticks.is_changed(self.last_change_tick(), self.read_change_tick())
2049 })
2050 })
2051 }
2052
2053 /// Retrieves the change ticks for the given resource.
2054 pub fn get_resource_change_ticks<R: Resource>(&self) -> Option<ComponentTicks> {
2055 self.components
2056 .get_valid_resource_id(TypeId::of::<R>())
2057 .and_then(|component_id| self.get_resource_change_ticks_by_id(component_id))
2058 }
2059
2060 /// Retrieves the change ticks for the given [`ComponentId`].
2061 ///
2062 /// **You should prefer to use the typed API [`World::get_resource_change_ticks`] where possible.**
2063 pub fn get_resource_change_ticks_by_id(
2064 &self,
2065 component_id: ComponentId,
2066 ) -> Option<ComponentTicks> {
2067 self.storages
2068 .resources
2069 .get(component_id)
2070 .and_then(ResourceData::get_ticks)
2071 }
2072
2073 /// Gets a reference to the resource of the given type
2074 ///
2075 /// # Panics
2076 ///
2077 /// Panics if the resource does not exist.
2078 /// Use [`get_resource`](World::get_resource) instead if you want to handle this case.
2079 ///
2080 /// If you want to instead insert a value if the resource does not exist,
2081 /// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
2082 #[inline]
2083 #[track_caller]
2084 pub fn resource<R: Resource>(&self) -> &R {
2085 match self.get_resource() {
2086 Some(x) => x,
2087 None => panic!(
2088 "Requested resource {} does not exist in the `World`.
2089 Did you forget to add it using `app.insert_resource` / `app.init_resource`?
2090 Resources are also implicitly added via `app.add_message`,
2091 and can be added by plugins.",
2092 DebugName::type_name::<R>()
2093 ),
2094 }
2095 }
2096
2097 /// Gets a reference to the resource of the given type
2098 ///
2099 /// # Panics
2100 ///
2101 /// Panics if the resource does not exist.
2102 /// Use [`get_resource_ref`](World::get_resource_ref) instead if you want to handle this case.
2103 ///
2104 /// If you want to instead insert a value if the resource does not exist,
2105 /// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
2106 #[inline]
2107 #[track_caller]
2108 pub fn resource_ref<R: Resource>(&self) -> Ref<'_, R> {
2109 match self.get_resource_ref() {
2110 Some(x) => x,
2111 None => panic!(
2112 "Requested resource {} does not exist in the `World`.
2113 Did you forget to add it using `app.insert_resource` / `app.init_resource`?
2114 Resources are also implicitly added via `app.add_message`,
2115 and can be added by plugins.",
2116 DebugName::type_name::<R>()
2117 ),
2118 }
2119 }
2120
2121 /// Gets a mutable reference to the resource of the given type
2122 ///
2123 /// # Panics
2124 ///
2125 /// Panics if the resource does not exist.
2126 /// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.
2127 ///
2128 /// If you want to instead insert a value if the resource does not exist,
2129 /// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
2130 #[inline]
2131 #[track_caller]
2132 pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {
2133 match self.get_resource_mut() {
2134 Some(x) => x,
2135 None => panic!(
2136 "Requested resource {} does not exist in the `World`.
2137 Did you forget to add it using `app.insert_resource` / `app.init_resource`?
2138 Resources are also implicitly added via `app.add_message`,
2139 and can be added by plugins.",
2140 DebugName::type_name::<R>()
2141 ),
2142 }
2143 }
2144
2145 /// Gets a reference to the resource of the given type if it exists
2146 #[inline]
2147 pub fn get_resource<R: Resource>(&self) -> Option<&R> {
2148 // SAFETY:
2149 // - `as_unsafe_world_cell_readonly` gives permission to access everything immutably
2150 // - `&self` ensures nothing in world is borrowed mutably
2151 unsafe { self.as_unsafe_world_cell_readonly().get_resource() }
2152 }
2153
2154 /// Gets a reference including change detection to the resource of the given type if it exists.
2155 #[inline]
2156 pub fn get_resource_ref<R: Resource>(&self) -> Option<Ref<'_, R>> {
2157 // SAFETY:
2158 // - `as_unsafe_world_cell_readonly` gives permission to access everything immutably
2159 // - `&self` ensures nothing in world is borrowed mutably
2160 unsafe { self.as_unsafe_world_cell_readonly().get_resource_ref() }
2161 }
2162
2163 /// Gets a mutable reference to the resource of the given type if it exists
2164 #[inline]
2165 pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {
2166 // SAFETY:
2167 // - `as_unsafe_world_cell` gives permission to access everything mutably
2168 // - `&mut self` ensures nothing in world is borrowed
2169 unsafe { self.as_unsafe_world_cell().get_resource_mut() }
2170 }
2171
2172 /// Gets a mutable reference to the resource of type `T` if it exists,
2173 /// otherwise inserts the resource using the result of calling `func`.
2174 ///
2175 /// # Example
2176 ///
2177 /// ```
2178 /// # use bevy_ecs::prelude::*;
2179 /// #
2180 /// #[derive(Resource)]
2181 /// struct MyResource(i32);
2182 ///
2183 /// # let mut world = World::new();
2184 /// let my_res = world.get_resource_or_insert_with(|| MyResource(10));
2185 /// assert_eq!(my_res.0, 10);
2186 /// ```
2187 #[inline]
2188 #[track_caller]
2189 pub fn get_resource_or_insert_with<R: Resource>(
2190 &mut self,
2191 func: impl FnOnce() -> R,
2192 ) -> Mut<'_, R> {
2193 let caller = MaybeLocation::caller();
2194 let change_tick = self.change_tick();
2195 let last_change_tick = self.last_change_tick();
2196
2197 let component_id = self.components_registrator().register_resource::<R>();
2198 let data = self.initialize_resource_internal(component_id);
2199 if !data.is_present() {
2200 OwningPtr::make(func(), |ptr| {
2201 // SAFETY: component_id was just initialized and corresponds to resource of type R.
2202 unsafe {
2203 data.insert(ptr, change_tick, caller);
2204 }
2205 });
2206 }
2207
2208 // SAFETY: The resource must be present, as we would have inserted it if it was empty.
2209 let data = unsafe {
2210 data.get_mut(last_change_tick, change_tick)
2211 .debug_checked_unwrap()
2212 };
2213 // SAFETY: The underlying type of the resource is `R`.
2214 unsafe { data.with_type::<R>() }
2215 }
2216
2217 /// Gets a mutable reference to the resource of type `T` if it exists,
2218 /// otherwise initializes the resource by calling its [`FromWorld`]
2219 /// implementation.
2220 ///
2221 /// # Example
2222 ///
2223 /// ```
2224 /// # use bevy_ecs::prelude::*;
2225 /// #
2226 /// #[derive(Resource)]
2227 /// struct Foo(i32);
2228 ///
2229 /// impl Default for Foo {
2230 /// fn default() -> Self {
2231 /// Self(15)
2232 /// }
2233 /// }
2234 ///
2235 /// #[derive(Resource)]
2236 /// struct MyResource(i32);
2237 ///
2238 /// impl FromWorld for MyResource {
2239 /// fn from_world(world: &mut World) -> Self {
2240 /// let foo = world.get_resource_or_init::<Foo>();
2241 /// Self(foo.0 * 2)
2242 /// }
2243 /// }
2244 ///
2245 /// # let mut world = World::new();
2246 /// let my_res = world.get_resource_or_init::<MyResource>();
2247 /// assert_eq!(my_res.0, 30);
2248 /// ```
2249 #[track_caller]
2250 pub fn get_resource_or_init<R: Resource + FromWorld>(&mut self) -> Mut<'_, R> {
2251 let caller = MaybeLocation::caller();
2252 let change_tick = self.change_tick();
2253 let last_change_tick = self.last_change_tick();
2254
2255 let component_id = self.components_registrator().register_resource::<R>();
2256 if self
2257 .storages
2258 .resources
2259 .get(component_id)
2260 .is_none_or(|data| !data.is_present())
2261 {
2262 let value = R::from_world(self);
2263 OwningPtr::make(value, |ptr| {
2264 // SAFETY: component_id was just initialized and corresponds to resource of type R.
2265 unsafe {
2266 self.insert_resource_by_id(component_id, ptr, caller);
2267 }
2268 });
2269 }
2270
2271 // SAFETY: The resource was just initialized if it was empty.
2272 let data = unsafe {
2273 self.storages
2274 .resources
2275 .get_mut(component_id)
2276 .debug_checked_unwrap()
2277 };
2278 // SAFETY: The resource must be present, as we would have inserted it if it was empty.
2279 let data = unsafe {
2280 data.get_mut(last_change_tick, change_tick)
2281 .debug_checked_unwrap()
2282 };
2283 // SAFETY: The underlying type of the resource is `R`.
2284 unsafe { data.with_type::<R>() }
2285 }
2286
2287 /// Gets an immutable reference to the non-send resource of the given type, if it exists.
2288 ///
2289 /// # Panics
2290 ///
2291 /// Panics if the resource does not exist.
2292 /// Use [`get_non_send_resource`](World::get_non_send_resource) instead if you want to handle this case.
2293 ///
2294 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2295 #[inline]
2296 #[track_caller]
2297 pub fn non_send_resource<R: 'static>(&self) -> &R {
2298 match self.get_non_send_resource() {
2299 Some(x) => x,
2300 None => panic!(
2301 "Requested non-send resource {} does not exist in the `World`.
2302 Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?
2303 Non-send resources can also be added by plugins.",
2304 DebugName::type_name::<R>()
2305 ),
2306 }
2307 }
2308
2309 /// Gets a mutable reference to the non-send resource of the given type, if it exists.
2310 ///
2311 /// # Panics
2312 ///
2313 /// Panics if the resource does not exist.
2314 /// Use [`get_non_send_resource_mut`](World::get_non_send_resource_mut) instead if you want to handle this case.
2315 ///
2316 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2317 #[inline]
2318 #[track_caller]
2319 pub fn non_send_resource_mut<R: 'static>(&mut self) -> Mut<'_, R> {
2320 match self.get_non_send_resource_mut() {
2321 Some(x) => x,
2322 None => panic!(
2323 "Requested non-send resource {} does not exist in the `World`.
2324 Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?
2325 Non-send resources can also be added by plugins.",
2326 DebugName::type_name::<R>()
2327 ),
2328 }
2329 }
2330
2331 /// Gets a reference to the non-send resource of the given type, if it exists.
2332 /// Otherwise returns `None`.
2333 ///
2334 /// # Panics
2335 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2336 #[inline]
2337 pub fn get_non_send_resource<R: 'static>(&self) -> Option<&R> {
2338 // SAFETY:
2339 // - `as_unsafe_world_cell_readonly` gives permission to access the entire world immutably
2340 // - `&self` ensures that there are no mutable borrows of world data
2341 unsafe { self.as_unsafe_world_cell_readonly().get_non_send_resource() }
2342 }
2343
2344 /// Gets a mutable reference to the non-send resource of the given type, if it exists.
2345 /// Otherwise returns `None`.
2346 ///
2347 /// # Panics
2348 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
2349 #[inline]
2350 pub fn get_non_send_resource_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {
2351 // SAFETY:
2352 // - `as_unsafe_world_cell` gives permission to access the entire world mutably
2353 // - `&mut self` ensures that there are no borrows of world data
2354 unsafe { self.as_unsafe_world_cell().get_non_send_resource_mut() }
2355 }
2356
2357 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2358 /// adds the `Bundle` of components to each `Entity`.
2359 /// This is faster than doing equivalent operations one-by-one.
2360 ///
2361 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2362 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2363 ///
2364 /// This will overwrite any previous values of components shared by the `Bundle`.
2365 /// See [`World::insert_batch_if_new`] to keep the old values instead.
2366 ///
2367 /// # Panics
2368 ///
2369 /// This function will panic if any of the associated entities do not exist.
2370 ///
2371 /// For the fallible version, see [`World::try_insert_batch`].
2372 #[track_caller]
2373 pub fn insert_batch<I, B>(&mut self, batch: I)
2374 where
2375 I: IntoIterator,
2376 I::IntoIter: Iterator<Item = (Entity, B)>,
2377 B: Bundle<Effect: NoBundleEffect>,
2378 {
2379 self.insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller());
2380 }
2381
2382 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2383 /// adds the `Bundle` of components to each `Entity` without overwriting.
2384 /// This is faster than doing equivalent operations one-by-one.
2385 ///
2386 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2387 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2388 ///
2389 /// This is the same as [`World::insert_batch`], but in case of duplicate
2390 /// components it will leave the old values instead of replacing them with new ones.
2391 ///
2392 /// # Panics
2393 ///
2394 /// This function will panic if any of the associated entities do not exist.
2395 ///
2396 /// For the fallible version, see [`World::try_insert_batch_if_new`].
2397 #[track_caller]
2398 pub fn insert_batch_if_new<I, B>(&mut self, batch: I)
2399 where
2400 I: IntoIterator,
2401 I::IntoIter: Iterator<Item = (Entity, B)>,
2402 B: Bundle<Effect: NoBundleEffect>,
2403 {
2404 self.insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller());
2405 }
2406
2407 /// Split into a new function so we can differentiate the calling location.
2408 ///
2409 /// This can be called by:
2410 /// - [`World::insert_batch`]
2411 /// - [`World::insert_batch_if_new`]
2412 #[inline]
2413 pub(crate) fn insert_batch_with_caller<I, B>(
2414 &mut self,
2415 batch: I,
2416 insert_mode: InsertMode,
2417 caller: MaybeLocation,
2418 ) where
2419 I: IntoIterator,
2420 I::IntoIter: Iterator<Item = (Entity, B)>,
2421 B: Bundle<Effect: NoBundleEffect>,
2422 {
2423 struct InserterArchetypeCache<'w> {
2424 inserter: BundleInserter<'w>,
2425 archetype_id: ArchetypeId,
2426 }
2427
2428 let change_tick = self.change_tick();
2429 let bundle_id = self.register_bundle_info::<B>();
2430
2431 let mut batch_iter = batch.into_iter();
2432
2433 if let Some((first_entity, first_bundle)) = batch_iter.next() {
2434 match self.entities().get_spawned(first_entity) {
2435 Err(err) => {
2436 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>());
2437 }
2438 Ok(first_location) => {
2439 let mut cache = InserterArchetypeCache {
2440 // SAFETY: we initialized this bundle_id in `register_info`
2441 inserter: unsafe {
2442 BundleInserter::new_with_id(
2443 self,
2444 first_location.archetype_id,
2445 bundle_id,
2446 change_tick,
2447 )
2448 },
2449 archetype_id: first_location.archetype_id,
2450 };
2451 move_as_ptr!(first_bundle);
2452 // SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter
2453 unsafe {
2454 cache.inserter.insert(
2455 first_entity,
2456 first_location,
2457 first_bundle,
2458 insert_mode,
2459 caller,
2460 RelationshipHookMode::Run,
2461 )
2462 };
2463
2464 for (entity, bundle) in batch_iter {
2465 match cache.inserter.entities().get_spawned(entity) {
2466 Ok(location) => {
2467 if location.archetype_id != cache.archetype_id {
2468 cache = InserterArchetypeCache {
2469 // SAFETY: we initialized this bundle_id in `register_info`
2470 inserter: unsafe {
2471 BundleInserter::new_with_id(
2472 self,
2473 location.archetype_id,
2474 bundle_id,
2475 change_tick,
2476 )
2477 },
2478 archetype_id: location.archetype_id,
2479 }
2480 }
2481 move_as_ptr!(bundle);
2482 // SAFETY: `entity` is valid, `location` matches entity, bundle matches inserter
2483 unsafe {
2484 cache.inserter.insert(
2485 entity,
2486 location,
2487 bundle,
2488 insert_mode,
2489 caller,
2490 RelationshipHookMode::Run,
2491 )
2492 };
2493 }
2494 Err(err) => {
2495 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>());
2496 }
2497 }
2498 }
2499 }
2500 }
2501 }
2502 }
2503
2504 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2505 /// adds the `Bundle` of components to each `Entity`.
2506 /// This is faster than doing equivalent operations one-by-one.
2507 ///
2508 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2509 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2510 ///
2511 /// This will overwrite any previous values of components shared by the `Bundle`.
2512 /// See [`World::try_insert_batch_if_new`] to keep the old values instead.
2513 ///
2514 /// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.
2515 ///
2516 /// For the panicking version, see [`World::insert_batch`].
2517 #[track_caller]
2518 pub fn try_insert_batch<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>
2519 where
2520 I: IntoIterator,
2521 I::IntoIter: Iterator<Item = (Entity, B)>,
2522 B: Bundle<Effect: NoBundleEffect>,
2523 {
2524 self.try_insert_batch_with_caller(batch, InsertMode::Replace, MaybeLocation::caller())
2525 }
2526 /// For a given batch of ([`Entity`], [`Bundle`]) pairs,
2527 /// adds the `Bundle` of components to each `Entity` without overwriting.
2528 /// This is faster than doing equivalent operations one-by-one.
2529 ///
2530 /// A batch can be any type that implements [`IntoIterator`] containing `(Entity, Bundle)` tuples,
2531 /// such as a [`Vec<(Entity, Bundle)>`] or an array `[(Entity, Bundle); N]`.
2532 ///
2533 /// This is the same as [`World::try_insert_batch`], but in case of duplicate
2534 /// components it will leave the old values instead of replacing them with new ones.
2535 ///
2536 /// Returns a [`TryInsertBatchError`] if any of the provided entities do not exist.
2537 ///
2538 /// For the panicking version, see [`World::insert_batch_if_new`].
2539 #[track_caller]
2540 pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I) -> Result<(), TryInsertBatchError>
2541 where
2542 I: IntoIterator,
2543 I::IntoIter: Iterator<Item = (Entity, B)>,
2544 B: Bundle<Effect: NoBundleEffect>,
2545 {
2546 self.try_insert_batch_with_caller(batch, InsertMode::Keep, MaybeLocation::caller())
2547 }
2548
2549 /// Split into a new function so we can differentiate the calling location.
2550 ///
2551 /// This can be called by:
2552 /// - [`World::try_insert_batch`]
2553 /// - [`World::try_insert_batch_if_new`]
2554 /// - [`Commands::insert_batch`]
2555 /// - [`Commands::insert_batch_if_new`]
2556 /// - [`Commands::try_insert_batch`]
2557 /// - [`Commands::try_insert_batch_if_new`]
2558 #[inline]
2559 pub(crate) fn try_insert_batch_with_caller<I, B>(
2560 &mut self,
2561 batch: I,
2562 insert_mode: InsertMode,
2563 caller: MaybeLocation,
2564 ) -> Result<(), TryInsertBatchError>
2565 where
2566 I: IntoIterator,
2567 I::IntoIter: Iterator<Item = (Entity, B)>,
2568 B: Bundle<Effect: NoBundleEffect>,
2569 {
2570 struct InserterArchetypeCache<'w> {
2571 inserter: BundleInserter<'w>,
2572 archetype_id: ArchetypeId,
2573 }
2574
2575 let change_tick = self.change_tick();
2576 let bundle_id = self.register_bundle_info::<B>();
2577
2578 let mut invalid_entities = Vec::<Entity>::new();
2579 let mut batch_iter = batch.into_iter();
2580
2581 // We need to find the first valid entity so we can initialize the bundle inserter.
2582 // This differs from `insert_batch_with_caller` because that method can just panic
2583 // if the first entity is invalid, whereas this method needs to keep going.
2584 let cache = loop {
2585 if let Some((first_entity, first_bundle)) = batch_iter.next() {
2586 if let Ok(first_location) = self.entities().get_spawned(first_entity) {
2587 let mut cache = InserterArchetypeCache {
2588 // SAFETY: we initialized this bundle_id in `register_bundle_info`
2589 inserter: unsafe {
2590 BundleInserter::new_with_id(
2591 self,
2592 first_location.archetype_id,
2593 bundle_id,
2594 change_tick,
2595 )
2596 },
2597 archetype_id: first_location.archetype_id,
2598 };
2599
2600 move_as_ptr!(first_bundle);
2601 // SAFETY:
2602 // - `entity` is valid, `location` matches entity, bundle matches inserter
2603 // - `apply_effect` is never called on this bundle.
2604 // - `first_bundle` is not be accessed or dropped after this.
2605 unsafe {
2606 cache.inserter.insert(
2607 first_entity,
2608 first_location,
2609 first_bundle,
2610 insert_mode,
2611 caller,
2612 RelationshipHookMode::Run,
2613 )
2614 };
2615 break Some(cache);
2616 }
2617 invalid_entities.push(first_entity);
2618 } else {
2619 // We reached the end of the entities the caller provided and none were valid.
2620 break None;
2621 }
2622 };
2623
2624 if let Some(mut cache) = cache {
2625 for (entity, bundle) in batch_iter {
2626 if let Ok(location) = cache.inserter.entities().get_spawned(entity) {
2627 if location.archetype_id != cache.archetype_id {
2628 cache = InserterArchetypeCache {
2629 // SAFETY: we initialized this bundle_id in `register_info`
2630 inserter: unsafe {
2631 BundleInserter::new_with_id(
2632 self,
2633 location.archetype_id,
2634 bundle_id,
2635 change_tick,
2636 )
2637 },
2638 archetype_id: location.archetype_id,
2639 }
2640 }
2641
2642 move_as_ptr!(bundle);
2643 // SAFETY:
2644 // - `entity` is valid, `location` matches entity, bundle matches inserter
2645 // - `apply_effect` is never called on this bundle.
2646 // - `bundle` is not be accessed or dropped after this.
2647 unsafe {
2648 cache.inserter.insert(
2649 entity,
2650 location,
2651 bundle,
2652 insert_mode,
2653 caller,
2654 RelationshipHookMode::Run,
2655 )
2656 };
2657 } else {
2658 invalid_entities.push(entity);
2659 }
2660 }
2661 }
2662
2663 if invalid_entities.is_empty() {
2664 Ok(())
2665 } else {
2666 Err(TryInsertBatchError {
2667 bundle_type: DebugName::type_name::<B>(),
2668 entities: invalid_entities,
2669 })
2670 }
2671 }
2672
2673 /// Temporarily removes the requested resource from this [`World`], runs custom user code,
2674 /// then re-adds the resource before returning.
2675 ///
2676 /// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].
2677 /// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).
2678 ///
2679 /// # Panics
2680 ///
2681 /// Panics if the resource does not exist.
2682 /// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.
2683 ///
2684 /// # Example
2685 /// ```
2686 /// use bevy_ecs::prelude::*;
2687 /// #[derive(Resource)]
2688 /// struct A(u32);
2689 /// #[derive(Component)]
2690 /// struct B(u32);
2691 /// let mut world = World::new();
2692 /// world.insert_resource(A(1));
2693 /// let entity = world.spawn(B(1)).id();
2694 ///
2695 /// world.resource_scope(|world, mut a: Mut<A>| {
2696 /// let b = world.get_mut::<B>(entity).unwrap();
2697 /// a.0 += b.0;
2698 /// });
2699 /// assert_eq!(world.get_resource::<A>().unwrap().0, 2);
2700 /// ```
2701 #[track_caller]
2702 pub fn resource_scope<R: Resource, U>(&mut self, f: impl FnOnce(&mut World, Mut<R>) -> U) -> U {
2703 self.try_resource_scope(f)
2704 .unwrap_or_else(|| panic!("resource does not exist: {}", DebugName::type_name::<R>()))
2705 }
2706
2707 /// Temporarily removes the requested resource from this [`World`] if it exists, runs custom user code,
2708 /// then re-adds the resource before returning. Returns `None` if the resource does not exist in this [`World`].
2709 ///
2710 /// This enables safe simultaneous mutable access to both a resource and the rest of the [`World`].
2711 /// For more complex access patterns, consider using [`SystemState`](crate::system::SystemState).
2712 ///
2713 /// See also [`resource_scope`](Self::resource_scope).
2714 pub fn try_resource_scope<R: Resource, U>(
2715 &mut self,
2716 f: impl FnOnce(&mut World, Mut<R>) -> U,
2717 ) -> Option<U> {
2718 let last_change_tick = self.last_change_tick();
2719 let change_tick = self.change_tick();
2720
2721 let component_id = self.components.get_valid_resource_id(TypeId::of::<R>())?;
2722 let (ptr, ticks, caller) = self.storages.resources.get_mut(component_id)?.remove()?;
2723
2724 // Read the value onto the stack to avoid potential mut aliasing.
2725 // SAFETY: `ptr` was obtained from the TypeId of `R`.
2726 let value = unsafe { ptr.read::<R>() };
2727
2728 // type used to manage reinserting the resource at the end of the scope. use of a drop impl means that
2729 // the resource is inserted even if the user-provided closure unwinds.
2730 // this facilitates localized panic recovery and makes app shutdown in response to a panic more graceful
2731 // by avoiding knock-on errors.
2732 struct ReinsertGuard<'a, R> {
2733 world: &'a mut World,
2734 component_id: ComponentId,
2735 value: ManuallyDrop<R>,
2736 ticks: ComponentTicks,
2737 caller: MaybeLocation,
2738 was_successful: &'a mut bool,
2739 }
2740 impl<R> Drop for ReinsertGuard<'_, R> {
2741 fn drop(&mut self) {
2742 // take ownership of the value first so it'll get dropped if we return early
2743 // SAFETY: drop semantics ensure that `self.value` will never be accessed again after this call
2744 let value = unsafe { ManuallyDrop::take(&mut self.value) };
2745
2746 let Some(resource_data) = self.world.storages.resources.get_mut(self.component_id)
2747 else {
2748 return;
2749 };
2750
2751 // in debug mode, raise a panic if user code re-inserted a resource of this type within the scope.
2752 // resource insertion usually indicates a logic error in user code, which is useful to catch at dev time,
2753 // however it does not inherently lead to corrupted state, so we avoid introducing an unnecessary crash
2754 // for production builds.
2755 if resource_data.is_present() {
2756 #[cfg(debug_assertions)]
2757 {
2758 // if we're already panicking, log an error instead of panicking, as double-panics result in an abort
2759 #[cfg(feature = "std")]
2760 if std::thread::panicking() {
2761 log::error!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\
2762 In release builds, the value inserted will be overwritten at the end of the scope.",
2763 DebugName::type_name::<R>());
2764 // return early to maintain consistent behavior with non-panicking calls in debug builds
2765 return;
2766 }
2767
2768 panic!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\
2769 In release builds, the value inserted will be overwritten at the end of the scope.",
2770 DebugName::type_name::<R>());
2771 }
2772 #[cfg(not(debug_assertions))]
2773 {
2774 #[cold]
2775 #[inline(never)]
2776 fn warn_reinsert(resource_name: &str) {
2777 warn!(
2778 "Resource `{resource_name}` was inserted during a call to World::resource_scope: the inserted value will be overwritten.",
2779 );
2780 }
2781
2782 warn_reinsert(&DebugName::type_name::<R>());
2783 }
2784 }
2785
2786 OwningPtr::make(value, |ptr| {
2787 // SAFETY: ptr is of type `R`, which corresponds to the same component ID used to retrieve the resource data.
2788 unsafe {
2789 resource_data.insert_with_ticks(ptr, self.ticks, self.caller);
2790 }
2791 });
2792
2793 *self.was_successful = true;
2794 }
2795 }
2796
2797 // used to track whether the guard's drop impl was able to successfully reinsert the value into the world.
2798 // an alternative way to track success would be to have a separate `guard.apply()` method used
2799 // in the happy path -- however this would require two code paths for panicking vs regular control flow
2800 // which would have suboptimal codegen. `resource_scope` is a widely used primitive, both throughout the
2801 // engine and in user code, so this measure is likely worth it.
2802 let mut was_successful = false;
2803 let result = {
2804 let mut guard = ReinsertGuard {
2805 world: self,
2806 component_id,
2807 value: ManuallyDrop::new(value),
2808 ticks,
2809 caller,
2810 was_successful: &mut was_successful,
2811 };
2812
2813 let value_mut = Mut {
2814 value: &mut *guard.value,
2815 ticks: ComponentTicksMut {
2816 added: &mut guard.ticks.added,
2817 changed: &mut guard.ticks.changed,
2818 changed_by: guard.caller.as_mut(),
2819 last_run: last_change_tick,
2820 this_run: change_tick,
2821 },
2822 };
2823
2824 f(guard.world, value_mut)
2825
2826 // guard's drop impl runs here
2827 };
2828
2829 was_successful.then_some(result)
2830 }
2831
2832 /// Writes a [`Message`].
2833 /// This method returns the [`MessageId`] of the written `message`,
2834 /// or [`None`] if the `message` could not be written.
2835 #[inline]
2836 pub fn write_message<M: Message>(&mut self, message: M) -> Option<MessageId<M>> {
2837 self.write_message_batch(core::iter::once(message))?.next()
2838 }
2839
2840 /// Writes the default value of the [`Message`] of type `M`.
2841 /// This method returns the [`MessageId`] of the written message,
2842 /// or [`None`] if the `event` could not be written.
2843 #[inline]
2844 pub fn write_message_default<M: Message + Default>(&mut self) -> Option<MessageId<M>> {
2845 self.write_message(M::default())
2846 }
2847
2848 /// Writes a batch of [`Message`]s from an iterator.
2849 /// This method returns the [IDs](`MessageId`) of the written `messages`,
2850 /// or [`None`] if the `events` could not be written.
2851 #[inline]
2852 pub fn write_message_batch<M: Message>(
2853 &mut self,
2854 messages: impl IntoIterator<Item = M>,
2855 ) -> Option<WriteBatchIds<M>> {
2856 let Some(mut events_resource) = self.get_resource_mut::<Messages<M>>() else {
2857 log::error!(
2858 "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 ",
2859 DebugName::type_name::<M>()
2860 );
2861 return None;
2862 };
2863 Some(events_resource.write_batch(messages))
2864 }
2865
2866 /// Inserts a new resource with the given `value`. Will replace the value if it already existed.
2867 ///
2868 /// **You should prefer to use the typed API [`World::insert_resource`] where possible and only
2869 /// use this in cases where the actual types are not known at compile time.**
2870 ///
2871 /// # Safety
2872 /// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.
2873 #[inline]
2874 #[track_caller]
2875 pub unsafe fn insert_resource_by_id(
2876 &mut self,
2877 component_id: ComponentId,
2878 value: OwningPtr<'_>,
2879 caller: MaybeLocation,
2880 ) {
2881 let change_tick = self.change_tick();
2882
2883 let resource = self.initialize_resource_internal(component_id);
2884 // SAFETY: `value` is valid for `component_id`, ensured by caller
2885 unsafe {
2886 resource.insert(value, change_tick, caller);
2887 }
2888 }
2889
2890 /// Inserts a new `!Send` resource with the given `value`. Will replace the value if it already
2891 /// existed.
2892 ///
2893 /// **You should prefer to use the typed API [`World::insert_non_send_resource`] where possible and only
2894 /// use this in cases where the actual types are not known at compile time.**
2895 ///
2896 /// # Panics
2897 /// If a value is already present, this function will panic if not called from the same
2898 /// thread that the original value was inserted from.
2899 ///
2900 /// # Safety
2901 /// The value referenced by `value` must be valid for the given [`ComponentId`] of this world.
2902 #[inline]
2903 #[track_caller]
2904 pub unsafe fn insert_non_send_by_id(
2905 &mut self,
2906 component_id: ComponentId,
2907 value: OwningPtr<'_>,
2908 caller: MaybeLocation,
2909 ) {
2910 let change_tick = self.change_tick();
2911
2912 let resource = self.initialize_non_send_internal(component_id);
2913 // SAFETY: `value` is valid for `component_id`, ensured by caller
2914 unsafe {
2915 resource.insert(value, change_tick, caller);
2916 }
2917 }
2918
2919 /// # Panics
2920 /// Panics if `component_id` is not registered as a `Send` component type in this `World`
2921 #[inline]
2922 pub(crate) fn initialize_resource_internal(
2923 &mut self,
2924 component_id: ComponentId,
2925 ) -> &mut ResourceData<true> {
2926 self.flush_components();
2927 self.storages
2928 .resources
2929 .initialize_with(component_id, &self.components)
2930 }
2931
2932 /// # Panics
2933 /// Panics if `component_id` is not registered in this world
2934 #[inline]
2935 pub(crate) fn initialize_non_send_internal(
2936 &mut self,
2937 component_id: ComponentId,
2938 ) -> &mut ResourceData<false> {
2939 self.flush_components();
2940 self.storages
2941 .non_send_resources
2942 .initialize_with(component_id, &self.components)
2943 }
2944
2945 /// Applies any commands in the world's internal [`CommandQueue`].
2946 /// This does not apply commands from any systems, only those stored in the world.
2947 ///
2948 /// # Panics
2949 /// This will panic if any of the queued commands are [`spawn`](Commands::spawn).
2950 /// If this is possible, you should instead use [`flush`](Self::flush).
2951 pub(crate) fn flush_commands(&mut self) {
2952 // SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`
2953 if !unsafe { self.command_queue.is_empty() } {
2954 // SAFETY: `self.command_queue` is only de-allocated in `World`'s `Drop`
2955 unsafe {
2956 self.command_queue
2957 .clone()
2958 .apply_or_drop_queued(Some(self.into()));
2959 };
2960 }
2961 }
2962
2963 /// Applies any queued component registration.
2964 /// For spawning vanilla rust component types and resources, this is not strictly necessary.
2965 /// However, flushing components can make information available more quickly, and can have performance benefits.
2966 /// Additionally, for components and resources registered dynamically through a raw descriptor or similar,
2967 /// this is the only way to complete their registration.
2968 pub(crate) fn flush_components(&mut self) {
2969 self.components_registrator().apply_queued_registrations();
2970 }
2971
2972 /// Flushes queued entities and commands.
2973 ///
2974 /// Queued entities will be spawned, and then commands will be applied.
2975 #[inline]
2976 #[track_caller]
2977 pub fn flush(&mut self) {
2978 self.flush_components();
2979 self.flush_commands();
2980 }
2981
2982 /// Increments the world's current change tick and returns the old value.
2983 ///
2984 /// If you need to call this method, but do not have `&mut` access to the world,
2985 /// consider using [`as_unsafe_world_cell_readonly`](Self::as_unsafe_world_cell_readonly)
2986 /// to obtain an [`UnsafeWorldCell`] and calling [`increment_change_tick`](UnsafeWorldCell::increment_change_tick) on that.
2987 /// Note that this *can* be done in safe code, despite the name of the type.
2988 #[inline]
2989 pub fn increment_change_tick(&mut self) -> Tick {
2990 let change_tick = self.change_tick.get_mut();
2991 let prev_tick = *change_tick;
2992 *change_tick = change_tick.wrapping_add(1);
2993 Tick::new(prev_tick)
2994 }
2995
2996 /// Reads the current change tick of this world.
2997 ///
2998 /// If you have exclusive (`&mut`) access to the world, consider using [`change_tick()`](Self::change_tick),
2999 /// which is more efficient since it does not require atomic synchronization.
3000 #[inline]
3001 pub fn read_change_tick(&self) -> Tick {
3002 let tick = self.change_tick.load(Ordering::Acquire);
3003 Tick::new(tick)
3004 }
3005
3006 /// Reads the current change tick of this world.
3007 ///
3008 /// This does the same thing as [`read_change_tick()`](Self::read_change_tick), only this method
3009 /// is more efficient since it does not require atomic synchronization.
3010 #[inline]
3011 pub fn change_tick(&mut self) -> Tick {
3012 let tick = *self.change_tick.get_mut();
3013 Tick::new(tick)
3014 }
3015
3016 /// When called from within an exclusive system (a [`System`] that takes `&mut World` as its first
3017 /// parameter), this method returns the [`Tick`] indicating the last time the exclusive system was run.
3018 ///
3019 /// Otherwise, this returns the `Tick` indicating the last time that [`World::clear_trackers`] was called.
3020 ///
3021 /// [`System`]: crate::system::System
3022 #[inline]
3023 pub fn last_change_tick(&self) -> Tick {
3024 self.last_change_tick
3025 }
3026
3027 /// Returns the id of the last ECS event that was fired.
3028 /// Used internally to ensure observers don't trigger multiple times for the same event.
3029 #[inline]
3030 pub(crate) fn last_trigger_id(&self) -> u32 {
3031 self.last_trigger_id
3032 }
3033
3034 /// Sets [`World::last_change_tick()`] to the specified value during a scope.
3035 /// When the scope terminates, it will return to its old value.
3036 ///
3037 /// This is useful if you need a region of code to be able to react to earlier changes made in the same system.
3038 ///
3039 /// # Examples
3040 ///
3041 /// ```
3042 /// # use bevy_ecs::prelude::*;
3043 /// // This function runs an update loop repeatedly, allowing each iteration of the loop
3044 /// // to react to changes made in the previous loop iteration.
3045 /// fn update_loop(
3046 /// world: &mut World,
3047 /// mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,
3048 /// ) {
3049 /// let mut last_change_tick = world.last_change_tick();
3050 ///
3051 /// // Repeatedly run the update function until it requests a break.
3052 /// loop {
3053 /// let control_flow = world.last_change_tick_scope(last_change_tick, |world| {
3054 /// // Increment the change tick so we can detect changes from the previous update.
3055 /// last_change_tick = world.change_tick();
3056 /// world.increment_change_tick();
3057 ///
3058 /// // Update once.
3059 /// update_fn(world)
3060 /// });
3061 ///
3062 /// // End the loop when the closure returns `ControlFlow::Break`.
3063 /// if control_flow.is_break() {
3064 /// break;
3065 /// }
3066 /// }
3067 /// }
3068 /// #
3069 /// # #[derive(Resource)] struct Count(u32);
3070 /// # let mut world = World::new();
3071 /// # world.insert_resource(Count(0));
3072 /// # let saved_last_tick = world.last_change_tick();
3073 /// # let mut num_updates = 0;
3074 /// # update_loop(&mut world, |world| {
3075 /// # let mut c = world.resource_mut::<Count>();
3076 /// # match c.0 {
3077 /// # 0 => {
3078 /// # assert_eq!(num_updates, 0);
3079 /// # assert!(c.is_added());
3080 /// # c.0 = 1;
3081 /// # }
3082 /// # 1 => {
3083 /// # assert_eq!(num_updates, 1);
3084 /// # assert!(!c.is_added());
3085 /// # assert!(c.is_changed());
3086 /// # c.0 = 2;
3087 /// # }
3088 /// # 2 if c.is_changed() => {
3089 /// # assert_eq!(num_updates, 2);
3090 /// # assert!(!c.is_added());
3091 /// # }
3092 /// # 2 => {
3093 /// # assert_eq!(num_updates, 3);
3094 /// # assert!(!c.is_changed());
3095 /// # world.remove_resource::<Count>();
3096 /// # world.insert_resource(Count(3));
3097 /// # }
3098 /// # 3 if c.is_changed() => {
3099 /// # assert_eq!(num_updates, 4);
3100 /// # assert!(c.is_added());
3101 /// # }
3102 /// # 3 => {
3103 /// # assert_eq!(num_updates, 5);
3104 /// # assert!(!c.is_added());
3105 /// # c.0 = 4;
3106 /// # return std::ops::ControlFlow::Break(());
3107 /// # }
3108 /// # _ => unreachable!(),
3109 /// # }
3110 /// # num_updates += 1;
3111 /// # std::ops::ControlFlow::Continue(())
3112 /// # });
3113 /// # assert_eq!(num_updates, 5);
3114 /// # assert_eq!(world.resource::<Count>().0, 4);
3115 /// # assert_eq!(world.last_change_tick(), saved_last_tick);
3116 /// ```
3117 pub fn last_change_tick_scope<T>(
3118 &mut self,
3119 last_change_tick: Tick,
3120 f: impl FnOnce(&mut World) -> T,
3121 ) -> T {
3122 struct LastTickGuard<'a> {
3123 world: &'a mut World,
3124 last_tick: Tick,
3125 }
3126
3127 // By setting the change tick in the drop impl, we ensure that
3128 // the change tick gets reset even if a panic occurs during the scope.
3129 impl Drop for LastTickGuard<'_> {
3130 fn drop(&mut self) {
3131 self.world.last_change_tick = self.last_tick;
3132 }
3133 }
3134
3135 let guard = LastTickGuard {
3136 last_tick: self.last_change_tick,
3137 world: self,
3138 };
3139
3140 guard.world.last_change_tick = last_change_tick;
3141
3142 f(guard.world)
3143 }
3144
3145 /// Iterates all component change ticks and clamps any older than [`MAX_CHANGE_AGE`](crate::change_detection::MAX_CHANGE_AGE).
3146 /// This also triggers [`CheckChangeTicks`] observers and returns the same event here.
3147 ///
3148 /// Calling this method prevents [`Tick`]s overflowing and thus prevents false positives when comparing them.
3149 ///
3150 /// **Note:** Does nothing and returns `None` if the [`World`] counter has not been incremented at least [`CHECK_TICK_THRESHOLD`]
3151 /// times since the previous pass.
3152 // TODO: benchmark and optimize
3153 pub fn check_change_ticks(&mut self) -> Option<CheckChangeTicks> {
3154 let change_tick = self.change_tick();
3155 if change_tick.relative_to(self.last_check_tick).get() < CHECK_TICK_THRESHOLD {
3156 return None;
3157 }
3158
3159 let check = CheckChangeTicks(change_tick);
3160
3161 let Storages {
3162 ref mut tables,
3163 ref mut sparse_sets,
3164 ref mut resources,
3165 ref mut non_send_resources,
3166 } = self.storages;
3167
3168 #[cfg(feature = "trace")]
3169 let _span = tracing::info_span!("check component ticks").entered();
3170 tables.check_change_ticks(check);
3171 sparse_sets.check_change_ticks(check);
3172 resources.check_change_ticks(check);
3173 non_send_resources.check_change_ticks(check);
3174 self.entities.check_change_ticks(check);
3175
3176 if let Some(mut schedules) = self.get_resource_mut::<Schedules>() {
3177 schedules.check_change_ticks(check);
3178 }
3179
3180 self.trigger(check);
3181 self.flush();
3182
3183 self.last_check_tick = change_tick;
3184
3185 Some(check)
3186 }
3187
3188 /// Runs both [`clear_entities`](Self::clear_entities) and [`clear_resources`](Self::clear_resources),
3189 /// invalidating all [`Entity`] and resource fetches such as [`Res`](crate::system::Res), [`ResMut`](crate::system::ResMut)
3190 pub fn clear_all(&mut self) {
3191 self.clear_entities();
3192 self.clear_resources();
3193 }
3194
3195 /// Despawns all entities in this [`World`].
3196 pub fn clear_entities(&mut self) {
3197 self.storages.tables.clear();
3198 self.storages.sparse_sets.clear_entities();
3199 self.archetypes.clear_entities();
3200 self.entities.clear();
3201 self.allocator.restart();
3202 }
3203
3204 /// Clears all resources in this [`World`].
3205 ///
3206 /// **Note:** Any resource fetch to this [`World`] will fail unless they are re-initialized,
3207 /// including engine-internal resources that are only initialized on app/world construction.
3208 ///
3209 /// This can easily cause systems expecting certain resources to immediately start panicking.
3210 /// Use with caution.
3211 pub fn clear_resources(&mut self) {
3212 self.storages.resources.clear();
3213 self.storages.non_send_resources.clear();
3214 }
3215
3216 /// Registers all of the components in the given [`Bundle`] and returns both the component
3217 /// ids and the bundle id.
3218 ///
3219 /// This is largely equivalent to calling [`register_component`](Self::register_component) on each
3220 /// component in the bundle.
3221 #[inline]
3222 pub fn register_bundle<B: Bundle>(&mut self) -> &BundleInfo {
3223 let id = self.register_bundle_info::<B>();
3224
3225 // SAFETY: We just initialized the bundle so its id should definitely be valid.
3226 unsafe { self.bundles.get(id).debug_checked_unwrap() }
3227 }
3228
3229 pub(crate) fn register_bundle_info<B: Bundle>(&mut self) -> BundleId {
3230 // SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.
3231 let mut registrator =
3232 unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };
3233
3234 // SAFETY: `registrator`, `self.storages` and `self.bundles` all come from this world.
3235 unsafe {
3236 self.bundles
3237 .register_info::<B>(&mut registrator, &mut self.storages)
3238 }
3239 }
3240
3241 pub(crate) fn register_contributed_bundle_info<B: Bundle>(&mut self) -> BundleId {
3242 // SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too.
3243 let mut registrator =
3244 unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };
3245
3246 // SAFETY: `registrator`, `self.bundles` and `self.storages` are all from this world.
3247 unsafe {
3248 self.bundles
3249 .register_contributed_bundle_info::<B>(&mut registrator, &mut self.storages)
3250 }
3251 }
3252
3253 /// Registers the given [`ComponentId`]s as a dynamic bundle and returns both the required component ids and the bundle id.
3254 ///
3255 /// Note that the components need to be registered first, this function only creates a bundle combining them. Components
3256 /// can be registered with [`World::register_component`]/[`_with_descriptor`](World::register_component_with_descriptor).
3257 ///
3258 /// **You should prefer to use the typed API [`World::register_bundle`] where possible and only use this in cases where
3259 /// not all of the actual types are known at compile time.**
3260 ///
3261 /// # Panics
3262 /// This function will panic if any of the provided component ids do not belong to a component known to this [`World`].
3263 #[inline]
3264 pub fn register_dynamic_bundle(&mut self, component_ids: &[ComponentId]) -> &BundleInfo {
3265 let id =
3266 self.bundles
3267 .init_dynamic_info(&mut self.storages, &self.components, component_ids);
3268 // SAFETY: We just initialized the bundle so its id should definitely be valid.
3269 unsafe { self.bundles.get(id).debug_checked_unwrap() }
3270 }
3271
3272 /// Convenience method for accessing the world's default error handler,
3273 /// which can be overwritten with [`DefaultErrorHandler`].
3274 #[inline]
3275 pub fn default_error_handler(&self) -> ErrorHandler {
3276 self.get_resource::<DefaultErrorHandler>()
3277 .copied()
3278 .unwrap_or_default()
3279 .0
3280 }
3281}
3282
3283impl World {
3284 /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
3285 /// The returned pointer must not be used to modify the resource, and must not be
3286 /// dereferenced after the immutable borrow of the [`World`] ends.
3287 ///
3288 /// **You should prefer to use the typed API [`World::get_resource`] where possible and only
3289 /// use this in cases where the actual types are not known at compile time.**
3290 #[inline]
3291 pub fn get_resource_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
3292 // SAFETY:
3293 // - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably
3294 // - `&self` ensures there are no mutable borrows on world data
3295 unsafe {
3296 self.as_unsafe_world_cell_readonly()
3297 .get_resource_by_id(component_id)
3298 }
3299 }
3300
3301 /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
3302 /// The returned pointer may be used to modify the resource, as long as the mutable borrow
3303 /// of the [`World`] is still valid.
3304 ///
3305 /// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only
3306 /// use this in cases where the actual types are not known at compile time.**
3307 #[inline]
3308 pub fn get_resource_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
3309 // SAFETY:
3310 // - `&mut self` ensures that all accessed data is unaliased
3311 // - `as_unsafe_world_cell` provides mutable permission to the whole world
3312 unsafe {
3313 self.as_unsafe_world_cell()
3314 .get_resource_mut_by_id(component_id)
3315 }
3316 }
3317
3318 /// Iterates over all resources in the world.
3319 ///
3320 /// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading the contents
3321 /// of each resource will require the use of unsafe code.
3322 ///
3323 /// # Examples
3324 ///
3325 /// ## Printing the size of all resources
3326 ///
3327 /// ```
3328 /// # use bevy_ecs::prelude::*;
3329 /// # #[derive(Resource)]
3330 /// # struct A(u32);
3331 /// # #[derive(Resource)]
3332 /// # struct B(u32);
3333 /// #
3334 /// # let mut world = World::new();
3335 /// # world.remove_resource::<bevy_ecs::entity_disabling::DefaultQueryFilters>();
3336 /// # world.insert_resource(A(1));
3337 /// # world.insert_resource(B(2));
3338 /// let mut total = 0;
3339 /// for (info, _) in world.iter_resources() {
3340 /// println!("Resource: {}", info.name());
3341 /// println!("Size: {} bytes", info.layout().size());
3342 /// total += info.layout().size();
3343 /// }
3344 /// println!("Total size: {} bytes", total);
3345 /// # assert_eq!(total, size_of::<A>() + size_of::<B>());
3346 /// ```
3347 ///
3348 /// ## Dynamically running closures for resources matching specific `TypeId`s
3349 ///
3350 /// ```
3351 /// # use bevy_ecs::prelude::*;
3352 /// # use std::collections::HashMap;
3353 /// # use std::any::TypeId;
3354 /// # use bevy_ptr::Ptr;
3355 /// # #[derive(Resource)]
3356 /// # struct A(u32);
3357 /// # #[derive(Resource)]
3358 /// # struct B(u32);
3359 /// #
3360 /// # let mut world = World::new();
3361 /// # world.insert_resource(A(1));
3362 /// # world.insert_resource(B(2));
3363 /// #
3364 /// // In this example, `A` and `B` are resources. We deliberately do not use the
3365 /// // `bevy_reflect` crate here to showcase the low-level [`Ptr`] usage. You should
3366 /// // probably use something like `ReflectFromPtr` in a real-world scenario.
3367 ///
3368 /// // Create the hash map that will store the closures for each resource type
3369 /// let mut closures: HashMap<TypeId, Box<dyn Fn(&Ptr<'_>)>> = HashMap::default();
3370 ///
3371 /// // Add closure for `A`
3372 /// closures.insert(TypeId::of::<A>(), Box::new(|ptr| {
3373 /// // SAFETY: We assert ptr is the same type of A with TypeId of A
3374 /// let a = unsafe { &ptr.deref::<A>() };
3375 /// # assert_eq!(a.0, 1);
3376 /// // ... do something with `a` here
3377 /// }));
3378 ///
3379 /// // Add closure for `B`
3380 /// closures.insert(TypeId::of::<B>(), Box::new(|ptr| {
3381 /// // SAFETY: We assert ptr is the same type of B with TypeId of B
3382 /// let b = unsafe { &ptr.deref::<B>() };
3383 /// # assert_eq!(b.0, 2);
3384 /// // ... do something with `b` here
3385 /// }));
3386 ///
3387 /// // Iterate all resources, in order to run the closures for each matching resource type
3388 /// for (info, ptr) in world.iter_resources() {
3389 /// let Some(type_id) = info.type_id() else {
3390 /// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources
3391 /// // dynamically inserted via a scripting language) in which case we can't match them.
3392 /// continue;
3393 /// };
3394 ///
3395 /// let Some(closure) = closures.get(&type_id) else {
3396 /// // No closure for this resource type, skip it.
3397 /// continue;
3398 /// };
3399 ///
3400 /// // Run the closure for the resource
3401 /// closure(&ptr);
3402 /// }
3403 /// ```
3404 #[inline]
3405 pub fn iter_resources(&self) -> impl Iterator<Item = (&ComponentInfo, Ptr<'_>)> {
3406 self.storages
3407 .resources
3408 .iter()
3409 .filter_map(|(component_id, data)| {
3410 // SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.
3411 let component_info = unsafe {
3412 self.components
3413 .get_info(component_id)
3414 .debug_checked_unwrap()
3415 };
3416 Some((component_info, data.get_data()?))
3417 })
3418 }
3419
3420 /// Mutably iterates over all resources in the world.
3421 ///
3422 /// The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading from or writing
3423 /// to the contents of each resource will require the use of unsafe code.
3424 ///
3425 /// # Example
3426 ///
3427 /// ```
3428 /// # use bevy_ecs::prelude::*;
3429 /// # use bevy_ecs::change_detection::MutUntyped;
3430 /// # use std::collections::HashMap;
3431 /// # use std::any::TypeId;
3432 /// # #[derive(Resource)]
3433 /// # struct A(u32);
3434 /// # #[derive(Resource)]
3435 /// # struct B(u32);
3436 /// #
3437 /// # let mut world = World::new();
3438 /// # world.insert_resource(A(1));
3439 /// # world.insert_resource(B(2));
3440 /// #
3441 /// // In this example, `A` and `B` are resources. We deliberately do not use the
3442 /// // `bevy_reflect` crate here to showcase the low-level `MutUntyped` usage. You should
3443 /// // probably use something like `ReflectFromPtr` in a real-world scenario.
3444 ///
3445 /// // Create the hash map that will store the mutator closures for each resource type
3446 /// let mut mutators: HashMap<TypeId, Box<dyn Fn(&mut MutUntyped<'_>)>> = HashMap::default();
3447 ///
3448 /// // Add mutator closure for `A`
3449 /// mutators.insert(TypeId::of::<A>(), Box::new(|mut_untyped| {
3450 /// // Note: `MutUntyped::as_mut()` automatically marks the resource as changed
3451 /// // for ECS change detection, and gives us a `PtrMut` we can use to mutate the resource.
3452 /// // SAFETY: We assert ptr is the same type of A with TypeId of A
3453 /// let a = unsafe { &mut mut_untyped.as_mut().deref_mut::<A>() };
3454 /// # a.0 += 1;
3455 /// // ... mutate `a` here
3456 /// }));
3457 ///
3458 /// // Add mutator closure for `B`
3459 /// mutators.insert(TypeId::of::<B>(), Box::new(|mut_untyped| {
3460 /// // SAFETY: We assert ptr is the same type of B with TypeId of B
3461 /// let b = unsafe { &mut mut_untyped.as_mut().deref_mut::<B>() };
3462 /// # b.0 += 1;
3463 /// // ... mutate `b` here
3464 /// }));
3465 ///
3466 /// // Iterate all resources, in order to run the mutator closures for each matching resource type
3467 /// for (info, mut mut_untyped) in world.iter_resources_mut() {
3468 /// let Some(type_id) = info.type_id() else {
3469 /// // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources
3470 /// // dynamically inserted via a scripting language) in which case we can't match them.
3471 /// continue;
3472 /// };
3473 ///
3474 /// let Some(mutator) = mutators.get(&type_id) else {
3475 /// // No mutator closure for this resource type, skip it.
3476 /// continue;
3477 /// };
3478 ///
3479 /// // Run the mutator closure for the resource
3480 /// mutator(&mut mut_untyped);
3481 /// }
3482 /// # assert_eq!(world.resource::<A>().0, 2);
3483 /// # assert_eq!(world.resource::<B>().0, 3);
3484 /// ```
3485 #[inline]
3486 pub fn iter_resources_mut(&mut self) -> impl Iterator<Item = (&ComponentInfo, MutUntyped<'_>)> {
3487 self.storages
3488 .resources
3489 .iter()
3490 .filter_map(|(component_id, data)| {
3491 // SAFETY: If a resource has been initialized, a corresponding ComponentInfo must exist with its ID.
3492 let component_info = unsafe {
3493 self.components
3494 .get_info(component_id)
3495 .debug_checked_unwrap()
3496 };
3497 let (ptr, ticks) = data.get_with_ticks()?;
3498
3499 // SAFETY:
3500 // - We have exclusive access to the world, so no other code can be aliasing the `ComponentTickCells`
3501 // - We only hold one `ComponentTicksMut` at a time, and we let go of it before getting the next one
3502 let ticks = unsafe {
3503 ComponentTicksMut::from_tick_cells(
3504 ticks,
3505 self.last_change_tick(),
3506 self.read_change_tick(),
3507 )
3508 };
3509
3510 let mut_untyped = MutUntyped {
3511 // SAFETY:
3512 // - We have exclusive access to the world, so no other code can be aliasing the `Ptr`
3513 // - We iterate one resource at a time, and we let go of each `PtrMut` before getting the next one
3514 value: unsafe { ptr.assert_unique() },
3515 ticks,
3516 };
3517
3518 Some((component_info, mut_untyped))
3519 })
3520 }
3521
3522 /// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.
3523 /// The returned pointer must not be used to modify the resource, and must not be
3524 /// dereferenced after the immutable borrow of the [`World`] ends.
3525 ///
3526 /// **You should prefer to use the typed API [`World::get_resource`] where possible and only
3527 /// use this in cases where the actual types are not known at compile time.**
3528 ///
3529 /// # Panics
3530 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3531 #[inline]
3532 pub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
3533 // SAFETY:
3534 // - `as_unsafe_world_cell_readonly` gives permission to access the whole world immutably
3535 // - `&self` ensures there are no mutable borrows on world data
3536 unsafe {
3537 self.as_unsafe_world_cell_readonly()
3538 .get_non_send_resource_by_id(component_id)
3539 }
3540 }
3541
3542 /// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.
3543 /// The returned pointer may be used to modify the resource, as long as the mutable borrow
3544 /// of the [`World`] is still valid.
3545 ///
3546 /// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only
3547 /// use this in cases where the actual types are not known at compile time.**
3548 ///
3549 /// # Panics
3550 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3551 #[inline]
3552 pub fn get_non_send_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
3553 // SAFETY:
3554 // - `&mut self` ensures that all accessed data is unaliased
3555 // - `as_unsafe_world_cell` provides mutable permission to the whole world
3556 unsafe {
3557 self.as_unsafe_world_cell()
3558 .get_non_send_resource_mut_by_id(component_id)
3559 }
3560 }
3561
3562 /// Removes the resource of a given type, if it exists. Otherwise returns `None`.
3563 ///
3564 /// **You should prefer to use the typed API [`World::remove_resource`] where possible and only
3565 /// use this in cases where the actual types are not known at compile time.**
3566 pub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> Option<()> {
3567 self.storages
3568 .resources
3569 .get_mut(component_id)?
3570 .remove_and_drop();
3571 Some(())
3572 }
3573
3574 /// Removes the resource of a given type, if it exists. Otherwise returns `None`.
3575 ///
3576 /// **You should prefer to use the typed API [`World::remove_resource`] where possible and only
3577 /// use this in cases where the actual types are not known at compile time.**
3578 ///
3579 /// # Panics
3580 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3581 pub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()> {
3582 self.storages
3583 .non_send_resources
3584 .get_mut(component_id)?
3585 .remove_and_drop();
3586 Some(())
3587 }
3588
3589 /// Retrieves an immutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
3590 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
3591 ///
3592 /// **You should prefer to use the typed API [`World::get_mut`] where possible and only
3593 /// use this in cases where the actual types are not known at compile time.**
3594 ///
3595 /// # Panics
3596 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
3597 #[inline]
3598 pub fn get_by_id(&self, entity: Entity, component_id: ComponentId) -> Option<Ptr<'_>> {
3599 self.get_entity(entity).ok()?.get_by_id(component_id).ok()
3600 }
3601
3602 /// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
3603 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
3604 ///
3605 /// **You should prefer to use the typed API [`World::get_mut`] where possible and only
3606 /// use this in cases where the actual types are not known at compile time.**
3607 #[inline]
3608 pub fn get_mut_by_id(
3609 &mut self,
3610 entity: Entity,
3611 component_id: ComponentId,
3612 ) -> Option<MutUntyped<'_>> {
3613 self.get_entity_mut(entity)
3614 .ok()?
3615 .into_mut_by_id(component_id)
3616 .ok()
3617 }
3618}
3619
3620// Schedule-related methods
3621impl World {
3622 /// Adds the specified [`Schedule`] to the world.
3623 /// If a schedule already exists with the same [label](Schedule::label), it will be replaced.
3624 ///
3625 /// The schedule can later be run
3626 /// by calling [`.run_schedule(label)`](Self::run_schedule) or by directly
3627 /// accessing the [`Schedules`] resource.
3628 ///
3629 /// The `Schedules` resource will be initialized if it does not already exist.
3630 ///
3631 /// An alternative to this is to call [`Schedules::add_systems()`] with some
3632 /// [`ScheduleLabel`] and let the schedule for that label be created if it
3633 /// does not already exist.
3634 pub fn add_schedule(&mut self, schedule: Schedule) {
3635 let mut schedules = self.get_resource_or_init::<Schedules>();
3636 schedules.insert(schedule);
3637 }
3638
3639 /// Temporarily removes the schedule associated with `label` from the world,
3640 /// runs user code, and finally re-adds the schedule.
3641 /// This returns a [`TryRunScheduleError`] if there is no schedule
3642 /// associated with `label`.
3643 ///
3644 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3645 /// and system state is cached.
3646 ///
3647 /// For simple cases where you just need to call the schedule once,
3648 /// consider using [`World::try_run_schedule`] instead.
3649 /// For other use cases, see the example on [`World::schedule_scope`].
3650 pub fn try_schedule_scope<R>(
3651 &mut self,
3652 label: impl ScheduleLabel,
3653 f: impl FnOnce(&mut World, &mut Schedule) -> R,
3654 ) -> Result<R, TryRunScheduleError> {
3655 let label = label.intern();
3656 let Some(mut schedule) = self
3657 .get_resource_mut::<Schedules>()
3658 .and_then(|mut s| s.remove(label))
3659 else {
3660 return Err(TryRunScheduleError(label));
3661 };
3662
3663 let value = f(self, &mut schedule);
3664
3665 let old = self.resource_mut::<Schedules>().insert(schedule);
3666 if old.is_some() {
3667 warn!("Schedule `{label:?}` was inserted during a call to `World::schedule_scope`: its value has been overwritten");
3668 }
3669
3670 Ok(value)
3671 }
3672
3673 /// Temporarily removes the schedule associated with `label` from the world,
3674 /// runs user code, and finally re-adds the schedule.
3675 ///
3676 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3677 /// and system state is cached.
3678 ///
3679 /// # Examples
3680 ///
3681 /// ```
3682 /// # use bevy_ecs::{prelude::*, schedule::ScheduleLabel};
3683 /// # #[derive(ScheduleLabel, Debug, Clone, Copy, PartialEq, Eq, Hash)]
3684 /// # pub struct MySchedule;
3685 /// # #[derive(Resource)]
3686 /// # struct Counter(usize);
3687 /// #
3688 /// # let mut world = World::new();
3689 /// # world.insert_resource(Counter(0));
3690 /// # let mut schedule = Schedule::new(MySchedule);
3691 /// # schedule.add_systems(tick_counter);
3692 /// # world.init_resource::<Schedules>();
3693 /// # world.add_schedule(schedule);
3694 /// # fn tick_counter(mut counter: ResMut<Counter>) { counter.0 += 1; }
3695 /// // Run the schedule five times.
3696 /// world.schedule_scope(MySchedule, |world, schedule| {
3697 /// for _ in 0..5 {
3698 /// schedule.run(world);
3699 /// }
3700 /// });
3701 /// # assert_eq!(world.resource::<Counter>().0, 5);
3702 /// ```
3703 ///
3704 /// For simple cases where you just need to call the schedule once,
3705 /// consider using [`World::run_schedule`] instead.
3706 ///
3707 /// # Panics
3708 ///
3709 /// If the requested schedule does not exist.
3710 pub fn schedule_scope<R>(
3711 &mut self,
3712 label: impl ScheduleLabel,
3713 f: impl FnOnce(&mut World, &mut Schedule) -> R,
3714 ) -> R {
3715 self.try_schedule_scope(label, f)
3716 .unwrap_or_else(|e| panic!("{e}"))
3717 }
3718
3719 /// Attempts to run the [`Schedule`] associated with the `label` a single time,
3720 /// and returns a [`TryRunScheduleError`] if the schedule does not exist.
3721 ///
3722 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3723 /// and system state is cached.
3724 ///
3725 /// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.
3726 pub fn try_run_schedule(
3727 &mut self,
3728 label: impl ScheduleLabel,
3729 ) -> Result<(), TryRunScheduleError> {
3730 self.try_schedule_scope(label, |world, sched| sched.run(world))
3731 }
3732
3733 /// Runs the [`Schedule`] associated with the `label` a single time.
3734 ///
3735 /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label,
3736 /// and system state is cached.
3737 ///
3738 /// For simple testing use cases, call [`Schedule::run(&mut world)`](Schedule::run) instead.
3739 /// This avoids the need to create a unique [`ScheduleLabel`].
3740 ///
3741 /// # Panics
3742 ///
3743 /// If the requested schedule does not exist.
3744 pub fn run_schedule(&mut self, label: impl ScheduleLabel) {
3745 self.schedule_scope(label, |world, sched| sched.run(world));
3746 }
3747
3748 /// Ignore system order ambiguities caused by conflicts on [`Component`]s of type `T`.
3749 pub fn allow_ambiguous_component<T: Component>(&mut self) {
3750 let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();
3751 schedules.allow_ambiguous_component::<T>(self);
3752 self.insert_resource(schedules);
3753 }
3754
3755 /// Ignore system order ambiguities caused by conflicts on [`Resource`]s of type `T`.
3756 pub fn allow_ambiguous_resource<T: Resource>(&mut self) {
3757 let mut schedules = self.remove_resource::<Schedules>().unwrap_or_default();
3758 schedules.allow_ambiguous_resource::<T>(self);
3759 self.insert_resource(schedules);
3760 }
3761}
3762
3763impl fmt::Debug for World {
3764 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3765 // SAFETY: `UnsafeWorldCell` requires that this must only access metadata.
3766 // Accessing any data stored in the world would be unsound.
3767 f.debug_struct("World")
3768 .field("id", &self.id)
3769 .field("entity_count", &self.entities.count_spawned())
3770 .field("archetype_count", &self.archetypes.len())
3771 .field("component_count", &self.components.len())
3772 .field("resource_count", &self.storages.resources.len())
3773 .finish()
3774 }
3775}
3776
3777// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread
3778unsafe impl Send for World {}
3779// SAFETY: all methods on the world ensure that non-send resources are only accessible on the main thread
3780unsafe impl Sync for World {}
3781
3782/// Creates an instance of the type this trait is implemented for
3783/// using data from the supplied [`World`].
3784///
3785/// This can be helpful for complex initialization or context-aware defaults.
3786///
3787/// [`FromWorld`] is automatically implemented for any type implementing [`Default`]
3788/// and may also be derived for:
3789/// - any struct whose fields all implement `FromWorld`
3790/// - any enum where one variant has the attribute `#[from_world]`
3791///
3792/// ```rs
3793///
3794/// #[derive(Default)]
3795/// struct A;
3796///
3797/// #[derive(Default)]
3798/// struct B(Option<u32>)
3799///
3800/// struct C;
3801///
3802/// impl FromWorld for C {
3803/// fn from_world(_world: &mut World) -> Self {
3804/// Self
3805/// }
3806/// }
3807///
3808/// #[derive(FromWorld)]
3809/// struct D(A, B, C);
3810///
3811/// #[derive(FromWorld)]
3812/// enum E {
3813/// #[from_world]
3814/// F,
3815/// G
3816/// }
3817/// ```
3818pub trait FromWorld {
3819 /// Creates `Self` using data from the given [`World`].
3820 fn from_world(world: &mut World) -> Self;
3821}
3822
3823impl<T: Default> FromWorld for T {
3824 /// Creates `Self` using [`default()`](`Default::default`).
3825 #[track_caller]
3826 fn from_world(_world: &mut World) -> Self {
3827 T::default()
3828 }
3829}
3830
3831#[cfg(test)]
3832#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
3833mod tests {
3834 use super::{FromWorld, World};
3835 use crate::{
3836 change_detection::{DetectChangesMut, MaybeLocation},
3837 component::{ComponentCloneBehavior, ComponentDescriptor, ComponentInfo, StorageType},
3838 entity::EntityHashSet,
3839 entity_disabling::{DefaultQueryFilters, Disabled},
3840 ptr::OwningPtr,
3841 resource::Resource,
3842 world::{error::EntityMutableFetchError, DeferredWorld},
3843 };
3844 use alloc::{
3845 borrow::ToOwned,
3846 string::{String, ToString},
3847 sync::Arc,
3848 vec,
3849 vec::Vec,
3850 };
3851 use bevy_ecs_macros::Component;
3852 use bevy_platform::collections::HashSet;
3853 use bevy_utils::prelude::DebugName;
3854 use core::{
3855 any::TypeId,
3856 panic,
3857 sync::atomic::{AtomicBool, AtomicU32, Ordering},
3858 };
3859 use std::{println, sync::Mutex};
3860
3861 type ID = u8;
3862
3863 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
3864 enum DropLogItem {
3865 Create(ID),
3866 Drop(ID),
3867 }
3868
3869 #[derive(Component)]
3870 struct MayPanicInDrop {
3871 drop_log: Arc<Mutex<Vec<DropLogItem>>>,
3872 expected_panic_flag: Arc<AtomicBool>,
3873 should_panic: bool,
3874 id: u8,
3875 }
3876
3877 impl MayPanicInDrop {
3878 fn new(
3879 drop_log: &Arc<Mutex<Vec<DropLogItem>>>,
3880 expected_panic_flag: &Arc<AtomicBool>,
3881 should_panic: bool,
3882 id: u8,
3883 ) -> Self {
3884 println!("creating component with id {id}");
3885 drop_log.lock().unwrap().push(DropLogItem::Create(id));
3886
3887 Self {
3888 drop_log: Arc::clone(drop_log),
3889 expected_panic_flag: Arc::clone(expected_panic_flag),
3890 should_panic,
3891 id,
3892 }
3893 }
3894 }
3895
3896 impl Drop for MayPanicInDrop {
3897 fn drop(&mut self) {
3898 println!("dropping component with id {}", self.id);
3899
3900 {
3901 let mut drop_log = self.drop_log.lock().unwrap();
3902 drop_log.push(DropLogItem::Drop(self.id));
3903 // Don't keep the mutex while panicking, or we'll poison it.
3904 drop(drop_log);
3905 }
3906
3907 if self.should_panic {
3908 self.expected_panic_flag.store(true, Ordering::SeqCst);
3909 panic!("testing what happens on panic inside drop");
3910 }
3911 }
3912 }
3913
3914 struct DropTestHelper {
3915 drop_log: Arc<Mutex<Vec<DropLogItem>>>,
3916 /// Set to `true` right before we intentionally panic, so that if we get
3917 /// a panic, we know if it was intended or not.
3918 expected_panic_flag: Arc<AtomicBool>,
3919 }
3920
3921 impl DropTestHelper {
3922 pub fn new() -> Self {
3923 Self {
3924 drop_log: Arc::new(Mutex::new(Vec::<DropLogItem>::new())),
3925 expected_panic_flag: Arc::new(AtomicBool::new(false)),
3926 }
3927 }
3928
3929 pub fn make_component(&self, should_panic: bool, id: ID) -> MayPanicInDrop {
3930 MayPanicInDrop::new(&self.drop_log, &self.expected_panic_flag, should_panic, id)
3931 }
3932
3933 pub fn finish(self, panic_res: std::thread::Result<()>) -> Vec<DropLogItem> {
3934 let drop_log = self.drop_log.lock().unwrap();
3935 let expected_panic_flag = self.expected_panic_flag.load(Ordering::SeqCst);
3936
3937 if !expected_panic_flag {
3938 match panic_res {
3939 Ok(()) => panic!("Expected a panic but it didn't happen"),
3940 Err(e) => std::panic::resume_unwind(e),
3941 }
3942 }
3943
3944 drop_log.to_owned()
3945 }
3946 }
3947
3948 #[test]
3949 fn panic_while_overwriting_component() {
3950 let helper = DropTestHelper::new();
3951
3952 let res = std::panic::catch_unwind(|| {
3953 let mut world = World::new();
3954 world
3955 .spawn_empty()
3956 .insert(helper.make_component(true, 0))
3957 .insert(helper.make_component(false, 1));
3958
3959 println!("Done inserting! Dropping world...");
3960 });
3961
3962 let drop_log = helper.finish(res);
3963
3964 assert_eq!(
3965 &*drop_log,
3966 [
3967 DropLogItem::Create(0),
3968 DropLogItem::Create(1),
3969 DropLogItem::Drop(0),
3970 DropLogItem::Drop(1),
3971 ]
3972 );
3973 }
3974
3975 #[derive(Resource)]
3976 struct TestResource(u32);
3977
3978 #[derive(Resource)]
3979 struct TestResource2(String);
3980
3981 #[derive(Resource)]
3982 struct TestResource3;
3983
3984 #[test]
3985 fn get_resource_by_id() {
3986 let mut world = World::new();
3987 world.insert_resource(TestResource(42));
3988 let component_id = world
3989 .components()
3990 .get_valid_resource_id(TypeId::of::<TestResource>())
3991 .unwrap();
3992
3993 let resource = world.get_resource_by_id(component_id).unwrap();
3994 // SAFETY: `TestResource` is the correct resource type
3995 let resource = unsafe { resource.deref::<TestResource>() };
3996
3997 assert_eq!(resource.0, 42);
3998 }
3999
4000 #[test]
4001 fn get_resource_mut_by_id() {
4002 let mut world = World::new();
4003 world.insert_resource(TestResource(42));
4004 let component_id = world
4005 .components()
4006 .get_valid_resource_id(TypeId::of::<TestResource>())
4007 .unwrap();
4008
4009 {
4010 let mut resource = world.get_resource_mut_by_id(component_id).unwrap();
4011 resource.set_changed();
4012 // SAFETY: `TestResource` is the correct resource type
4013 let resource = unsafe { resource.into_inner().deref_mut::<TestResource>() };
4014 resource.0 = 43;
4015 }
4016
4017 let resource = world.get_resource_by_id(component_id).unwrap();
4018 // SAFETY: `TestResource` is the correct resource type
4019 let resource = unsafe { resource.deref::<TestResource>() };
4020
4021 assert_eq!(resource.0, 43);
4022 }
4023
4024 #[test]
4025 fn iter_resources() {
4026 let mut world = World::new();
4027 // Remove DefaultQueryFilters so it doesn't show up in the iterator
4028 world.remove_resource::<DefaultQueryFilters>();
4029 world.insert_resource(TestResource(42));
4030 world.insert_resource(TestResource2("Hello, world!".to_string()));
4031 world.insert_resource(TestResource3);
4032 world.remove_resource::<TestResource3>();
4033
4034 let mut iter = world.iter_resources();
4035
4036 let (info, ptr) = iter.next().unwrap();
4037 assert_eq!(info.name(), DebugName::type_name::<TestResource>());
4038 // SAFETY: We know that the resource is of type `TestResource`
4039 assert_eq!(unsafe { ptr.deref::<TestResource>().0 }, 42);
4040
4041 let (info, ptr) = iter.next().unwrap();
4042 assert_eq!(info.name(), DebugName::type_name::<TestResource2>());
4043 assert_eq!(
4044 // SAFETY: We know that the resource is of type `TestResource2`
4045 unsafe { &ptr.deref::<TestResource2>().0 },
4046 &"Hello, world!".to_string()
4047 );
4048
4049 assert!(iter.next().is_none());
4050 }
4051
4052 #[test]
4053 fn iter_resources_mut() {
4054 let mut world = World::new();
4055 // Remove DefaultQueryFilters so it doesn't show up in the iterator
4056 world.remove_resource::<DefaultQueryFilters>();
4057 world.insert_resource(TestResource(42));
4058 world.insert_resource(TestResource2("Hello, world!".to_string()));
4059 world.insert_resource(TestResource3);
4060 world.remove_resource::<TestResource3>();
4061
4062 let mut iter = world.iter_resources_mut();
4063
4064 let (info, mut mut_untyped) = iter.next().unwrap();
4065 assert_eq!(info.name(), DebugName::type_name::<TestResource>());
4066 // SAFETY: We know that the resource is of type `TestResource`
4067 unsafe {
4068 mut_untyped.as_mut().deref_mut::<TestResource>().0 = 43;
4069 };
4070
4071 let (info, mut mut_untyped) = iter.next().unwrap();
4072 assert_eq!(info.name(), DebugName::type_name::<TestResource2>());
4073 // SAFETY: We know that the resource is of type `TestResource2`
4074 unsafe {
4075 mut_untyped.as_mut().deref_mut::<TestResource2>().0 = "Hello, world?".to_string();
4076 };
4077
4078 assert!(iter.next().is_none());
4079 drop(iter);
4080
4081 assert_eq!(world.resource::<TestResource>().0, 43);
4082 assert_eq!(
4083 world.resource::<TestResource2>().0,
4084 "Hello, world?".to_string()
4085 );
4086 }
4087
4088 #[test]
4089 fn dynamic_resource() {
4090 let mut world = World::new();
4091
4092 let descriptor = ComponentDescriptor::new_resource::<TestResource>();
4093
4094 let component_id = world.register_resource_with_descriptor(descriptor);
4095
4096 let value = 0;
4097 OwningPtr::make(value, |ptr| {
4098 // SAFETY: value is valid for the layout of `TestResource`
4099 unsafe {
4100 world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());
4101 }
4102 });
4103
4104 // SAFETY: We know that the resource is of type `TestResource`
4105 let resource = unsafe {
4106 world
4107 .get_resource_by_id(component_id)
4108 .unwrap()
4109 .deref::<TestResource>()
4110 };
4111 assert_eq!(resource.0, 0);
4112
4113 assert!(world.remove_resource_by_id(component_id).is_some());
4114 }
4115
4116 #[test]
4117 fn custom_resource_with_layout() {
4118 static DROP_COUNT: AtomicU32 = AtomicU32::new(0);
4119
4120 let mut world = World::new();
4121
4122 // SAFETY: the drop function is valid for the layout and the data will be safe to access from any thread
4123 let descriptor = unsafe {
4124 ComponentDescriptor::new_with_layout(
4125 "Custom Test Component".to_string(),
4126 StorageType::Table,
4127 core::alloc::Layout::new::<[u8; 8]>(),
4128 Some(|ptr| {
4129 let data = ptr.read::<[u8; 8]>();
4130 assert_eq!(data, [0, 1, 2, 3, 4, 5, 6, 7]);
4131 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4132 }),
4133 true,
4134 ComponentCloneBehavior::Default,
4135 None,
4136 )
4137 };
4138
4139 let component_id = world.register_resource_with_descriptor(descriptor);
4140
4141 let value: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
4142 OwningPtr::make(value, |ptr| {
4143 // SAFETY: value is valid for the component layout
4144 unsafe {
4145 world.insert_resource_by_id(component_id, ptr, MaybeLocation::caller());
4146 }
4147 });
4148
4149 // SAFETY: [u8; 8] is the correct type for the resource
4150 let data = unsafe {
4151 world
4152 .get_resource_by_id(component_id)
4153 .unwrap()
4154 .deref::<[u8; 8]>()
4155 };
4156 assert_eq!(*data, [0, 1, 2, 3, 4, 5, 6, 7]);
4157
4158 assert!(world.remove_resource_by_id(component_id).is_some());
4159
4160 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
4161 }
4162
4163 #[derive(Resource)]
4164 struct TestFromWorld(u32);
4165 impl FromWorld for TestFromWorld {
4166 fn from_world(world: &mut World) -> Self {
4167 let b = world.resource::<TestResource>();
4168 Self(b.0)
4169 }
4170 }
4171
4172 #[test]
4173 fn init_resource_does_not_overwrite() {
4174 let mut world = World::new();
4175 world.insert_resource(TestResource(0));
4176 world.init_resource::<TestFromWorld>();
4177 world.insert_resource(TestResource(1));
4178 world.init_resource::<TestFromWorld>();
4179
4180 let resource = world.resource::<TestFromWorld>();
4181
4182 assert_eq!(resource.0, 0);
4183 }
4184
4185 #[test]
4186 fn init_non_send_resource_does_not_overwrite() {
4187 let mut world = World::new();
4188 world.insert_resource(TestResource(0));
4189 world.init_non_send_resource::<TestFromWorld>();
4190 world.insert_resource(TestResource(1));
4191 world.init_non_send_resource::<TestFromWorld>();
4192
4193 let resource = world.non_send_resource::<TestFromWorld>();
4194
4195 assert_eq!(resource.0, 0);
4196 }
4197
4198 #[derive(Component)]
4199 struct Foo;
4200
4201 #[derive(Component)]
4202 struct Bar;
4203
4204 #[derive(Component)]
4205 struct Baz;
4206
4207 #[test]
4208 fn inspect_entity_components() {
4209 let mut world = World::new();
4210 let ent0 = world.spawn((Foo, Bar, Baz)).id();
4211 let ent1 = world.spawn((Foo, Bar)).id();
4212 let ent2 = world.spawn((Bar, Baz)).id();
4213 let ent3 = world.spawn((Foo, Baz)).id();
4214 let ent4 = world.spawn(Foo).id();
4215 let ent5 = world.spawn(Bar).id();
4216 let ent6 = world.spawn(Baz).id();
4217
4218 fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {
4219 component_infos
4220 .into_iter()
4221 .map(ComponentInfo::type_id)
4222 .collect()
4223 }
4224
4225 let foo_id = TypeId::of::<Foo>();
4226 let bar_id = TypeId::of::<Bar>();
4227 let baz_id = TypeId::of::<Baz>();
4228 assert_eq!(
4229 to_type_ids(world.inspect_entity(ent0).unwrap().collect()),
4230 [Some(foo_id), Some(bar_id), Some(baz_id)]
4231 .into_iter()
4232 .collect::<HashSet<_>>()
4233 );
4234 assert_eq!(
4235 to_type_ids(world.inspect_entity(ent1).unwrap().collect()),
4236 [Some(foo_id), Some(bar_id)]
4237 .into_iter()
4238 .collect::<HashSet<_>>()
4239 );
4240 assert_eq!(
4241 to_type_ids(world.inspect_entity(ent2).unwrap().collect()),
4242 [Some(bar_id), Some(baz_id)]
4243 .into_iter()
4244 .collect::<HashSet<_>>()
4245 );
4246 assert_eq!(
4247 to_type_ids(world.inspect_entity(ent3).unwrap().collect()),
4248 [Some(foo_id), Some(baz_id)]
4249 .into_iter()
4250 .collect::<HashSet<_>>()
4251 );
4252 assert_eq!(
4253 to_type_ids(world.inspect_entity(ent4).unwrap().collect()),
4254 [Some(foo_id)].into_iter().collect::<HashSet<_>>()
4255 );
4256 assert_eq!(
4257 to_type_ids(world.inspect_entity(ent5).unwrap().collect()),
4258 [Some(bar_id)].into_iter().collect::<HashSet<_>>()
4259 );
4260 assert_eq!(
4261 to_type_ids(world.inspect_entity(ent6).unwrap().collect()),
4262 [Some(baz_id)].into_iter().collect::<HashSet<_>>()
4263 );
4264 }
4265
4266 #[test]
4267 fn spawn_empty_bundle() {
4268 let mut world = World::new();
4269 world.spawn(());
4270 }
4271
4272 #[test]
4273 fn get_entity() {
4274 let mut world = World::new();
4275
4276 let e1 = world.spawn_empty().id();
4277 let e2 = world.spawn_empty().id();
4278
4279 assert!(world.get_entity(e1).is_ok());
4280 assert!(world.get_entity([e1, e2]).is_ok());
4281 assert!(world
4282 .get_entity(&[e1, e2] /* this is an array not a slice */)
4283 .is_ok());
4284 assert!(world.get_entity(&vec![e1, e2][..]).is_ok());
4285 assert!(world
4286 .get_entity(&EntityHashSet::from_iter([e1, e2]))
4287 .is_ok());
4288
4289 world.entity_mut(e1).despawn();
4290
4291 assert_eq!(
4292 Err(e1),
4293 world.get_entity(e1).map(|_| {}).map_err(|e| e.entity())
4294 );
4295 assert_eq!(
4296 Err(e1),
4297 world
4298 .get_entity([e1, e2])
4299 .map(|_| {})
4300 .map_err(|e| e.entity())
4301 );
4302 assert_eq!(
4303 Err(e1),
4304 world
4305 .get_entity(&[e1, e2] /* this is an array not a slice */)
4306 .map(|_| {})
4307 .map_err(|e| e.entity())
4308 );
4309 assert_eq!(
4310 Err(e1),
4311 world
4312 .get_entity(&vec![e1, e2][..])
4313 .map(|_| {})
4314 .map_err(|e| e.entity())
4315 );
4316 assert_eq!(
4317 Err(e1),
4318 world
4319 .get_entity(&EntityHashSet::from_iter([e1, e2]))
4320 .map(|_| {})
4321 .map_err(|e| e.entity())
4322 );
4323 }
4324
4325 #[test]
4326 fn get_entity_mut() {
4327 let mut world = World::new();
4328
4329 let e1 = world.spawn_empty().id();
4330 let e2 = world.spawn_empty().id();
4331
4332 assert!(world.get_entity_mut(e1).is_ok());
4333 assert!(world.get_entity_mut([e1, e2]).is_ok());
4334 assert!(world
4335 .get_entity_mut(&[e1, e2] /* this is an array not a slice */)
4336 .is_ok());
4337 assert!(world.get_entity_mut(&vec![e1, e2][..]).is_ok());
4338 assert!(world
4339 .get_entity_mut(&EntityHashSet::from_iter([e1, e2]))
4340 .is_ok());
4341
4342 assert_eq!(
4343 Err(EntityMutableFetchError::AliasedMutability(e1)),
4344 world.get_entity_mut([e1, e2, e1]).map(|_| {})
4345 );
4346 assert_eq!(
4347 Err(EntityMutableFetchError::AliasedMutability(e1)),
4348 world
4349 .get_entity_mut(&[e1, e2, e1] /* this is an array not a slice */)
4350 .map(|_| {})
4351 );
4352 assert_eq!(
4353 Err(EntityMutableFetchError::AliasedMutability(e1)),
4354 world.get_entity_mut(&vec![e1, e2, e1][..]).map(|_| {})
4355 );
4356 // Aliased mutability isn't allowed by HashSets
4357 assert!(world
4358 .get_entity_mut(&EntityHashSet::from_iter([e1, e2, e1]))
4359 .is_ok());
4360
4361 world.entity_mut(e1).despawn();
4362 assert!(world.get_entity_mut(e2).is_ok());
4363
4364 assert!(matches!(
4365 world.get_entity_mut(e1).map(|_| {}),
4366 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1
4367 ));
4368 assert!(matches!(
4369 world.get_entity_mut([e1, e2]).map(|_| {}),
4370 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));
4371 assert!(matches!(
4372 world
4373 .get_entity_mut(&[e1, e2] /* this is an array not a slice */)
4374 .map(|_| {}),
4375 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));
4376 assert!(matches!(
4377 world.get_entity_mut(&vec![e1, e2][..]).map(|_| {}),
4378 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1,
4379 ));
4380 assert!(matches!(
4381 world
4382 .get_entity_mut(&EntityHashSet::from_iter([e1, e2]))
4383 .map(|_| {}),
4384 Err(EntityMutableFetchError::NotSpawned(e)) if e.entity() == e1));
4385 }
4386
4387 #[test]
4388 #[track_caller]
4389 fn entity_spawn_despawn_tracking() {
4390 use core::panic::Location;
4391
4392 let mut world = World::new();
4393 let entity = world.spawn_empty().id();
4394 assert_eq!(
4395 world.entities.entity_get_spawned_or_despawned_by(entity),
4396 MaybeLocation::new(Some(Location::caller()))
4397 );
4398 assert_eq!(
4399 world.entities.entity_get_spawn_or_despawn_tick(entity),
4400 Some(world.change_tick())
4401 );
4402 world.despawn(entity);
4403 assert_eq!(
4404 world.entities.entity_get_spawned_or_despawned_by(entity),
4405 MaybeLocation::new(Some(Location::caller()))
4406 );
4407 assert_eq!(
4408 world.entities.entity_get_spawn_or_despawn_tick(entity),
4409 Some(world.change_tick())
4410 );
4411 let new = world.spawn_empty().id();
4412 assert_eq!(entity.index(), new.index());
4413 assert_eq!(
4414 world.entities.entity_get_spawned_or_despawned_by(entity),
4415 MaybeLocation::new(None)
4416 );
4417 assert_eq!(
4418 world.entities.entity_get_spawn_or_despawn_tick(entity),
4419 None
4420 );
4421 world.despawn(new);
4422 assert_eq!(
4423 world.entities.entity_get_spawned_or_despawned_by(entity),
4424 MaybeLocation::new(None)
4425 );
4426 assert_eq!(
4427 world.entities.entity_get_spawn_or_despawn_tick(entity),
4428 None
4429 );
4430 }
4431
4432 #[test]
4433 fn new_world_has_disabling() {
4434 let mut world = World::new();
4435 world.spawn(Foo);
4436 world.spawn((Foo, Disabled));
4437 assert_eq!(1, world.query::<&Foo>().iter(&world).count());
4438
4439 // If we explicitly remove the resource, no entities should be filtered anymore
4440 world.remove_resource::<DefaultQueryFilters>();
4441 assert_eq!(2, world.query::<&Foo>().iter(&world).count());
4442 }
4443
4444 #[test]
4445 fn entities_and_commands() {
4446 #[derive(Component, PartialEq, Debug)]
4447 struct Foo(u32);
4448
4449 let mut world = World::new();
4450
4451 let eid = world.spawn(Foo(35)).id();
4452
4453 let (mut fetcher, mut commands) = world.entities_and_commands();
4454 let emut = fetcher.get_mut(eid).unwrap();
4455 commands.entity(eid).despawn();
4456 assert_eq!(emut.get::<Foo>().unwrap(), &Foo(35));
4457
4458 world.flush();
4459
4460 assert!(world.get_entity(eid).is_err());
4461 }
4462
4463 #[test]
4464 fn entities_and_commands_deferred() {
4465 #[derive(Component, PartialEq, Debug)]
4466 struct Foo(u32);
4467
4468 let mut world = World::new();
4469
4470 let eid = world.spawn(Foo(1)).id();
4471
4472 let mut dworld = DeferredWorld::from(&mut world);
4473
4474 let (mut fetcher, mut commands) = dworld.entities_and_commands();
4475 let emut = fetcher.get_mut(eid).unwrap();
4476 commands.entity(eid).despawn();
4477 assert_eq!(emut.get::<Foo>().unwrap(), &Foo(1));
4478
4479 world.flush();
4480
4481 assert!(world.get_entity(eid).is_err());
4482 }
4483}