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