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