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