bevy_ecs/
lib.rs

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
29// Required to make proc macros work in bevy itself.
30extern 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
63/// The ECS prelude.
64///
65/// This includes the most common types in this crate, re-exported for your convenience.
66pub 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/// Exports used by macros.
121///
122/// These are not meant to be used directly and are subject to breaking changes.
123#[doc(hidden)]
124pub mod __macro_exports {
125    // Cannot directly use `alloc::vec::Vec` in macros, as a crate may not have
126    // included `extern crate alloc;`. This re-export ensures we have access
127    // to `Vec` in `no_std` and `std` contexts.
128    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        // test archetype get_mut()
214        world.get_mut::<TableStored>(e).unwrap().0 = "xyz";
215        assert_eq!(world.get::<TableStored>(e).unwrap().0, "xyz");
216
217        // test sparse set get_mut()
218        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        // test archetype get_mut()
259        world.get_mut::<TableStored>(e1).unwrap().0 = "xyz";
260        assert_eq!(world.get::<TableStored>(e1).unwrap().0, "xyz");
261
262        // test sparse set get_mut()
263        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        // this should be skipped
614        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        // this should be skipped
633        // world.spawn(SparseStored(1));
634        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        // // this should be skipped
654        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        // Regression test for: https://github.com/bevyengine/bevy/issues/6623
809        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        // TODO: uncomment when world.clear() is implemented
880        // let c = world.spawn(("abc", 123)).id();
881        // let d = world.spawn(("abc", 123)).id();
882        // world.clear();
883        // assert_eq!(
884        //     world.removed::<i32>(),
885        //     &[c, d],
886        //     "world clears result in 'removed component' states"
887        // );
888        // assert_eq!(
889        //     world.removed::<&'static str>(),
890        //     &[c, d, b],
891        //     "world clears result in 'removed component' states"
892        // );
893        // assert_eq!(
894        //     world.removed::<f64>(),
895        //     &[b],
896        //     "world clears result in 'removed component' states"
897        // );
898    }
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        // ensure changing an entity's archetypes also moves its changed state
1009        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        // spawning a new A entity should not change existing changed state
1018        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        // removing an unchanged entity should not change changed state
1027        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        // removing a changed entity should remove it from enumeration
1035        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        // ensure inserting multiple components set changed state for all components and set added
1067        // state for non existing components even when changing archetype.
1068        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        // ensure changing an entity's archetypes also moves its changed state
1118        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        // spawning a new SparseStored entity should not change existing changed state
1123        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        // removing an unchanged entity should not change changed state
1131        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        // removing a changed entity should remove it from enumeration
1139        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        // ensure inserting multiple components set changed state for all components and set added
1171        // state for non existing components even when changing archetype.
1172        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        // We remove entity disabling so it doesn't affect our query filters
1526        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            // Dropping the non-send resource on a different thread
1582            // Should result in a panic
1583            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        // All the following should set minimum size to 0, as it's impossible to predict
1692        // how many entities the filters will trim.
1693        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        // Spawn entity and ensure Y was added
2039        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        // Spawn entity and ensure Y was added
2069        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        // SAFETY: x_id is a valid component id
2145        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        //check that `remove` works as expected
2177        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        //remove `X` again and ensure that `Y` and `Z` was removed too
2190        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        //check that `remove` works as expected
2222        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        //remove `X` again and ensure that `Y` and `Z` was removed too
2235        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        // Same as `required_components` test but with runtime registration
2287
2288        #[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        // - X requires Y with default constructor
2371        // - Y requires Z with custom constructor
2372        // - X requires Z with custom constructor (more specific than X -> Y -> Z)
2373        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        // Same as `runtime_required_components_override_1` test but with different registration order
2389
2390        #[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        // - X requires Y with default constructor
2402        // - X requires Z with custom constructor (more specific than X -> Y -> Z)
2403        // - Y requires Z with custom constructor
2404        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        // `A` requires `B` directly.
2420        #[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        // `B` requires `C` with a runtime registration.
2433        // `A` should also require `C` because it requires `B`.
2434        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        // This should replace the require constructor in A since it is
2486        // shallower.
2487        world.register_required_components_with::<C, Counter>(|| Counter(1));
2488
2489        let id = world.spawn(A).id();
2490
2491        // The "shallower" of the two components is used.
2492        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        // The "shallower" of the two components is used.
2526        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        // Registering required components after the archetype has already been created should panic.
2540        // This may change in the future.
2541        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        // This should fail: Tried to register Y as a requirement for X, but the requirement already exists.
2560        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        // Test that inheritance depths are computed correctly for requirements.
2569        //
2570        // Requirements with `require` attribute:
2571        //
2572        // A -> B -> C
2573        //   0    1
2574        //
2575        // Runtime requirements:
2576        //
2577        // X -> A -> B -> C
2578        //   0    1    2
2579        //
2580        // X -> Y -> Z -> B -> C
2581        //   0    1    2    3
2582
2583        #[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        /// Returns the component IDs and inheritance depths of the required components
2626        /// in ascending order based on the component ID.
2627        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        // Check that the inheritance depths are correct for each component.
2638        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}