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#![doc = include_str!("../README.md")]
6#![cfg_attr(
7 any(docsrs, docsrs_dep),
8 expect(
9 internal_features,
10 reason = "rustdoc_internals is needed for fake_variadic"
11 )
12)]
13#![cfg_attr(any(docsrs, docsrs_dep), feature(doc_auto_cfg, rustdoc_internals))]
14#![expect(unsafe_code, reason = "Unsafe code is used to improve performance.")]
15#![doc(
16 html_logo_url = "https://bevyengine.org/assets/icon.png",
17 html_favicon_url = "https://bevyengine.org/assets/icon.png"
18)]
19#![no_std]
20
21#[cfg(feature = "std")]
22extern crate std;
23
24#[cfg(target_pointer_width = "16")]
25compile_error!("bevy_ecs cannot safely compile for a 16-bit platform.");
26
27extern crate alloc;
28
29extern crate self as bevy_ecs;
31
32pub mod archetype;
33pub mod batching;
34pub mod bundle;
35pub mod change_detection;
36pub mod component;
37pub mod entity;
38pub mod entity_disabling;
39pub mod error;
40pub mod event;
41pub mod hierarchy;
42pub mod identifier;
43pub mod intern;
44pub mod label;
45pub mod name;
46pub mod never;
47pub mod observer;
48pub mod query;
49#[cfg(feature = "bevy_reflect")]
50pub mod reflect;
51pub mod relationship;
52pub mod removal_detection;
53pub mod resource;
54pub mod schedule;
55pub mod spawn;
56pub mod storage;
57pub mod system;
58pub mod traversal;
59pub mod world;
60
61pub use bevy_ptr as ptr;
62
63pub mod prelude {
67 #[expect(
68 deprecated,
69 reason = "`crate::schedule::apply_deferred` is considered deprecated; however, it may still be used by crates which consume `bevy_ecs`, so its removal here may cause confusion. It is intended to be removed in the Bevy 0.17 cycle."
70 )]
71 #[doc(hidden)]
72 pub use crate::{
73 bundle::Bundle,
74 change_detection::{DetectChanges, DetectChangesMut, Mut, Ref},
75 children,
76 component::Component,
77 entity::{ContainsEntity, Entity, EntityMapper},
78 error::{BevyError, Result},
79 event::{Event, EventMutator, EventReader, EventWriter, Events},
80 hierarchy::{ChildOf, ChildSpawner, ChildSpawnerCommands, Children},
81 name::{Name, NameOrEntity},
82 observer::{Observer, Trigger},
83 query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without},
84 related,
85 relationship::RelationshipTarget,
86 removal_detection::RemovedComponents,
87 resource::Resource,
88 schedule::{
89 apply_deferred, common_conditions::*, ApplyDeferred, Condition, IntoScheduleConfigs,
90 IntoSystemSet, Schedule, Schedules, SystemSet,
91 },
92 spawn::{Spawn, SpawnRelated},
93 system::{
94 Command, Commands, Deferred, EntityCommand, EntityCommands, In, InMut, InRef,
95 IntoSystem, Local, NonSend, NonSendMut, ParamSet, Populated, Query, ReadOnlySystem,
96 Res, ResMut, Single, System, SystemIn, SystemInput, SystemParamBuilder,
97 SystemParamFunction,
98 },
99 world::{
100 EntityMut, EntityRef, EntityWorldMut, FilteredResources, FilteredResourcesMut,
101 FromWorld, OnAdd, OnInsert, OnRemove, OnReplace, World,
102 },
103 };
104
105 #[doc(hidden)]
106 #[cfg(feature = "std")]
107 pub use crate::system::ParallelCommands;
108
109 #[doc(hidden)]
110 #[cfg(feature = "bevy_reflect")]
111 pub use crate::reflect::{
112 AppTypeRegistry, ReflectComponent, ReflectFromWorld, ReflectResource,
113 };
114
115 #[doc(hidden)]
116 #[cfg(feature = "reflect_functions")]
117 pub use crate::reflect::AppFunctionRegistry;
118}
119
120#[doc(hidden)]
124pub mod __macro_exports {
125 pub use alloc::vec::Vec;
129}
130
131#[cfg(test)]
132mod tests {
133 use crate::{
134 bundle::Bundle,
135 change_detection::Ref,
136 component::{Component, ComponentId, RequiredComponents, RequiredComponentsError},
137 entity::{Entity, EntityMapper},
138 entity_disabling::DefaultQueryFilters,
139 prelude::Or,
140 query::{Added, Changed, FilteredAccess, QueryFilter, With, Without},
141 resource::Resource,
142 world::{EntityMut, EntityRef, Mut, World},
143 };
144 use alloc::{
145 string::{String, ToString},
146 sync::Arc,
147 vec,
148 vec::Vec,
149 };
150 use bevy_platform::collections::HashSet;
151 use bevy_tasks::{ComputeTaskPool, TaskPool};
152 use core::{
153 any::TypeId,
154 marker::PhantomData,
155 num::NonZero,
156 sync::atomic::{AtomicUsize, Ordering},
157 };
158 use std::sync::Mutex;
159
160 #[derive(Component, Resource, Debug, PartialEq, Eq, Hash, Clone, Copy)]
161 struct A(usize);
162 #[derive(Component, Debug, PartialEq, Eq, Hash, Clone, Copy)]
163 struct B(usize);
164 #[derive(Component, Debug, PartialEq, Eq, Clone, Copy)]
165 struct C;
166
167 #[derive(Default)]
168 struct NonSendA(PhantomData<*mut ()>);
169
170 #[derive(Component, Clone, Debug)]
171 struct DropCk(Arc<AtomicUsize>);
172 impl DropCk {
173 fn new_pair() -> (Self, Arc<AtomicUsize>) {
174 let atomic = Arc::new(AtomicUsize::new(0));
175 (DropCk(atomic.clone()), atomic)
176 }
177 }
178
179 impl Drop for DropCk {
180 fn drop(&mut self) {
181 self.0.as_ref().fetch_add(1, Ordering::Relaxed);
182 }
183 }
184
185 #[expect(
186 dead_code,
187 reason = "This struct is used to test how `Drop` behavior works in regards to SparseSet storage, and as such is solely a wrapper around `DropCk` to make it use the SparseSet storage. Because of this, the inner field is intentionally never read."
188 )]
189 #[derive(Component, Clone, Debug)]
190 #[component(storage = "SparseSet")]
191 struct DropCkSparse(DropCk);
192
193 #[derive(Component, Copy, Clone, PartialEq, Eq, Debug)]
194 #[component(storage = "Table")]
195 struct TableStored(&'static str);
196 #[derive(Component, Copy, Clone, PartialEq, Eq, Hash, Debug)]
197 #[component(storage = "SparseSet")]
198 struct SparseStored(u32);
199
200 #[test]
201 fn random_access() {
202 let mut world = World::new();
203
204 let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
205 let f = world
206 .spawn((TableStored("def"), SparseStored(456), A(1)))
207 .id();
208 assert_eq!(world.get::<TableStored>(e).unwrap().0, "abc");
209 assert_eq!(world.get::<SparseStored>(e).unwrap().0, 123);
210 assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
211 assert_eq!(world.get::<SparseStored>(f).unwrap().0, 456);
212
213 world.get_mut::<TableStored>(e).unwrap().0 = "xyz";
215 assert_eq!(world.get::<TableStored>(e).unwrap().0, "xyz");
216
217 world.get_mut::<SparseStored>(f).unwrap().0 = 42;
219 assert_eq!(world.get::<SparseStored>(f).unwrap().0, 42);
220 }
221
222 #[test]
223 fn bundle_derive() {
224 let mut world = World::new();
225
226 #[derive(Bundle, PartialEq, Debug)]
227 struct FooBundle {
228 x: TableStored,
229 y: SparseStored,
230 }
231 let mut ids = Vec::new();
232 <FooBundle as Bundle>::component_ids(&mut world.components_registrator(), &mut |id| {
233 ids.push(id);
234 });
235
236 assert_eq!(
237 ids,
238 &[
239 world.register_component::<TableStored>(),
240 world.register_component::<SparseStored>(),
241 ]
242 );
243
244 let e1 = world
245 .spawn(FooBundle {
246 x: TableStored("abc"),
247 y: SparseStored(123),
248 })
249 .id();
250 let e2 = world
251 .spawn((TableStored("def"), SparseStored(456), A(1)))
252 .id();
253 assert_eq!(world.get::<TableStored>(e1).unwrap().0, "abc");
254 assert_eq!(world.get::<SparseStored>(e1).unwrap().0, 123);
255 assert_eq!(world.get::<TableStored>(e2).unwrap().0, "def");
256 assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 456);
257
258 world.get_mut::<TableStored>(e1).unwrap().0 = "xyz";
260 assert_eq!(world.get::<TableStored>(e1).unwrap().0, "xyz");
261
262 world.get_mut::<SparseStored>(e2).unwrap().0 = 42;
264 assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 42);
265
266 assert_eq!(
267 world.entity_mut(e1).take::<FooBundle>().unwrap(),
268 FooBundle {
269 x: TableStored("xyz"),
270 y: SparseStored(123),
271 }
272 );
273
274 #[derive(Bundle, PartialEq, Debug)]
275 struct NestedBundle {
276 a: A,
277 foo: FooBundle,
278 b: B,
279 }
280
281 let mut ids = Vec::new();
282 <NestedBundle as Bundle>::component_ids(&mut world.components_registrator(), &mut |id| {
283 ids.push(id);
284 });
285
286 assert_eq!(
287 ids,
288 &[
289 world.register_component::<A>(),
290 world.register_component::<TableStored>(),
291 world.register_component::<SparseStored>(),
292 world.register_component::<B>(),
293 ]
294 );
295
296 let e3 = world
297 .spawn(NestedBundle {
298 a: A(1),
299 foo: FooBundle {
300 x: TableStored("ghi"),
301 y: SparseStored(789),
302 },
303 b: B(2),
304 })
305 .id();
306
307 assert_eq!(world.get::<TableStored>(e3).unwrap().0, "ghi");
308 assert_eq!(world.get::<SparseStored>(e3).unwrap().0, 789);
309 assert_eq!(world.get::<A>(e3).unwrap().0, 1);
310 assert_eq!(world.get::<B>(e3).unwrap().0, 2);
311 assert_eq!(
312 world.entity_mut(e3).take::<NestedBundle>().unwrap(),
313 NestedBundle {
314 a: A(1),
315 foo: FooBundle {
316 x: TableStored("ghi"),
317 y: SparseStored(789),
318 },
319 b: B(2),
320 }
321 );
322
323 #[derive(Default, Component, PartialEq, Debug)]
324 struct Ignored;
325
326 #[derive(Bundle, PartialEq, Debug)]
327 struct BundleWithIgnored {
328 c: C,
329 #[bundle(ignore)]
330 ignored: Ignored,
331 }
332
333 let mut ids = Vec::new();
334 <BundleWithIgnored as Bundle>::component_ids(
335 &mut world.components_registrator(),
336 &mut |id| {
337 ids.push(id);
338 },
339 );
340
341 assert_eq!(ids, &[world.register_component::<C>(),]);
342
343 let e4 = world
344 .spawn(BundleWithIgnored {
345 c: C,
346 ignored: Ignored,
347 })
348 .id();
349
350 assert_eq!(world.get::<C>(e4).unwrap(), &C);
351 assert_eq!(world.get::<Ignored>(e4), None);
352
353 assert_eq!(
354 world.entity_mut(e4).take::<BundleWithIgnored>().unwrap(),
355 BundleWithIgnored {
356 c: C,
357 ignored: Ignored,
358 }
359 );
360 }
361
362 #[test]
363 fn despawn_table_storage() {
364 let mut world = World::new();
365 let e = world.spawn((TableStored("abc"), A(123))).id();
366 let f = world.spawn((TableStored("def"), A(456))).id();
367 assert_eq!(world.entities.len(), 2);
368 assert!(world.despawn(e));
369 assert_eq!(world.entities.len(), 1);
370 assert!(world.get::<TableStored>(e).is_none());
371 assert!(world.get::<A>(e).is_none());
372 assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
373 assert_eq!(world.get::<A>(f).unwrap().0, 456);
374 }
375
376 #[test]
377 fn despawn_mixed_storage() {
378 let mut world = World::new();
379
380 let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
381 let f = world.spawn((TableStored("def"), SparseStored(456))).id();
382 assert_eq!(world.entities.len(), 2);
383 assert!(world.despawn(e));
384 assert_eq!(world.entities.len(), 1);
385 assert!(world.get::<TableStored>(e).is_none());
386 assert!(world.get::<SparseStored>(e).is_none());
387 assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
388 assert_eq!(world.get::<SparseStored>(f).unwrap().0, 456);
389 }
390
391 #[test]
392 fn query_all() {
393 let mut world = World::new();
394 let e = world.spawn((TableStored("abc"), A(123))).id();
395 let f = world.spawn((TableStored("def"), A(456))).id();
396
397 let ents = world
398 .query::<(Entity, &A, &TableStored)>()
399 .iter(&world)
400 .map(|(e, &i, &s)| (e, i, s))
401 .collect::<Vec<_>>();
402 assert_eq!(
403 ents,
404 &[
405 (e, A(123), TableStored("abc")),
406 (f, A(456), TableStored("def"))
407 ]
408 );
409 }
410
411 #[test]
412 fn query_all_for_each() {
413 let mut world = World::new();
414 let e = world.spawn((TableStored("abc"), A(123))).id();
415 let f = world.spawn((TableStored("def"), A(456))).id();
416
417 let mut results = Vec::new();
418 world
419 .query::<(Entity, &A, &TableStored)>()
420 .iter(&world)
421 .for_each(|(e, &i, &s)| results.push((e, i, s)));
422 assert_eq!(
423 results,
424 &[
425 (e, A(123), TableStored("abc")),
426 (f, A(456), TableStored("def"))
427 ]
428 );
429 }
430
431 #[test]
432 fn query_single_component() {
433 let mut world = World::new();
434 let e = world.spawn((TableStored("abc"), A(123))).id();
435 let f = world.spawn((TableStored("def"), A(456), B(1))).id();
436 let ents = world
437 .query::<(Entity, &A)>()
438 .iter(&world)
439 .map(|(e, &i)| (e, i))
440 .collect::<HashSet<_>>();
441 assert!(ents.contains(&(e, A(123))));
442 assert!(ents.contains(&(f, A(456))));
443 }
444
445 #[test]
446 fn stateful_query_handles_new_archetype() {
447 let mut world = World::new();
448 let e = world.spawn((TableStored("abc"), A(123))).id();
449 let mut query = world.query::<(Entity, &A)>();
450
451 let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
452 assert_eq!(ents, &[(e, A(123))]);
453
454 let f = world.spawn((TableStored("def"), A(456), B(1))).id();
455 let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
456 assert_eq!(ents, &[(e, A(123)), (f, A(456))]);
457 }
458
459 #[test]
460 fn query_single_component_for_each() {
461 let mut world = World::new();
462 let e = world.spawn((TableStored("abc"), A(123))).id();
463 let f = world.spawn((TableStored("def"), A(456), B(1))).id();
464 let mut results = <HashSet<_>>::default();
465 world
466 .query::<(Entity, &A)>()
467 .iter(&world)
468 .for_each(|(e, &i)| {
469 results.insert((e, i));
470 });
471 assert!(results.contains(&(e, A(123))));
472 assert!(results.contains(&(f, A(456))));
473 }
474
475 #[test]
476 fn par_for_each_dense() {
477 ComputeTaskPool::get_or_init(TaskPool::default);
478 let mut world = World::new();
479 let e1 = world.spawn(A(1)).id();
480 let e2 = world.spawn(A(2)).id();
481 let e3 = world.spawn(A(3)).id();
482 let e4 = world.spawn((A(4), B(1))).id();
483 let e5 = world.spawn((A(5), B(1))).id();
484 let results = Arc::new(Mutex::new(Vec::new()));
485 world
486 .query::<(Entity, &A)>()
487 .par_iter(&world)
488 .for_each(|(e, &A(i))| {
489 results.lock().unwrap().push((e, i));
490 });
491 results.lock().unwrap().sort();
492 assert_eq!(
493 &*results.lock().unwrap(),
494 &[(e1, 1), (e2, 2), (e3, 3), (e4, 4), (e5, 5)]
495 );
496 }
497
498 #[test]
499 fn par_for_each_sparse() {
500 ComputeTaskPool::get_or_init(TaskPool::default);
501 let mut world = World::new();
502 let e1 = world.spawn(SparseStored(1)).id();
503 let e2 = world.spawn(SparseStored(2)).id();
504 let e3 = world.spawn(SparseStored(3)).id();
505 let e4 = world.spawn((SparseStored(4), A(1))).id();
506 let e5 = world.spawn((SparseStored(5), A(1))).id();
507 let results = Arc::new(Mutex::new(Vec::new()));
508 world
509 .query::<(Entity, &SparseStored)>()
510 .par_iter(&world)
511 .for_each(|(e, &SparseStored(i))| results.lock().unwrap().push((e, i)));
512 results.lock().unwrap().sort();
513 assert_eq!(
514 &*results.lock().unwrap(),
515 &[(e1, 1), (e2, 2), (e3, 3), (e4, 4), (e5, 5)]
516 );
517 }
518
519 #[test]
520 fn query_missing_component() {
521 let mut world = World::new();
522 world.spawn((TableStored("abc"), A(123)));
523 world.spawn((TableStored("def"), A(456)));
524 assert!(world.query::<(&B, &A)>().iter(&world).next().is_none());
525 }
526
527 #[test]
528 fn query_sparse_component() {
529 let mut world = World::new();
530 world.spawn((TableStored("abc"), A(123)));
531 let f = world.spawn((TableStored("def"), A(456), B(1))).id();
532 let ents = world
533 .query::<(Entity, &B)>()
534 .iter(&world)
535 .map(|(e, &b)| (e, b))
536 .collect::<Vec<_>>();
537 assert_eq!(ents, &[(f, B(1))]);
538 }
539
540 #[test]
541 fn query_filter_with() {
542 let mut world = World::new();
543 world.spawn((A(123), B(1)));
544 world.spawn(A(456));
545 let result = world
546 .query_filtered::<&A, With<B>>()
547 .iter(&world)
548 .cloned()
549 .collect::<Vec<_>>();
550 assert_eq!(result, vec![A(123)]);
551 }
552
553 #[test]
554 fn query_filter_with_for_each() {
555 let mut world = World::new();
556 world.spawn((A(123), B(1)));
557 world.spawn(A(456));
558
559 let mut results = Vec::new();
560 world
561 .query_filtered::<&A, With<B>>()
562 .iter(&world)
563 .for_each(|i| results.push(*i));
564 assert_eq!(results, vec![A(123)]);
565 }
566
567 #[test]
568 fn query_filter_with_sparse() {
569 let mut world = World::new();
570
571 world.spawn((A(123), SparseStored(321)));
572 world.spawn(A(456));
573 let result = world
574 .query_filtered::<&A, With<SparseStored>>()
575 .iter(&world)
576 .cloned()
577 .collect::<Vec<_>>();
578 assert_eq!(result, vec![A(123)]);
579 }
580
581 #[test]
582 fn query_filter_with_sparse_for_each() {
583 let mut world = World::new();
584
585 world.spawn((A(123), SparseStored(321)));
586 world.spawn(A(456));
587 let mut results = Vec::new();
588 world
589 .query_filtered::<&A, With<SparseStored>>()
590 .iter(&world)
591 .for_each(|i| results.push(*i));
592 assert_eq!(results, vec![A(123)]);
593 }
594
595 #[test]
596 fn query_filter_without() {
597 let mut world = World::new();
598 world.spawn((A(123), B(321)));
599 world.spawn(A(456));
600 let result = world
601 .query_filtered::<&A, Without<B>>()
602 .iter(&world)
603 .cloned()
604 .collect::<Vec<_>>();
605 assert_eq!(result, vec![A(456)]);
606 }
607
608 #[test]
609 fn query_optional_component_table() {
610 let mut world = World::new();
611 let e = world.spawn((TableStored("abc"), A(123))).id();
612 let f = world.spawn((TableStored("def"), A(456), B(1))).id();
613 world.spawn(TableStored("abc"));
615 let ents = world
616 .query::<(Entity, Option<&B>, &A)>()
617 .iter(&world)
618 .map(|(e, b, &i)| (e, b.copied(), i))
619 .collect::<HashSet<_>>();
620 assert!(ents.contains(&(e, None, A(123))));
621 assert!(ents.contains(&(f, Some(B(1)), A(456))));
622 }
623
624 #[test]
625 fn query_optional_component_sparse() {
626 let mut world = World::new();
627
628 let e = world.spawn((TableStored("abc"), A(123))).id();
629 let f = world
630 .spawn((TableStored("def"), A(456), SparseStored(1)))
631 .id();
632 let ents = world
635 .query::<(Entity, Option<&SparseStored>, &A)>()
636 .iter(&world)
637 .map(|(e, b, &i)| (e, b.copied(), i))
638 .collect::<HashSet<_>>();
639 assert_eq!(
640 ents,
641 [(e, None, A(123)), (f, Some(SparseStored(1)), A(456))]
642 .into_iter()
643 .collect::<HashSet<_>>()
644 );
645 }
646
647 #[test]
648 fn query_optional_component_sparse_no_match() {
649 let mut world = World::new();
650
651 let e = world.spawn((TableStored("abc"), A(123))).id();
652 let f = world.spawn((TableStored("def"), A(456))).id();
653 world.spawn(TableStored("abc"));
655 let ents = world
656 .query::<(Entity, Option<&SparseStored>, &A)>()
657 .iter(&world)
658 .map(|(e, b, &i)| (e, b.copied(), i))
659 .collect::<Vec<_>>();
660 assert_eq!(ents, &[(e, None, A(123)), (f, None, A(456))]);
661 }
662
663 #[test]
664 fn add_remove_components() {
665 let mut world = World::new();
666 let e1 = world.spawn((A(1), B(3), TableStored("abc"))).id();
667 let e2 = world.spawn((A(2), B(4), TableStored("xyz"))).id();
668
669 assert_eq!(
670 world
671 .query::<(Entity, &A, &B)>()
672 .iter(&world)
673 .map(|(e, &i, &b)| (e, i, b))
674 .collect::<HashSet<_>>(),
675 [(e1, A(1), B(3)), (e2, A(2), B(4))]
676 .into_iter()
677 .collect::<HashSet<_>>()
678 );
679 assert_eq!(world.entity_mut(e1).take::<A>(), Some(A(1)));
680 assert_eq!(
681 world
682 .query::<(Entity, &A, &B)>()
683 .iter(&world)
684 .map(|(e, &i, &b)| (e, i, b))
685 .collect::<Vec<_>>(),
686 &[(e2, A(2), B(4))]
687 );
688 assert_eq!(
689 world
690 .query::<(Entity, &B, &TableStored)>()
691 .iter(&world)
692 .map(|(e, &B(b), &TableStored(s))| (e, b, s))
693 .collect::<HashSet<_>>(),
694 [(e2, 4, "xyz"), (e1, 3, "abc")]
695 .into_iter()
696 .collect::<HashSet<_>>()
697 );
698 world.entity_mut(e1).insert(A(43));
699 assert_eq!(
700 world
701 .query::<(Entity, &A, &B)>()
702 .iter(&world)
703 .map(|(e, &i, &b)| (e, i, b))
704 .collect::<HashSet<_>>(),
705 [(e2, A(2), B(4)), (e1, A(43), B(3))]
706 .into_iter()
707 .collect::<HashSet<_>>()
708 );
709 world.entity_mut(e1).insert(C);
710 assert_eq!(
711 world
712 .query::<(Entity, &C)>()
713 .iter(&world)
714 .map(|(e, &f)| (e, f))
715 .collect::<Vec<_>>(),
716 &[(e1, C)]
717 );
718 }
719
720 #[test]
721 fn table_add_remove_many() {
722 let mut world = World::default();
723 #[cfg(miri)]
724 let (mut entities, to) = {
725 let to = 10;
726 (Vec::with_capacity(to), to)
727 };
728 #[cfg(not(miri))]
729 let (mut entities, to) = {
730 let to = 10_000;
731 (Vec::with_capacity(to), to)
732 };
733
734 for _ in 0..to {
735 entities.push(world.spawn(B(0)).id());
736 }
737
738 for (i, entity) in entities.iter().cloned().enumerate() {
739 world.entity_mut(entity).insert(A(i));
740 }
741
742 for (i, entity) in entities.iter().cloned().enumerate() {
743 assert_eq!(world.entity_mut(entity).take::<A>(), Some(A(i)));
744 }
745 }
746
747 #[test]
748 fn sparse_set_add_remove_many() {
749 let mut world = World::default();
750
751 let mut entities = Vec::with_capacity(1000);
752 for _ in 0..4 {
753 entities.push(world.spawn(A(2)).id());
754 }
755
756 for (i, entity) in entities.iter().cloned().enumerate() {
757 world.entity_mut(entity).insert(SparseStored(i as u32));
758 }
759
760 for (i, entity) in entities.iter().cloned().enumerate() {
761 assert_eq!(
762 world.entity_mut(entity).take::<SparseStored>(),
763 Some(SparseStored(i as u32))
764 );
765 }
766 }
767
768 #[test]
769 fn remove_missing() {
770 let mut world = World::new();
771 let e = world.spawn((TableStored("abc"), A(123))).id();
772 assert!(world.entity_mut(e).take::<B>().is_none());
773 }
774
775 #[test]
776 fn spawn_batch() {
777 let mut world = World::new();
778 world.spawn_batch((0..100).map(|x| (A(x), TableStored("abc"))));
779 let values = world
780 .query::<&A>()
781 .iter(&world)
782 .map(|v| v.0)
783 .collect::<Vec<_>>();
784 let expected = (0..100).collect::<Vec<_>>();
785 assert_eq!(values, expected);
786 }
787
788 #[test]
789 fn query_get() {
790 let mut world = World::new();
791 let a = world.spawn((TableStored("abc"), A(123))).id();
792 let b = world.spawn((TableStored("def"), A(456))).id();
793 let c = world.spawn((TableStored("ghi"), A(789), B(1))).id();
794
795 let mut i32_query = world.query::<&A>();
796 assert_eq!(i32_query.get(&world, a).unwrap().0, 123);
797 assert_eq!(i32_query.get(&world, b).unwrap().0, 456);
798
799 let mut i32_bool_query = world.query::<(&A, &B)>();
800 assert!(i32_bool_query.get(&world, a).is_err());
801 assert_eq!(i32_bool_query.get(&world, c).unwrap(), (&A(789), &B(1)));
802 assert!(world.despawn(a));
803 assert!(i32_query.get(&world, a).is_err());
804 }
805
806 #[test]
807 fn query_get_works_across_sparse_removal() {
808 let mut world = World::new();
810 let a = world.spawn((TableStored("abc"), SparseStored(123))).id();
811 let b = world.spawn((TableStored("def"), SparseStored(456))).id();
812 let c = world
813 .spawn((TableStored("ghi"), SparseStored(789), B(1)))
814 .id();
815
816 let mut query = world.query::<&TableStored>();
817 assert_eq!(query.get(&world, a).unwrap(), &TableStored("abc"));
818 assert_eq!(query.get(&world, b).unwrap(), &TableStored("def"));
819 assert_eq!(query.get(&world, c).unwrap(), &TableStored("ghi"));
820
821 world.entity_mut(b).remove::<SparseStored>();
822 world.entity_mut(c).remove::<SparseStored>();
823
824 assert_eq!(query.get(&world, a).unwrap(), &TableStored("abc"));
825 assert_eq!(query.get(&world, b).unwrap(), &TableStored("def"));
826 assert_eq!(query.get(&world, c).unwrap(), &TableStored("ghi"));
827 }
828
829 #[test]
830 fn remove_tracking() {
831 let mut world = World::new();
832
833 let a = world.spawn((SparseStored(0), A(123))).id();
834 let b = world.spawn((SparseStored(1), A(123))).id();
835
836 world.entity_mut(a).despawn();
837 assert_eq!(
838 world.removed::<A>().collect::<Vec<_>>(),
839 &[a],
840 "despawning results in 'removed component' state for table components"
841 );
842 assert_eq!(
843 world.removed::<SparseStored>().collect::<Vec<_>>(),
844 &[a],
845 "despawning results in 'removed component' state for sparse set components"
846 );
847
848 world.entity_mut(b).insert(B(1));
849 assert_eq!(
850 world.removed::<A>().collect::<Vec<_>>(),
851 &[a],
852 "archetype moves does not result in 'removed component' state"
853 );
854
855 world.entity_mut(b).remove::<A>();
856 assert_eq!(
857 world.removed::<A>().collect::<Vec<_>>(),
858 &[a, b],
859 "removing a component results in a 'removed component' state"
860 );
861
862 world.clear_trackers();
863 assert_eq!(
864 world.removed::<A>().collect::<Vec<_>>(),
865 &[],
866 "clearing trackers clears removals"
867 );
868 assert_eq!(
869 world.removed::<SparseStored>().collect::<Vec<_>>(),
870 &[],
871 "clearing trackers clears removals"
872 );
873 assert_eq!(
874 world.removed::<B>().collect::<Vec<_>>(),
875 &[],
876 "clearing trackers clears removals"
877 );
878
879 }
899
900 #[test]
901 fn added_tracking() {
902 let mut world = World::new();
903 let a = world.spawn(A(123)).id();
904
905 assert_eq!(world.query::<&A>().iter(&world).count(), 1);
906 assert_eq!(
907 world.query_filtered::<(), Added<A>>().iter(&world).count(),
908 1
909 );
910 assert_eq!(world.query::<&A>().iter(&world).count(), 1);
911 assert_eq!(
912 world.query_filtered::<(), Added<A>>().iter(&world).count(),
913 1
914 );
915 assert!(world.query::<&A>().get(&world, a).is_ok());
916 assert!(world
917 .query_filtered::<(), Added<A>>()
918 .get(&world, a)
919 .is_ok());
920 assert!(world.query::<&A>().get(&world, a).is_ok());
921 assert!(world
922 .query_filtered::<(), Added<A>>()
923 .get(&world, a)
924 .is_ok());
925
926 world.clear_trackers();
927
928 assert_eq!(world.query::<&A>().iter(&world).count(), 1);
929 assert_eq!(
930 world.query_filtered::<(), Added<A>>().iter(&world).count(),
931 0
932 );
933 assert_eq!(world.query::<&A>().iter(&world).count(), 1);
934 assert_eq!(
935 world.query_filtered::<(), Added<A>>().iter(&world).count(),
936 0
937 );
938 assert!(world.query::<&A>().get(&world, a).is_ok());
939 assert!(world
940 .query_filtered::<(), Added<A>>()
941 .get(&world, a)
942 .is_err());
943 assert!(world.query::<&A>().get(&world, a).is_ok());
944 assert!(world
945 .query_filtered::<(), Added<A>>()
946 .get(&world, a)
947 .is_err());
948 }
949
950 #[test]
951 fn added_queries() {
952 let mut world = World::default();
953 let e1 = world.spawn(A(0)).id();
954
955 fn get_added<Com: Component>(world: &mut World) -> Vec<Entity> {
956 world
957 .query_filtered::<Entity, Added<Com>>()
958 .iter(world)
959 .collect::<Vec<Entity>>()
960 }
961
962 assert_eq!(get_added::<A>(&mut world), vec![e1]);
963 world.entity_mut(e1).insert(B(0));
964 assert_eq!(get_added::<A>(&mut world), vec![e1]);
965 assert_eq!(get_added::<B>(&mut world), vec![e1]);
966
967 world.clear_trackers();
968 assert!(get_added::<A>(&mut world).is_empty());
969 let e2 = world.spawn((A(1), B(1))).id();
970 assert_eq!(get_added::<A>(&mut world), vec![e2]);
971 assert_eq!(get_added::<B>(&mut world), vec![e2]);
972
973 let added = world
974 .query_filtered::<Entity, (Added<A>, Added<B>)>()
975 .iter(&world)
976 .collect::<Vec<Entity>>();
977 assert_eq!(added, vec![e2]);
978 }
979
980 #[test]
981 fn changed_trackers() {
982 let mut world = World::default();
983 let e1 = world.spawn((A(0), B(0))).id();
984 let e2 = world.spawn((A(0), B(0))).id();
985 let e3 = world.spawn((A(0), B(0))).id();
986 world.spawn((A(0), B(0)));
987
988 world.clear_trackers();
989
990 for (i, mut a) in world.query::<&mut A>().iter_mut(&mut world).enumerate() {
991 if i % 2 == 0 {
992 a.0 += 1;
993 }
994 }
995
996 fn get_filtered<F: QueryFilter>(world: &mut World) -> HashSet<Entity> {
997 world
998 .query_filtered::<Entity, F>()
999 .iter(world)
1000 .collect::<HashSet<Entity>>()
1001 }
1002
1003 assert_eq!(
1004 get_filtered::<Changed<A>>(&mut world),
1005 [e1, e3].into_iter().collect::<HashSet<_>>()
1006 );
1007
1008 world.entity_mut(e1).insert(C);
1010
1011 assert_eq!(
1012 get_filtered::<Changed<A>>(&mut world),
1013 [e3, e1].into_iter().collect::<HashSet<_>>(),
1014 "changed entities list should not change"
1015 );
1016
1017 world.entity_mut(e1).insert((A(0), B(0)));
1019
1020 assert_eq!(
1021 get_filtered::<Changed<A>>(&mut world),
1022 [e3, e1].into_iter().collect::<HashSet<_>>(),
1023 "changed entities list should not change"
1024 );
1025
1026 assert!(world.despawn(e2));
1028 assert_eq!(
1029 get_filtered::<Changed<A>>(&mut world),
1030 [e3, e1].into_iter().collect::<HashSet<_>>(),
1031 "changed entities list should not change"
1032 );
1033
1034 assert!(world.despawn(e1));
1036 assert_eq!(
1037 get_filtered::<Changed<A>>(&mut world),
1038 [e3].into_iter().collect::<HashSet<_>>(),
1039 "e1 should no longer be returned"
1040 );
1041
1042 world.clear_trackers();
1043
1044 assert!(get_filtered::<Changed<A>>(&mut world).is_empty());
1045
1046 let e4 = world.spawn_empty().id();
1047
1048 world.entity_mut(e4).insert(A(0));
1049 assert_eq!(
1050 get_filtered::<Changed<A>>(&mut world),
1051 [e4].into_iter().collect::<HashSet<_>>()
1052 );
1053 assert_eq!(
1054 get_filtered::<Added<A>>(&mut world),
1055 [e4].into_iter().collect::<HashSet<_>>()
1056 );
1057
1058 world.entity_mut(e4).insert(A(1));
1059 assert_eq!(
1060 get_filtered::<Changed<A>>(&mut world),
1061 [e4].into_iter().collect::<HashSet<_>>()
1062 );
1063
1064 world.clear_trackers();
1065
1066 world.entity_mut(e4).insert((A(0), B(0)));
1069
1070 assert!(get_filtered::<Added<A>>(&mut world).is_empty());
1071 assert_eq!(
1072 get_filtered::<Changed<A>>(&mut world),
1073 [e4].into_iter().collect::<HashSet<_>>()
1074 );
1075 assert_eq!(
1076 get_filtered::<Added<B>>(&mut world),
1077 [e4].into_iter().collect::<HashSet<_>>()
1078 );
1079 assert_eq!(
1080 get_filtered::<Changed<B>>(&mut world),
1081 [e4].into_iter().collect::<HashSet<_>>()
1082 );
1083 }
1084
1085 #[test]
1086 fn changed_trackers_sparse() {
1087 let mut world = World::default();
1088 let e1 = world.spawn(SparseStored(0)).id();
1089 let e2 = world.spawn(SparseStored(0)).id();
1090 let e3 = world.spawn(SparseStored(0)).id();
1091 world.spawn(SparseStored(0));
1092
1093 world.clear_trackers();
1094
1095 for (i, mut a) in world
1096 .query::<&mut SparseStored>()
1097 .iter_mut(&mut world)
1098 .enumerate()
1099 {
1100 if i % 2 == 0 {
1101 a.0 += 1;
1102 }
1103 }
1104
1105 fn get_filtered<F: QueryFilter>(world: &mut World) -> HashSet<Entity> {
1106 world
1107 .query_filtered::<Entity, F>()
1108 .iter(world)
1109 .collect::<HashSet<Entity>>()
1110 }
1111
1112 assert_eq!(
1113 get_filtered::<Changed<SparseStored>>(&mut world),
1114 [e1, e3].into_iter().collect::<HashSet<_>>()
1115 );
1116
1117 world.entity_mut(e1).insert(C);
1119
1120 assert_eq!(get_filtered::<Changed<SparseStored>>(&mut world), [e3, e1].into_iter().collect::<HashSet<_>>(), "changed entities list should not change (although the order will due to archetype moves)");
1121
1122 world.entity_mut(e1).insert(SparseStored(0));
1124 assert_eq!(
1125 get_filtered::<Changed<SparseStored>>(&mut world),
1126 [e3, e1].into_iter().collect::<HashSet<_>>(),
1127 "changed entities list should not change"
1128 );
1129
1130 assert!(world.despawn(e2));
1132 assert_eq!(
1133 get_filtered::<Changed<SparseStored>>(&mut world),
1134 [e3, e1].into_iter().collect::<HashSet<_>>(),
1135 "changed entities list should not change"
1136 );
1137
1138 assert!(world.despawn(e1));
1140 assert_eq!(
1141 get_filtered::<Changed<SparseStored>>(&mut world),
1142 [e3].into_iter().collect::<HashSet<_>>(),
1143 "e1 should no longer be returned"
1144 );
1145
1146 world.clear_trackers();
1147
1148 assert!(get_filtered::<Changed<SparseStored>>(&mut world).is_empty());
1149
1150 let e4 = world.spawn_empty().id();
1151
1152 world.entity_mut(e4).insert(SparseStored(0));
1153 assert_eq!(
1154 get_filtered::<Changed<SparseStored>>(&mut world),
1155 [e4].into_iter().collect::<HashSet<_>>()
1156 );
1157 assert_eq!(
1158 get_filtered::<Added<SparseStored>>(&mut world),
1159 [e4].into_iter().collect::<HashSet<_>>()
1160 );
1161
1162 world.entity_mut(e4).insert(A(1));
1163 assert_eq!(
1164 get_filtered::<Changed<SparseStored>>(&mut world),
1165 [e4].into_iter().collect::<HashSet<_>>()
1166 );
1167
1168 world.clear_trackers();
1169
1170 world.entity_mut(e4).insert(SparseStored(0));
1173
1174 assert!(get_filtered::<Added<SparseStored>>(&mut world).is_empty());
1175 assert_eq!(
1176 get_filtered::<Changed<SparseStored>>(&mut world),
1177 [e4].into_iter().collect::<HashSet<_>>()
1178 );
1179 }
1180
1181 #[test]
1182 fn empty_spawn() {
1183 let mut world = World::default();
1184 let e = world.spawn_empty().id();
1185 let mut e_mut = world.entity_mut(e);
1186 e_mut.insert(A(0));
1187 assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
1188 }
1189
1190 #[test]
1191 fn reserve_and_spawn() {
1192 let mut world = World::default();
1193 let e = world.entities().reserve_entity();
1194 world.flush_entities();
1195 let mut e_mut = world.entity_mut(e);
1196 e_mut.insert(A(0));
1197 assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
1198 }
1199
1200 #[test]
1201 fn changed_query() {
1202 let mut world = World::default();
1203 let e1 = world.spawn((A(0), B(0))).id();
1204
1205 fn get_changed(world: &mut World) -> Vec<Entity> {
1206 world
1207 .query_filtered::<Entity, Changed<A>>()
1208 .iter(world)
1209 .collect::<Vec<Entity>>()
1210 }
1211 assert_eq!(get_changed(&mut world), vec![e1]);
1212 world.clear_trackers();
1213 assert_eq!(get_changed(&mut world), vec![]);
1214 *world.get_mut(e1).unwrap() = A(1);
1215 assert_eq!(get_changed(&mut world), vec![e1]);
1216 }
1217
1218 #[test]
1219 fn resource() {
1220 use crate::resource::Resource;
1221
1222 #[derive(Resource, PartialEq, Debug)]
1223 struct Num(i32);
1224
1225 #[derive(Resource, PartialEq, Debug)]
1226 struct BigNum(u64);
1227
1228 let mut world = World::default();
1229 assert!(world.get_resource::<Num>().is_none());
1230 assert!(!world.contains_resource::<Num>());
1231 assert!(!world.is_resource_added::<Num>());
1232 assert!(!world.is_resource_changed::<Num>());
1233
1234 world.insert_resource(Num(123));
1235 let resource_id = world
1236 .components()
1237 .get_resource_id(TypeId::of::<Num>())
1238 .unwrap();
1239 let archetype_component_id = world.storages().resources.get(resource_id).unwrap().id();
1240
1241 assert_eq!(world.resource::<Num>().0, 123);
1242 assert!(world.contains_resource::<Num>());
1243 assert!(world.is_resource_added::<Num>());
1244 assert!(world.is_resource_changed::<Num>());
1245
1246 world.insert_resource(BigNum(456));
1247 assert_eq!(world.resource::<BigNum>().0, 456u64);
1248
1249 world.insert_resource(BigNum(789));
1250 assert_eq!(world.resource::<BigNum>().0, 789);
1251
1252 {
1253 let mut value = world.resource_mut::<BigNum>();
1254 assert_eq!(value.0, 789);
1255 value.0 = 10;
1256 }
1257
1258 assert_eq!(
1259 world.resource::<BigNum>().0,
1260 10,
1261 "resource changes are preserved"
1262 );
1263
1264 assert_eq!(
1265 world.remove_resource::<BigNum>(),
1266 Some(BigNum(10)),
1267 "removed resource has the correct value"
1268 );
1269 assert_eq!(
1270 world.get_resource::<BigNum>(),
1271 None,
1272 "removed resource no longer exists"
1273 );
1274 assert_eq!(
1275 world.remove_resource::<BigNum>(),
1276 None,
1277 "double remove returns nothing"
1278 );
1279
1280 world.insert_resource(BigNum(1));
1281 assert_eq!(
1282 world.get_resource::<BigNum>(),
1283 Some(&BigNum(1)),
1284 "re-inserting resources works"
1285 );
1286
1287 assert_eq!(
1288 world.get_resource::<Num>(),
1289 Some(&Num(123)),
1290 "other resources are unaffected"
1291 );
1292
1293 let current_resource_id = world
1294 .components()
1295 .get_resource_id(TypeId::of::<Num>())
1296 .unwrap();
1297 assert_eq!(
1298 resource_id, current_resource_id,
1299 "resource id does not change after removing / re-adding"
1300 );
1301
1302 let current_archetype_component_id =
1303 world.storages().resources.get(resource_id).unwrap().id();
1304
1305 assert_eq!(
1306 archetype_component_id, current_archetype_component_id,
1307 "resource archetype component id does not change after removing / re-adding"
1308 );
1309 }
1310
1311 #[test]
1312 fn remove() {
1313 let mut world = World::default();
1314 let e1 = world.spawn((A(1), B(1), TableStored("a"))).id();
1315
1316 let mut e = world.entity_mut(e1);
1317 assert_eq!(e.get::<TableStored>(), Some(&TableStored("a")));
1318 assert_eq!(e.get::<A>(), Some(&A(1)));
1319 assert_eq!(e.get::<B>(), Some(&B(1)));
1320 assert_eq!(
1321 e.get::<C>(),
1322 None,
1323 "C is not in the entity, so it should not exist"
1324 );
1325
1326 e.remove::<(A, B, C)>();
1327 assert_eq!(
1328 e.get::<TableStored>(),
1329 Some(&TableStored("a")),
1330 "TableStored is not in the removed bundle, so it should exist"
1331 );
1332 assert_eq!(
1333 e.get::<A>(),
1334 None,
1335 "Num is in the removed bundle, so it should not exist"
1336 );
1337 assert_eq!(
1338 e.get::<B>(),
1339 None,
1340 "f64 is in the removed bundle, so it should not exist"
1341 );
1342 assert_eq!(
1343 e.get::<C>(),
1344 None,
1345 "usize is in the removed bundle, so it should not exist"
1346 );
1347 }
1348
1349 #[test]
1350 fn take() {
1351 let mut world = World::default();
1352 world.spawn((A(1), B(1), TableStored("1")));
1353 let e2 = world.spawn((A(2), B(2), TableStored("2"))).id();
1354 world.spawn((A(3), B(3), TableStored("3")));
1355
1356 let mut query = world.query::<(&B, &TableStored)>();
1357 let results = query
1358 .iter(&world)
1359 .map(|(a, b)| (a.0, b.0))
1360 .collect::<HashSet<_>>();
1361 assert_eq!(
1362 results,
1363 [(1, "1"), (2, "2"), (3, "3"),]
1364 .into_iter()
1365 .collect::<HashSet<_>>()
1366 );
1367
1368 let removed_bundle = world.entity_mut(e2).take::<(B, TableStored)>().unwrap();
1369 assert_eq!(removed_bundle, (B(2), TableStored("2")));
1370
1371 let results = query
1372 .iter(&world)
1373 .map(|(a, b)| (a.0, b.0))
1374 .collect::<HashSet<_>>();
1375 assert_eq!(
1376 results,
1377 [(1, "1"), (3, "3"),].into_iter().collect::<HashSet<_>>()
1378 );
1379
1380 let mut a_query = world.query::<&A>();
1381 let results = a_query.iter(&world).map(|a| a.0).collect::<HashSet<_>>();
1382 assert_eq!(results, [1, 3, 2].into_iter().collect::<HashSet<_>>());
1383
1384 let entity_ref = world.entity(e2);
1385 assert_eq!(
1386 entity_ref.get::<A>(),
1387 Some(&A(2)),
1388 "A is not in the removed bundle, so it should exist"
1389 );
1390 assert_eq!(
1391 entity_ref.get::<B>(),
1392 None,
1393 "B is in the removed bundle, so it should not exist"
1394 );
1395 assert_eq!(
1396 entity_ref.get::<TableStored>(),
1397 None,
1398 "TableStored is in the removed bundle, so it should not exist"
1399 );
1400 }
1401
1402 #[test]
1403 fn non_send_resource() {
1404 let mut world = World::default();
1405 world.insert_non_send_resource(123i32);
1406 world.insert_non_send_resource(456i64);
1407 assert_eq!(*world.non_send_resource::<i32>(), 123);
1408 assert_eq!(*world.non_send_resource_mut::<i64>(), 456);
1409 }
1410
1411 #[test]
1412 fn non_send_resource_points_to_distinct_data() {
1413 let mut world = World::default();
1414 world.insert_resource(A(123));
1415 world.insert_non_send_resource(A(456));
1416 assert_eq!(*world.resource::<A>(), A(123));
1417 assert_eq!(*world.non_send_resource::<A>(), A(456));
1418 }
1419
1420 #[test]
1421 #[should_panic]
1422 fn non_send_resource_panic() {
1423 let mut world = World::default();
1424 world.insert_non_send_resource(0i32);
1425 std::thread::spawn(move || {
1426 let _ = world.non_send_resource_mut::<i32>();
1427 })
1428 .join()
1429 .unwrap();
1430 }
1431
1432 #[test]
1433 fn exact_size_query() {
1434 let mut world = World::default();
1435 world.spawn((A(0), B(0)));
1436 world.spawn((A(0), B(0)));
1437 world.spawn((A(0), B(0), C));
1438 world.spawn(C);
1439
1440 let mut query = world.query::<(&A, &B)>();
1441 assert_eq!(query.iter(&world).len(), 3);
1442 }
1443
1444 #[test]
1445 #[should_panic]
1446 fn duplicate_components_panic() {
1447 let mut world = World::new();
1448 world.spawn((A(1), A(2)));
1449 }
1450
1451 #[test]
1452 #[should_panic]
1453 fn ref_and_mut_query_panic() {
1454 let mut world = World::new();
1455 world.query::<(&A, &mut A)>();
1456 }
1457
1458 #[test]
1459 #[should_panic]
1460 fn entity_ref_and_mut_query_panic() {
1461 let mut world = World::new();
1462 world.query::<(EntityRef, &mut A)>();
1463 }
1464
1465 #[test]
1466 #[should_panic]
1467 fn mut_and_ref_query_panic() {
1468 let mut world = World::new();
1469 world.query::<(&mut A, &A)>();
1470 }
1471
1472 #[test]
1473 #[should_panic]
1474 fn mut_and_entity_ref_query_panic() {
1475 let mut world = World::new();
1476 world.query::<(&mut A, EntityRef)>();
1477 }
1478
1479 #[test]
1480 #[should_panic]
1481 fn entity_ref_and_entity_mut_query_panic() {
1482 let mut world = World::new();
1483 world.query::<(EntityRef, EntityMut)>();
1484 }
1485
1486 #[test]
1487 #[should_panic]
1488 fn entity_mut_and_entity_mut_query_panic() {
1489 let mut world = World::new();
1490 world.query::<(EntityMut, EntityMut)>();
1491 }
1492
1493 #[test]
1494 fn entity_ref_and_entity_ref_query_no_panic() {
1495 let mut world = World::new();
1496 world.query::<(EntityRef, EntityRef)>();
1497 }
1498
1499 #[test]
1500 #[should_panic]
1501 fn mut_and_mut_query_panic() {
1502 let mut world = World::new();
1503 world.query::<(&mut A, &mut A)>();
1504 }
1505
1506 #[test]
1507 #[should_panic]
1508 fn multiple_worlds_same_query_iter() {
1509 let mut world_a = World::new();
1510 let world_b = World::new();
1511 let mut query = world_a.query::<&A>();
1512 query.iter(&world_a);
1513 query.iter(&world_b);
1514 }
1515
1516 #[test]
1517 fn query_filters_dont_collide_with_fetches() {
1518 let mut world = World::new();
1519 world.query_filtered::<&mut A, Changed<A>>();
1520 }
1521
1522 #[test]
1523 fn filtered_query_access() {
1524 let mut world = World::new();
1525 world.remove_resource::<DefaultQueryFilters>();
1527 let query = world.query_filtered::<&mut A, Changed<B>>();
1528
1529 let mut expected = FilteredAccess::<ComponentId>::default();
1530 let a_id = world.components.get_id(TypeId::of::<A>()).unwrap();
1531 let b_id = world.components.get_id(TypeId::of::<B>()).unwrap();
1532 expected.add_component_write(a_id);
1533 expected.add_component_read(b_id);
1534 assert!(
1535 query.component_access.eq(&expected),
1536 "ComponentId access from query fetch and query filter should be combined"
1537 );
1538 }
1539
1540 #[test]
1541 #[should_panic]
1542 fn multiple_worlds_same_query_get() {
1543 let mut world_a = World::new();
1544 let world_b = World::new();
1545 let mut query = world_a.query::<&A>();
1546 let _ = query.get(&world_a, Entity::from_raw(0));
1547 let _ = query.get(&world_b, Entity::from_raw(0));
1548 }
1549
1550 #[test]
1551 #[should_panic]
1552 fn multiple_worlds_same_query_for_each() {
1553 let mut world_a = World::new();
1554 let world_b = World::new();
1555 let mut query = world_a.query::<&A>();
1556 query.iter(&world_a).for_each(|_| {});
1557 query.iter(&world_b).for_each(|_| {});
1558 }
1559
1560 #[test]
1561 fn resource_scope() {
1562 let mut world = World::default();
1563 assert!(world.try_resource_scope::<A, _>(|_, _| {}).is_none());
1564 world.insert_resource(A(0));
1565 world.resource_scope(|world: &mut World, mut value: Mut<A>| {
1566 value.0 += 1;
1567 assert!(!world.contains_resource::<A>());
1568 });
1569 assert_eq!(world.resource::<A>().0, 1);
1570 }
1571
1572 #[test]
1573 #[should_panic(
1574 expected = "Attempted to access or drop non-send resource bevy_ecs::tests::NonSendA from thread"
1575 )]
1576 fn non_send_resource_drop_from_different_thread() {
1577 let mut world = World::default();
1578 world.insert_non_send_resource(NonSendA::default());
1579
1580 let thread = std::thread::spawn(move || {
1581 drop(world);
1584 });
1585
1586 if let Err(err) = thread.join() {
1587 std::panic::resume_unwind(err);
1588 }
1589 }
1590
1591 #[test]
1592 fn non_send_resource_drop_from_same_thread() {
1593 let mut world = World::default();
1594 world.insert_non_send_resource(NonSendA::default());
1595 drop(world);
1596 }
1597
1598 #[test]
1599 fn insert_overwrite_drop() {
1600 let (dropck1, dropped1) = DropCk::new_pair();
1601 let (dropck2, dropped2) = DropCk::new_pair();
1602 let mut world = World::default();
1603 world.spawn(dropck1).insert(dropck2);
1604 assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1605 assert_eq!(dropped2.load(Ordering::Relaxed), 0);
1606 drop(world);
1607 assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1608 assert_eq!(dropped2.load(Ordering::Relaxed), 1);
1609 }
1610
1611 #[test]
1612 fn insert_overwrite_drop_sparse() {
1613 let (dropck1, dropped1) = DropCk::new_pair();
1614 let (dropck2, dropped2) = DropCk::new_pair();
1615 let mut world = World::default();
1616
1617 world
1618 .spawn(DropCkSparse(dropck1))
1619 .insert(DropCkSparse(dropck2));
1620 assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1621 assert_eq!(dropped2.load(Ordering::Relaxed), 0);
1622 drop(world);
1623 assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1624 assert_eq!(dropped2.load(Ordering::Relaxed), 1);
1625 }
1626
1627 #[test]
1628 fn clear_entities() {
1629 let mut world = World::default();
1630
1631 world.insert_resource(A(0));
1632 world.spawn(A(1));
1633 world.spawn(SparseStored(1));
1634
1635 let mut q1 = world.query::<&A>();
1636 let mut q2 = world.query::<&SparseStored>();
1637
1638 assert_eq!(q1.iter(&world).len(), 1);
1639 assert_eq!(q2.iter(&world).len(), 1);
1640 assert_eq!(world.entities().len(), 2);
1641
1642 world.clear_entities();
1643
1644 assert_eq!(
1645 q1.iter(&world).len(),
1646 0,
1647 "world should not contain table components"
1648 );
1649 assert_eq!(
1650 q2.iter(&world).len(),
1651 0,
1652 "world should not contain sparse set components"
1653 );
1654 assert_eq!(
1655 world.entities().len(),
1656 0,
1657 "world should not have any entities"
1658 );
1659 assert_eq!(
1660 world.resource::<A>().0,
1661 0,
1662 "world should still contain resources"
1663 );
1664 }
1665
1666 #[test]
1667 fn test_is_archetypal_size_hints() {
1668 let mut world = World::default();
1669 macro_rules! query_min_size {
1670 ($query:ty, $filter:ty) => {
1671 world
1672 .query_filtered::<$query, $filter>()
1673 .iter(&world)
1674 .size_hint()
1675 .0
1676 };
1677 }
1678
1679 world.spawn((A(1), B(1), C));
1680 world.spawn((A(1), C));
1681 world.spawn((A(1), B(1)));
1682 world.spawn((B(1), C));
1683 world.spawn(A(1));
1684 world.spawn(C);
1685 assert_eq!(2, query_min_size![(), (With<A>, Without<B>)]);
1686 assert_eq!(3, query_min_size![&B, Or<(With<A>, With<C>)>]);
1687 assert_eq!(1, query_min_size![&B, (With<A>, With<C>)]);
1688 assert_eq!(1, query_min_size![(&A, &B), With<C>]);
1689 assert_eq!(4, query_min_size![&A, ()], "Simple Archetypal");
1690 assert_eq!(4, query_min_size![Ref<A>, ()]);
1691 assert_eq!(0, query_min_size![(), Added<A>], "Simple Added");
1694 assert_eq!(0, query_min_size![(), Changed<A>], "Simple Changed");
1695 assert_eq!(0, query_min_size![(&A, &B), Changed<A>]);
1696 assert_eq!(0, query_min_size![&A, (Changed<A>, With<B>)]);
1697 assert_eq!(0, query_min_size![(&A, &B), Or<(Changed<A>, Changed<B>)>]);
1698 }
1699
1700 #[test]
1701 fn insert_or_spawn_batch() {
1702 let mut world = World::default();
1703 let e0 = world.spawn(A(0)).id();
1704 let e1 = Entity::from_raw(1);
1705
1706 let values = vec![(e0, (B(0), C)), (e1, (B(1), C))];
1707
1708 #[expect(
1709 deprecated,
1710 reason = "This needs to be supported for now, and therefore still needs the test."
1711 )]
1712 world.insert_or_spawn_batch(values).unwrap();
1713
1714 assert_eq!(
1715 world.get::<A>(e0),
1716 Some(&A(0)),
1717 "existing component was preserved"
1718 );
1719 assert_eq!(
1720 world.get::<B>(e0),
1721 Some(&B(0)),
1722 "pre-existing entity received correct B component"
1723 );
1724 assert_eq!(
1725 world.get::<B>(e1),
1726 Some(&B(1)),
1727 "new entity was spawned and received correct B component"
1728 );
1729 assert_eq!(
1730 world.get::<C>(e0),
1731 Some(&C),
1732 "pre-existing entity received C component"
1733 );
1734 assert_eq!(
1735 world.get::<C>(e1),
1736 Some(&C),
1737 "new entity was spawned and received C component"
1738 );
1739 }
1740
1741 #[test]
1742 fn insert_or_spawn_batch_invalid() {
1743 let mut world = World::default();
1744 let e0 = world.spawn(A(0)).id();
1745 let e1 = Entity::from_raw(1);
1746 let e2 = world.spawn_empty().id();
1747 let invalid_e2 =
1748 Entity::from_raw_and_generation(e2.index(), NonZero::<u32>::new(2).unwrap());
1749
1750 let values = vec![(e0, (B(0), C)), (e1, (B(1), C)), (invalid_e2, (B(2), C))];
1751
1752 #[expect(
1753 deprecated,
1754 reason = "This needs to be supported for now, and therefore still needs the test."
1755 )]
1756 let result = world.insert_or_spawn_batch(values);
1757
1758 assert_eq!(
1759 result,
1760 Err(vec![invalid_e2]),
1761 "e2 failed to be spawned or inserted into"
1762 );
1763
1764 assert_eq!(
1765 world.get::<A>(e0),
1766 Some(&A(0)),
1767 "existing component was preserved"
1768 );
1769 assert_eq!(
1770 world.get::<B>(e0),
1771 Some(&B(0)),
1772 "pre-existing entity received correct B component"
1773 );
1774 assert_eq!(
1775 world.get::<B>(e1),
1776 Some(&B(1)),
1777 "new entity was spawned and received correct B component"
1778 );
1779 assert_eq!(
1780 world.get::<C>(e0),
1781 Some(&C),
1782 "pre-existing entity received C component"
1783 );
1784 assert_eq!(
1785 world.get::<C>(e1),
1786 Some(&C),
1787 "new entity was spawned and received C component"
1788 );
1789 }
1790
1791 #[test]
1792 fn insert_batch() {
1793 let mut world = World::default();
1794 let e0 = world.spawn(A(0)).id();
1795 let e1 = world.spawn(B(0)).id();
1796
1797 let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1798
1799 world.insert_batch(values);
1800
1801 assert_eq!(
1802 world.get::<A>(e0),
1803 Some(&A(1)),
1804 "first entity's A component should have been replaced"
1805 );
1806 assert_eq!(
1807 world.get::<B>(e0),
1808 Some(&B(0)),
1809 "first entity should have received B component"
1810 );
1811 assert_eq!(
1812 world.get::<A>(e1),
1813 Some(&A(0)),
1814 "second entity should have received A component"
1815 );
1816 assert_eq!(
1817 world.get::<B>(e1),
1818 Some(&B(1)),
1819 "second entity's B component should have been replaced"
1820 );
1821 }
1822
1823 #[test]
1824 fn insert_batch_same_archetype() {
1825 let mut world = World::default();
1826 let e0 = world.spawn((A(0), B(0))).id();
1827 let e1 = world.spawn((A(0), B(0))).id();
1828 let e2 = world.spawn(B(0)).id();
1829
1830 let values = vec![(e0, (B(1), C)), (e1, (B(2), C)), (e2, (B(3), C))];
1831
1832 world.insert_batch(values);
1833 let mut query = world.query::<(Option<&A>, &B, &C)>();
1834 let component_values = query.get_many(&world, [e0, e1, e2]).unwrap();
1835
1836 assert_eq!(
1837 component_values,
1838 [(Some(&A(0)), &B(1), &C), (Some(&A(0)), &B(2), &C), (None, &B(3), &C)],
1839 "all entities should have had their B component replaced, received C component, and had their A component (or lack thereof) unchanged"
1840 );
1841 }
1842
1843 #[test]
1844 fn insert_batch_if_new() {
1845 let mut world = World::default();
1846 let e0 = world.spawn(A(0)).id();
1847 let e1 = world.spawn(B(0)).id();
1848
1849 let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1850
1851 world.insert_batch_if_new(values);
1852
1853 assert_eq!(
1854 world.get::<A>(e0),
1855 Some(&A(0)),
1856 "first entity's A component should not have been replaced"
1857 );
1858 assert_eq!(
1859 world.get::<B>(e0),
1860 Some(&B(0)),
1861 "first entity should have received B component"
1862 );
1863 assert_eq!(
1864 world.get::<A>(e1),
1865 Some(&A(0)),
1866 "second entity should have received A component"
1867 );
1868 assert_eq!(
1869 world.get::<B>(e1),
1870 Some(&B(0)),
1871 "second entity's B component should not have been replaced"
1872 );
1873 }
1874
1875 #[test]
1876 fn try_insert_batch() {
1877 let mut world = World::default();
1878 let e0 = world.spawn(A(0)).id();
1879 let e1 = Entity::from_raw(1);
1880
1881 let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1882
1883 let error = world.try_insert_batch(values).unwrap_err();
1884
1885 assert_eq!(e1, error.entities[0]);
1886
1887 assert_eq!(
1888 world.get::<A>(e0),
1889 Some(&A(1)),
1890 "first entity's A component should have been replaced"
1891 );
1892 assert_eq!(
1893 world.get::<B>(e0),
1894 Some(&B(0)),
1895 "first entity should have received B component"
1896 );
1897 }
1898
1899 #[test]
1900 fn try_insert_batch_if_new() {
1901 let mut world = World::default();
1902 let e0 = world.spawn(A(0)).id();
1903 let e1 = Entity::from_raw(1);
1904
1905 let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1906
1907 let error = world.try_insert_batch_if_new(values).unwrap_err();
1908
1909 assert_eq!(e1, error.entities[0]);
1910
1911 assert_eq!(
1912 world.get::<A>(e0),
1913 Some(&A(0)),
1914 "first entity's A component should not have been replaced"
1915 );
1916 assert_eq!(
1917 world.get::<B>(e0),
1918 Some(&B(0)),
1919 "first entity should have received B component"
1920 );
1921 }
1922
1923 #[test]
1924 fn required_components() {
1925 #[derive(Component)]
1926 #[require(Y)]
1927 struct X;
1928
1929 #[derive(Component)]
1930 #[require(Z = new_z())]
1931 struct Y {
1932 value: String,
1933 }
1934
1935 #[derive(Component)]
1936 struct Z(u32);
1937
1938 impl Default for Y {
1939 fn default() -> Self {
1940 Self {
1941 value: "hello".to_string(),
1942 }
1943 }
1944 }
1945
1946 fn new_z() -> Z {
1947 Z(7)
1948 }
1949
1950 let mut world = World::new();
1951 let id = world.spawn(X).id();
1952 assert_eq!(
1953 "hello",
1954 world.entity(id).get::<Y>().unwrap().value,
1955 "Y should have the default value"
1956 );
1957 assert_eq!(
1958 7,
1959 world.entity(id).get::<Z>().unwrap().0,
1960 "Z should have the value provided by the constructor defined in Y"
1961 );
1962
1963 let id = world
1964 .spawn((
1965 X,
1966 Y {
1967 value: "foo".to_string(),
1968 },
1969 ))
1970 .id();
1971 assert_eq!(
1972 "foo",
1973 world.entity(id).get::<Y>().unwrap().value,
1974 "Y should have the manually provided value"
1975 );
1976 assert_eq!(
1977 7,
1978 world.entity(id).get::<Z>().unwrap().0,
1979 "Z should have the value provided by the constructor defined in Y"
1980 );
1981
1982 let id = world.spawn((X, Z(8))).id();
1983 assert_eq!(
1984 "hello",
1985 world.entity(id).get::<Y>().unwrap().value,
1986 "Y should have the default value"
1987 );
1988 assert_eq!(
1989 8,
1990 world.entity(id).get::<Z>().unwrap().0,
1991 "Z should have the manually provided value"
1992 );
1993 }
1994
1995 #[test]
1996 fn generic_required_components() {
1997 #[derive(Component)]
1998 #[require(Y<usize>)]
1999 struct X;
2000
2001 #[derive(Component, Default)]
2002 struct Y<T> {
2003 value: T,
2004 }
2005
2006 let mut world = World::new();
2007 let id = world.spawn(X).id();
2008 assert_eq!(
2009 0,
2010 world.entity(id).get::<Y<usize>>().unwrap().value,
2011 "Y should have the default value"
2012 );
2013 }
2014
2015 #[test]
2016 fn required_components_spawn_nonexistent_hooks() {
2017 #[derive(Component)]
2018 #[require(Y)]
2019 struct X;
2020
2021 #[derive(Component, Default)]
2022 struct Y;
2023
2024 #[derive(Resource)]
2025 struct A(usize);
2026
2027 #[derive(Resource)]
2028 struct I(usize);
2029
2030 let mut world = World::new();
2031 world.insert_resource(A(0));
2032 world.insert_resource(I(0));
2033 world
2034 .register_component_hooks::<Y>()
2035 .on_add(|mut world, _| world.resource_mut::<A>().0 += 1)
2036 .on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);
2037
2038 assert!(world.spawn(X).contains::<Y>());
2040
2041 assert_eq!(world.resource::<A>().0, 1);
2042 assert_eq!(world.resource::<I>().0, 1);
2043 }
2044
2045 #[test]
2046 fn required_components_insert_existing_hooks() {
2047 #[derive(Component)]
2048 #[require(Y)]
2049 struct X;
2050
2051 #[derive(Component, Default)]
2052 struct Y;
2053
2054 #[derive(Resource)]
2055 struct A(usize);
2056
2057 #[derive(Resource)]
2058 struct I(usize);
2059
2060 let mut world = World::new();
2061 world.insert_resource(A(0));
2062 world.insert_resource(I(0));
2063 world
2064 .register_component_hooks::<Y>()
2065 .on_add(|mut world, _| world.resource_mut::<A>().0 += 1)
2066 .on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);
2067
2068 assert!(world.spawn_empty().insert(X).contains::<Y>());
2070
2071 assert_eq!(world.resource::<A>().0, 1);
2072 assert_eq!(world.resource::<I>().0, 1);
2073 }
2074
2075 #[test]
2076 fn required_components_take_leaves_required() {
2077 #[derive(Component)]
2078 #[require(Y)]
2079 struct X;
2080
2081 #[derive(Component, Default)]
2082 struct Y;
2083
2084 let mut world = World::new();
2085 let e = world.spawn(X).id();
2086 let _ = world.entity_mut(e).take::<X>().unwrap();
2087 assert!(world.entity_mut(e).contains::<Y>());
2088 }
2089
2090 #[test]
2091 fn required_components_retain_keeps_required() {
2092 #[derive(Component)]
2093 #[require(Y)]
2094 struct X;
2095
2096 #[derive(Component, Default)]
2097 struct Y;
2098
2099 #[derive(Component, Default)]
2100 struct Z;
2101
2102 let mut world = World::new();
2103 let e = world.spawn((X, Z)).id();
2104 world.entity_mut(e).retain::<X>();
2105 assert!(world.entity_mut(e).contains::<X>());
2106 assert!(world.entity_mut(e).contains::<Y>());
2107 assert!(!world.entity_mut(e).contains::<Z>());
2108 }
2109
2110 #[test]
2111 fn required_components_spawn_then_insert_no_overwrite() {
2112 #[derive(Component)]
2113 #[require(Y)]
2114 struct X;
2115
2116 #[derive(Component, Default)]
2117 struct Y(usize);
2118
2119 let mut world = World::new();
2120 let id = world.spawn((X, Y(10))).id();
2121 world.entity_mut(id).insert(X);
2122
2123 assert_eq!(
2124 10,
2125 world.entity(id).get::<Y>().unwrap().0,
2126 "Y should still have the manually provided value"
2127 );
2128 }
2129
2130 #[test]
2131 fn dynamic_required_components() {
2132 #[derive(Component)]
2133 #[require(Y)]
2134 struct X;
2135
2136 #[derive(Component, Default)]
2137 struct Y;
2138
2139 let mut world = World::new();
2140 let x_id = world.register_component::<X>();
2141
2142 let mut e = world.spawn_empty();
2143
2144 bevy_ptr::OwningPtr::make(X, |ptr| unsafe {
2146 e.insert_by_id(x_id, ptr);
2147 });
2148
2149 assert!(e.contains::<Y>());
2150 }
2151
2152 #[test]
2153 fn remove_component_and_its_runtime_required_components() {
2154 #[derive(Component)]
2155 struct X;
2156
2157 #[derive(Component, Default)]
2158 struct Y;
2159
2160 #[derive(Component, Default)]
2161 struct Z;
2162
2163 #[derive(Component)]
2164 struct V;
2165
2166 let mut world = World::new();
2167 world.register_required_components::<X, Y>();
2168 world.register_required_components::<Y, Z>();
2169
2170 let e = world.spawn((X, V)).id();
2171 assert!(world.entity(e).contains::<X>());
2172 assert!(world.entity(e).contains::<Y>());
2173 assert!(world.entity(e).contains::<Z>());
2174 assert!(world.entity(e).contains::<V>());
2175
2176 world.entity_mut(e).remove::<X>();
2178 assert!(!world.entity(e).contains::<X>());
2179 assert!(world.entity(e).contains::<Y>());
2180 assert!(world.entity(e).contains::<Z>());
2181 assert!(world.entity(e).contains::<V>());
2182
2183 world.entity_mut(e).insert(X);
2184 assert!(world.entity(e).contains::<X>());
2185 assert!(world.entity(e).contains::<Y>());
2186 assert!(world.entity(e).contains::<Z>());
2187 assert!(world.entity(e).contains::<V>());
2188
2189 world.entity_mut(e).remove_with_requires::<X>();
2191 assert!(!world.entity(e).contains::<X>());
2192 assert!(!world.entity(e).contains::<Y>());
2193 assert!(!world.entity(e).contains::<Z>());
2194 assert!(world.entity(e).contains::<V>());
2195 }
2196
2197 #[test]
2198 fn remove_component_and_its_required_components() {
2199 #[derive(Component)]
2200 #[require(Y)]
2201 struct X;
2202
2203 #[derive(Component, Default)]
2204 #[require(Z)]
2205 struct Y;
2206
2207 #[derive(Component, Default)]
2208 struct Z;
2209
2210 #[derive(Component)]
2211 struct V;
2212
2213 let mut world = World::new();
2214
2215 let e = world.spawn((X, V)).id();
2216 assert!(world.entity(e).contains::<X>());
2217 assert!(world.entity(e).contains::<Y>());
2218 assert!(world.entity(e).contains::<Z>());
2219 assert!(world.entity(e).contains::<V>());
2220
2221 world.entity_mut(e).remove::<X>();
2223 assert!(!world.entity(e).contains::<X>());
2224 assert!(world.entity(e).contains::<Y>());
2225 assert!(world.entity(e).contains::<Z>());
2226 assert!(world.entity(e).contains::<V>());
2227
2228 world.entity_mut(e).insert(X);
2229 assert!(world.entity(e).contains::<X>());
2230 assert!(world.entity(e).contains::<Y>());
2231 assert!(world.entity(e).contains::<Z>());
2232 assert!(world.entity(e).contains::<V>());
2233
2234 world.entity_mut(e).remove_with_requires::<X>();
2236 assert!(!world.entity(e).contains::<X>());
2237 assert!(!world.entity(e).contains::<Y>());
2238 assert!(!world.entity(e).contains::<Z>());
2239 assert!(world.entity(e).contains::<V>());
2240 }
2241
2242 #[test]
2243 fn remove_bundle_and_his_required_components() {
2244 #[derive(Component, Default)]
2245 #[require(Y)]
2246 struct X;
2247
2248 #[derive(Component, Default)]
2249 struct Y;
2250
2251 #[derive(Component, Default)]
2252 #[require(W)]
2253 struct Z;
2254
2255 #[derive(Component, Default)]
2256 struct W;
2257
2258 #[derive(Component)]
2259 struct V;
2260
2261 #[derive(Bundle, Default)]
2262 struct TestBundle {
2263 x: X,
2264 z: Z,
2265 }
2266
2267 let mut world = World::new();
2268 let e = world.spawn((TestBundle::default(), V)).id();
2269
2270 assert!(world.entity(e).contains::<X>());
2271 assert!(world.entity(e).contains::<Y>());
2272 assert!(world.entity(e).contains::<Z>());
2273 assert!(world.entity(e).contains::<W>());
2274 assert!(world.entity(e).contains::<V>());
2275
2276 world.entity_mut(e).remove_with_requires::<TestBundle>();
2277 assert!(!world.entity(e).contains::<X>());
2278 assert!(!world.entity(e).contains::<Y>());
2279 assert!(!world.entity(e).contains::<Z>());
2280 assert!(!world.entity(e).contains::<W>());
2281 assert!(world.entity(e).contains::<V>());
2282 }
2283
2284 #[test]
2285 fn runtime_required_components() {
2286 #[derive(Component)]
2289 struct X;
2290
2291 #[derive(Component)]
2292 struct Y {
2293 value: String,
2294 }
2295
2296 #[derive(Component)]
2297 struct Z(u32);
2298
2299 impl Default for Y {
2300 fn default() -> Self {
2301 Self {
2302 value: "hello".to_string(),
2303 }
2304 }
2305 }
2306
2307 let mut world = World::new();
2308
2309 world.register_required_components::<X, Y>();
2310 world.register_required_components_with::<Y, Z>(|| Z(7));
2311
2312 let id = world.spawn(X).id();
2313
2314 assert_eq!(
2315 "hello",
2316 world.entity(id).get::<Y>().unwrap().value,
2317 "Y should have the default value"
2318 );
2319 assert_eq!(
2320 7,
2321 world.entity(id).get::<Z>().unwrap().0,
2322 "Z should have the value provided by the constructor defined in Y"
2323 );
2324
2325 let id = world
2326 .spawn((
2327 X,
2328 Y {
2329 value: "foo".to_string(),
2330 },
2331 ))
2332 .id();
2333 assert_eq!(
2334 "foo",
2335 world.entity(id).get::<Y>().unwrap().value,
2336 "Y should have the manually provided value"
2337 );
2338 assert_eq!(
2339 7,
2340 world.entity(id).get::<Z>().unwrap().0,
2341 "Z should have the value provided by the constructor defined in Y"
2342 );
2343
2344 let id = world.spawn((X, Z(8))).id();
2345 assert_eq!(
2346 "hello",
2347 world.entity(id).get::<Y>().unwrap().value,
2348 "Y should have the default value"
2349 );
2350 assert_eq!(
2351 8,
2352 world.entity(id).get::<Z>().unwrap().0,
2353 "Z should have the manually provided value"
2354 );
2355 }
2356
2357 #[test]
2358 fn runtime_required_components_override_1() {
2359 #[derive(Component)]
2360 struct X;
2361
2362 #[derive(Component, Default)]
2363 struct Y;
2364
2365 #[derive(Component)]
2366 struct Z(u32);
2367
2368 let mut world = World::new();
2369
2370 world.register_required_components::<X, Y>();
2374 world.register_required_components_with::<Y, Z>(|| Z(5));
2375 world.register_required_components_with::<X, Z>(|| Z(7));
2376
2377 let id = world.spawn(X).id();
2378
2379 assert_eq!(
2380 7,
2381 world.entity(id).get::<Z>().unwrap().0,
2382 "Z should have the value provided by the constructor defined in X"
2383 );
2384 }
2385
2386 #[test]
2387 fn runtime_required_components_override_2() {
2388 #[derive(Component)]
2391 struct X;
2392
2393 #[derive(Component, Default)]
2394 struct Y;
2395
2396 #[derive(Component)]
2397 struct Z(u32);
2398
2399 let mut world = World::new();
2400
2401 world.register_required_components::<X, Y>();
2405 world.register_required_components_with::<X, Z>(|| Z(7));
2406 world.register_required_components_with::<Y, Z>(|| Z(5));
2407
2408 let id = world.spawn(X).id();
2409
2410 assert_eq!(
2411 7,
2412 world.entity(id).get::<Z>().unwrap().0,
2413 "Z should have the value provided by the constructor defined in X"
2414 );
2415 }
2416
2417 #[test]
2418 fn runtime_required_components_propagate_up() {
2419 #[derive(Component)]
2421 #[require(B)]
2422 struct A;
2423
2424 #[derive(Component, Default)]
2425 struct B;
2426
2427 #[derive(Component, Default)]
2428 struct C;
2429
2430 let mut world = World::new();
2431
2432 world.register_required_components::<B, C>();
2435
2436 let id = world.spawn(A).id();
2437
2438 assert!(world.entity(id).get::<C>().is_some());
2439 }
2440
2441 #[test]
2442 fn runtime_required_components_propagate_up_even_more() {
2443 #[derive(Component)]
2444 struct A;
2445
2446 #[derive(Component, Default)]
2447 struct B;
2448
2449 #[derive(Component, Default)]
2450 struct C;
2451
2452 #[derive(Component, Default)]
2453 struct D;
2454
2455 let mut world = World::new();
2456
2457 world.register_required_components::<A, B>();
2458 world.register_required_components::<B, C>();
2459 world.register_required_components::<C, D>();
2460
2461 let id = world.spawn(A).id();
2462
2463 assert!(world.entity(id).get::<D>().is_some());
2464 }
2465
2466 #[test]
2467 fn runtime_required_components_deep_require_does_not_override_shallow_require() {
2468 #[derive(Component)]
2469 struct A;
2470 #[derive(Component, Default)]
2471 struct B;
2472 #[derive(Component, Default)]
2473 struct C;
2474 #[derive(Component)]
2475 struct Counter(i32);
2476 #[derive(Component, Default)]
2477 struct D;
2478
2479 let mut world = World::new();
2480
2481 world.register_required_components::<A, B>();
2482 world.register_required_components::<B, C>();
2483 world.register_required_components::<C, D>();
2484 world.register_required_components_with::<D, Counter>(|| Counter(2));
2485 world.register_required_components_with::<C, Counter>(|| Counter(1));
2488
2489 let id = world.spawn(A).id();
2490
2491 assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);
2493 }
2494
2495 #[test]
2496 fn runtime_required_components_deep_require_does_not_override_shallow_require_deep_subtree_after_shallow(
2497 ) {
2498 #[derive(Component)]
2499 struct A;
2500 #[derive(Component, Default)]
2501 struct B;
2502 #[derive(Component, Default)]
2503 struct C;
2504 #[derive(Component, Default)]
2505 struct D;
2506 #[derive(Component, Default)]
2507 struct E;
2508 #[derive(Component)]
2509 struct Counter(i32);
2510 #[derive(Component, Default)]
2511 struct F;
2512
2513 let mut world = World::new();
2514
2515 world.register_required_components::<A, B>();
2516 world.register_required_components::<B, C>();
2517 world.register_required_components::<C, D>();
2518 world.register_required_components::<D, E>();
2519 world.register_required_components_with::<E, Counter>(|| Counter(1));
2520 world.register_required_components_with::<F, Counter>(|| Counter(2));
2521 world.register_required_components::<E, F>();
2522
2523 let id = world.spawn(A).id();
2524
2525 assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);
2527 }
2528
2529 #[test]
2530 fn runtime_required_components_existing_archetype() {
2531 #[derive(Component)]
2532 struct X;
2533
2534 #[derive(Component, Default)]
2535 struct Y;
2536
2537 let mut world = World::new();
2538
2539 world.spawn(X);
2542 assert!(matches!(
2543 world.try_register_required_components::<X, Y>(),
2544 Err(RequiredComponentsError::ArchetypeExists(_))
2545 ));
2546 }
2547
2548 #[test]
2549 fn runtime_required_components_fail_with_duplicate() {
2550 #[derive(Component)]
2551 #[require(Y)]
2552 struct X;
2553
2554 #[derive(Component, Default)]
2555 struct Y;
2556
2557 let mut world = World::new();
2558
2559 assert!(matches!(
2561 world.try_register_required_components::<X, Y>(),
2562 Err(RequiredComponentsError::DuplicateRegistration(_, _))
2563 ));
2564 }
2565
2566 #[test]
2567 fn required_components_inheritance_depth() {
2568 #[derive(Component, Default)]
2584 #[require(B)]
2585 struct A;
2586
2587 #[derive(Component, Default)]
2588 #[require(C)]
2589 struct B;
2590
2591 #[derive(Component, Default)]
2592 struct C;
2593
2594 #[derive(Component, Default)]
2595 struct X;
2596
2597 #[derive(Component, Default)]
2598 struct Y;
2599
2600 #[derive(Component, Default)]
2601 struct Z;
2602
2603 let mut world = World::new();
2604
2605 let a = world.register_component::<A>();
2606 let b = world.register_component::<B>();
2607 let c = world.register_component::<C>();
2608 let y = world.register_component::<Y>();
2609 let z = world.register_component::<Z>();
2610
2611 world.register_required_components::<X, A>();
2612 world.register_required_components::<X, Y>();
2613 world.register_required_components::<Y, Z>();
2614 world.register_required_components::<Z, B>();
2615
2616 world.spawn(X);
2617
2618 let required_a = world.get_required_components::<A>().unwrap();
2619 let required_b = world.get_required_components::<B>().unwrap();
2620 let required_c = world.get_required_components::<C>().unwrap();
2621 let required_x = world.get_required_components::<X>().unwrap();
2622 let required_y = world.get_required_components::<Y>().unwrap();
2623 let required_z = world.get_required_components::<Z>().unwrap();
2624
2625 fn to_vec(required: &RequiredComponents) -> Vec<(ComponentId, u16)> {
2628 let mut vec = required
2629 .0
2630 .iter()
2631 .map(|(id, component)| (*id, component.inheritance_depth))
2632 .collect::<Vec<_>>();
2633 vec.sort_by_key(|(id, _)| *id);
2634 vec
2635 }
2636
2637 assert_eq!(to_vec(required_a), vec![(b, 0), (c, 1)]);
2639 assert_eq!(to_vec(required_b), vec![(c, 0)]);
2640 assert_eq!(to_vec(required_c), vec![]);
2641 assert_eq!(
2642 to_vec(required_x),
2643 vec![(a, 0), (b, 1), (c, 2), (y, 0), (z, 1)]
2644 );
2645 assert_eq!(to_vec(required_y), vec![(b, 1), (c, 2), (z, 0)]);
2646 assert_eq!(to_vec(required_z), vec![(b, 0), (c, 1)]);
2647 }
2648
2649 #[test]
2650 fn required_components_inheritance_depth_bias() {
2651 #[derive(Component, PartialEq, Eq, Clone, Copy, Debug)]
2652 struct MyRequired(bool);
2653
2654 #[derive(Component, Default)]
2655 #[require(MyRequired(false))]
2656 struct MiddleMan;
2657
2658 #[derive(Component, Default)]
2659 #[require(MiddleMan)]
2660 struct ConflictingRequire;
2661
2662 #[derive(Component, Default)]
2663 #[require(MyRequired(true))]
2664 struct MyComponent;
2665
2666 let mut world = World::new();
2667 let order_a = world
2668 .spawn((ConflictingRequire, MyComponent))
2669 .get::<MyRequired>()
2670 .cloned();
2671 let order_b = world
2672 .spawn((MyComponent, ConflictingRequire))
2673 .get::<MyRequired>()
2674 .cloned();
2675
2676 assert_eq!(order_a, Some(MyRequired(true)));
2677 assert_eq!(order_b, Some(MyRequired(true)));
2678 }
2679
2680 #[test]
2681 #[should_panic = "Recursive required components detected: A → B → C → B\nhelp: If this is intentional, consider merging the components."]
2682 fn required_components_recursion_errors() {
2683 #[derive(Component, Default)]
2684 #[require(B)]
2685 struct A;
2686
2687 #[derive(Component, Default)]
2688 #[require(C)]
2689 struct B;
2690
2691 #[derive(Component, Default)]
2692 #[require(B)]
2693 struct C;
2694
2695 World::new().register_component::<A>();
2696 }
2697
2698 #[test]
2699 #[should_panic = "Recursive required components detected: A → A\nhelp: Remove require(A)."]
2700 fn required_components_self_errors() {
2701 #[derive(Component, Default)]
2702 #[require(A)]
2703 struct A;
2704
2705 World::new().register_component::<A>();
2706 }
2707
2708 #[derive(Default)]
2709 struct CaptureMapper(Vec<Entity>);
2710 impl EntityMapper for CaptureMapper {
2711 fn get_mapped(&mut self, source: Entity) -> Entity {
2712 self.0.push(source);
2713 source
2714 }
2715
2716 fn set_mapped(&mut self, _source: Entity, _target: Entity) {}
2717 }
2718
2719 #[test]
2720 fn map_struct_entities() {
2721 #[derive(Component)]
2722 #[expect(
2723 unused,
2724 reason = "extra fields are used to ensure the derive works properly"
2725 )]
2726 struct Foo(usize, #[entities] Entity);
2727
2728 #[derive(Component)]
2729 #[expect(
2730 unused,
2731 reason = "extra fields are used to ensure the derive works properly"
2732 )]
2733 struct Bar {
2734 #[entities]
2735 a: Entity,
2736 b: usize,
2737 #[entities]
2738 c: Vec<Entity>,
2739 }
2740
2741 let mut world = World::new();
2742 let e1 = world.spawn_empty().id();
2743 let e2 = world.spawn_empty().id();
2744 let e3 = world.spawn_empty().id();
2745
2746 let mut foo = Foo(1, e1);
2747 let mut mapper = CaptureMapper::default();
2748 Component::map_entities(&mut foo, &mut mapper);
2749 assert_eq!(&mapper.0, &[e1]);
2750
2751 let mut bar = Bar {
2752 a: e1,
2753 b: 1,
2754 c: vec![e2, e3],
2755 };
2756 let mut mapper = CaptureMapper::default();
2757 Component::map_entities(&mut bar, &mut mapper);
2758 assert_eq!(&mapper.0, &[e1, e2, e3]);
2759 }
2760
2761 #[test]
2762 fn map_enum_entities() {
2763 #[derive(Component)]
2764 #[expect(
2765 unused,
2766 reason = "extra fields are used to ensure the derive works properly"
2767 )]
2768 enum Foo {
2769 Bar(usize, #[entities] Entity),
2770 Baz {
2771 #[entities]
2772 a: Entity,
2773 b: usize,
2774 #[entities]
2775 c: Vec<Entity>,
2776 },
2777 }
2778
2779 let mut world = World::new();
2780 let e1 = world.spawn_empty().id();
2781 let e2 = world.spawn_empty().id();
2782 let e3 = world.spawn_empty().id();
2783
2784 let mut foo = Foo::Bar(1, e1);
2785 let mut mapper = CaptureMapper::default();
2786 Component::map_entities(&mut foo, &mut mapper);
2787 assert_eq!(&mapper.0, &[e1]);
2788
2789 let mut foo = Foo::Baz {
2790 a: e1,
2791 b: 1,
2792 c: vec![e2, e3],
2793 };
2794 let mut mapper = CaptureMapper::default();
2795 Component::map_entities(&mut foo, &mut mapper);
2796 assert_eq!(&mapper.0, &[e1, e2, e3]);
2797 }
2798
2799 #[expect(
2800 dead_code,
2801 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
2802 )]
2803 #[derive(Component)]
2804 struct ComponentA(u32);
2805
2806 #[expect(
2807 dead_code,
2808 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
2809 )]
2810 #[derive(Component)]
2811 struct ComponentB(u32);
2812
2813 #[derive(Bundle)]
2814 struct Simple(ComponentA);
2815
2816 #[derive(Bundle)]
2817 struct Tuple(Simple, ComponentB);
2818
2819 #[derive(Bundle)]
2820 struct Record {
2821 field0: Simple,
2822 field1: ComponentB,
2823 }
2824
2825 #[derive(Component)]
2826 struct MyEntities {
2827 #[entities]
2828 entities: Vec<Entity>,
2829 #[entities]
2830 another_one: Entity,
2831 #[entities]
2832 maybe_entity: Option<Entity>,
2833 #[expect(
2834 dead_code,
2835 reason = "This struct is used as a compilation test to test the derive macros, and as such this field is intentionally never used."
2836 )]
2837 something_else: String,
2838 }
2839
2840 #[expect(
2841 dead_code,
2842 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
2843 )]
2844 #[derive(Component)]
2845 struct MyEntitiesTuple(#[entities] Vec<Entity>, #[entities] Entity, usize);
2846}