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