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