Thanks to visit codestin.com
Credit goes to docs.rs

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_cfg, rustdoc_internals))]
14#![expect(unsafe_code, reason = "Unsafe code is used to improve performance.")]
15#![doc(
16    html_logo_url = "https://bevy.org/assets/icon.png",
17    html_favicon_url = "https://bevy.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 intern;
43pub mod label;
44pub mod lifecycle;
45pub mod message;
46pub mod name;
47pub mod never;
48pub mod observer;
49pub mod query;
50#[cfg(feature = "bevy_reflect")]
51pub mod reflect;
52pub mod relationship;
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#[cfg(feature = "hotpatching")]
64use message::Message;
65
66/// The ECS prelude.
67///
68/// This includes the most common types in this crate, re-exported for your convenience.
69pub mod prelude {
70    #[doc(hidden)]
71    #[expect(
72        deprecated,
73        reason = "`Trigger` was deprecated in favor of `On`, and `OnX` lifecycle events were deprecated in favor of `X` events."
74    )]
75    pub use crate::{
76        bundle::Bundle,
77        change_detection::{DetectChanges, DetectChangesMut, Mut, Ref},
78        children,
79        component::Component,
80        entity::{ContainsEntity, Entity, EntityMapper},
81        error::{BevyError, Result},
82        event::{EntityEvent, Event, EventReader, EventWriter, Events},
83        hierarchy::{ChildOf, ChildSpawner, ChildSpawnerCommands, Children},
84        lifecycle::{
85            Add, Despawn, Insert, OnAdd, OnDespawn, OnInsert, OnRemove, OnReplace, Remove,
86            RemovedComponents, Replace,
87        },
88        message::{Message, MessageMutator, MessageReader, MessageWriter, Messages},
89        name::{Name, NameOrEntity},
90        observer::{Observer, On, Trigger},
91        query::{Added, Allow, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without},
92        related,
93        relationship::RelationshipTarget,
94        resource::Resource,
95        schedule::{
96            common_conditions::*, ApplyDeferred, IntoScheduleConfigs, IntoSystemSet, Schedule,
97            Schedules, SystemCondition, SystemSet,
98        },
99        spawn::{Spawn, SpawnIter, SpawnRelated, SpawnWith, WithOneRelated, WithRelated},
100        system::{
101            Command, Commands, Deferred, EntityCommand, EntityCommands, If, In, InMut, InRef,
102            IntoSystem, Local, NonSend, NonSendMut, ParamSet, Populated, Query, ReadOnlySystem,
103            Res, ResMut, Single, System, SystemIn, SystemInput, SystemParamBuilder,
104            SystemParamFunction,
105        },
106        world::{
107            EntityMut, EntityRef, EntityWorldMut, FilteredResources, FilteredResourcesMut,
108            FromWorld, World,
109        },
110    };
111
112    #[doc(hidden)]
113    #[cfg(feature = "std")]
114    pub use crate::system::ParallelCommands;
115
116    #[doc(hidden)]
117    #[cfg(feature = "bevy_reflect")]
118    pub use crate::reflect::{
119        AppTypeRegistry, ReflectComponent, ReflectFromWorld, ReflectResource,
120    };
121
122    #[doc(hidden)]
123    #[cfg(feature = "reflect_functions")]
124    pub use crate::reflect::AppFunctionRegistry;
125}
126
127/// Exports used by macros.
128///
129/// These are not meant to be used directly and are subject to breaking changes.
130#[doc(hidden)]
131pub mod __macro_exports {
132    // Cannot directly use `alloc::vec::Vec` in macros, as a crate may not have
133    // included `extern crate alloc;`. This re-export ensures we have access
134    // to `Vec` in `no_std` and `std` contexts.
135    pub use crate::query::DebugCheckedUnwrap;
136    pub use alloc::vec::Vec;
137}
138
139/// Event sent when a hotpatch happens.
140///
141/// Can be used for causing custom behavior on hot-patch.
142#[cfg(feature = "hotpatching")]
143#[derive(Message, Default)]
144pub struct HotPatched;
145
146/// Resource which "changes" when a hotpatch happens.
147///
148/// Exists solely for change-detection, which allows systems to
149/// know whether a hotpatch happened even if they only run irregularily and would
150/// miss the event.
151///
152/// Used by Executors and other places which run systems
153/// [`System::refresh_hotpatch`](crate::system::System::refresh_hotpatch) only when necessary.
154#[cfg(feature = "hotpatching")]
155#[derive(resource::Resource, Default)]
156pub struct HotPatchChanges;
157
158#[cfg(test)]
159mod tests {
160    use crate::{
161        bundle::Bundle,
162        change_detection::Ref,
163        component::Component,
164        entity::{Entity, EntityMapper},
165        entity_disabling::DefaultQueryFilters,
166        prelude::Or,
167        query::{Added, Changed, FilteredAccess, QueryFilter, With, Without},
168        resource::Resource,
169        world::{EntityMut, EntityRef, Mut, World},
170    };
171    use alloc::{string::String, sync::Arc, vec, vec::Vec};
172    use bevy_platform::collections::HashSet;
173    use bevy_tasks::{ComputeTaskPool, TaskPool};
174    use core::{
175        any::TypeId,
176        marker::PhantomData,
177        sync::atomic::{AtomicUsize, Ordering},
178    };
179    use std::sync::Mutex;
180
181    #[derive(Component, Resource, Debug, PartialEq, Eq, Hash, Clone, Copy)]
182    struct A(usize);
183    #[derive(Component, Debug, PartialEq, Eq, Hash, Clone, Copy)]
184    struct B(usize);
185    #[derive(Component, Debug, PartialEq, Eq, Clone, Copy)]
186    struct C;
187
188    #[derive(Default)]
189    struct NonSendA(PhantomData<*mut ()>);
190
191    #[derive(Component, Clone, Debug)]
192    struct DropCk(Arc<AtomicUsize>);
193    impl DropCk {
194        fn new_pair() -> (Self, Arc<AtomicUsize>) {
195            let atomic = Arc::new(AtomicUsize::new(0));
196            (DropCk(atomic.clone()), atomic)
197        }
198    }
199
200    impl Drop for DropCk {
201        fn drop(&mut self) {
202            self.0.as_ref().fetch_add(1, Ordering::Relaxed);
203        }
204    }
205
206    #[expect(
207        dead_code,
208        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."
209    )]
210    #[derive(Component, Clone, Debug)]
211    #[component(storage = "SparseSet")]
212    struct DropCkSparse(DropCk);
213
214    #[derive(Component, Copy, Clone, PartialEq, Eq, Debug)]
215    #[component(storage = "Table")]
216    struct TableStored(&'static str);
217    #[derive(Component, Copy, Clone, PartialEq, Eq, Hash, Debug)]
218    #[component(storage = "SparseSet")]
219    struct SparseStored(u32);
220
221    #[test]
222    fn random_access() {
223        let mut world = World::new();
224
225        let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
226        let f = world
227            .spawn((TableStored("def"), SparseStored(456), A(1)))
228            .id();
229        assert_eq!(world.get::<TableStored>(e).unwrap().0, "abc");
230        assert_eq!(world.get::<SparseStored>(e).unwrap().0, 123);
231        assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
232        assert_eq!(world.get::<SparseStored>(f).unwrap().0, 456);
233
234        // test archetype get_mut()
235        world.get_mut::<TableStored>(e).unwrap().0 = "xyz";
236        assert_eq!(world.get::<TableStored>(e).unwrap().0, "xyz");
237
238        // test sparse set get_mut()
239        world.get_mut::<SparseStored>(f).unwrap().0 = 42;
240        assert_eq!(world.get::<SparseStored>(f).unwrap().0, 42);
241    }
242
243    #[test]
244    fn bundle_derive() {
245        let mut world = World::new();
246
247        #[derive(Bundle, PartialEq, Debug)]
248        struct FooBundle {
249            x: TableStored,
250            y: SparseStored,
251        }
252        let mut ids = Vec::new();
253        <FooBundle as Bundle>::component_ids(&mut world.components_registrator(), &mut |id| {
254            ids.push(id);
255        });
256
257        assert_eq!(
258            ids,
259            &[
260                world.register_component::<TableStored>(),
261                world.register_component::<SparseStored>(),
262            ]
263        );
264
265        let e1 = world
266            .spawn(FooBundle {
267                x: TableStored("abc"),
268                y: SparseStored(123),
269            })
270            .id();
271        let e2 = world
272            .spawn((TableStored("def"), SparseStored(456), A(1)))
273            .id();
274        assert_eq!(world.get::<TableStored>(e1).unwrap().0, "abc");
275        assert_eq!(world.get::<SparseStored>(e1).unwrap().0, 123);
276        assert_eq!(world.get::<TableStored>(e2).unwrap().0, "def");
277        assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 456);
278
279        // test archetype get_mut()
280        world.get_mut::<TableStored>(e1).unwrap().0 = "xyz";
281        assert_eq!(world.get::<TableStored>(e1).unwrap().0, "xyz");
282
283        // test sparse set get_mut()
284        world.get_mut::<SparseStored>(e2).unwrap().0 = 42;
285        assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 42);
286
287        assert_eq!(
288            world.entity_mut(e1).take::<FooBundle>().unwrap(),
289            FooBundle {
290                x: TableStored("xyz"),
291                y: SparseStored(123),
292            }
293        );
294
295        #[derive(Bundle, PartialEq, Debug)]
296        struct NestedBundle {
297            a: A,
298            foo: FooBundle,
299            b: B,
300        }
301
302        let mut ids = Vec::new();
303        <NestedBundle as Bundle>::component_ids(&mut world.components_registrator(), &mut |id| {
304            ids.push(id);
305        });
306
307        assert_eq!(
308            ids,
309            &[
310                world.register_component::<A>(),
311                world.register_component::<TableStored>(),
312                world.register_component::<SparseStored>(),
313                world.register_component::<B>(),
314            ]
315        );
316
317        let e3 = world
318            .spawn(NestedBundle {
319                a: A(1),
320                foo: FooBundle {
321                    x: TableStored("ghi"),
322                    y: SparseStored(789),
323                },
324                b: B(2),
325            })
326            .id();
327
328        assert_eq!(world.get::<TableStored>(e3).unwrap().0, "ghi");
329        assert_eq!(world.get::<SparseStored>(e3).unwrap().0, 789);
330        assert_eq!(world.get::<A>(e3).unwrap().0, 1);
331        assert_eq!(world.get::<B>(e3).unwrap().0, 2);
332        assert_eq!(
333            world.entity_mut(e3).take::<NestedBundle>().unwrap(),
334            NestedBundle {
335                a: A(1),
336                foo: FooBundle {
337                    x: TableStored("ghi"),
338                    y: SparseStored(789),
339                },
340                b: B(2),
341            }
342        );
343
344        #[derive(Default, Component, PartialEq, Debug)]
345        struct Ignored;
346
347        #[derive(Bundle, PartialEq, Debug)]
348        struct BundleWithIgnored {
349            c: C,
350            #[bundle(ignore)]
351            ignored: Ignored,
352        }
353
354        let mut ids = Vec::new();
355        <BundleWithIgnored as Bundle>::component_ids(
356            &mut world.components_registrator(),
357            &mut |id| {
358                ids.push(id);
359            },
360        );
361
362        assert_eq!(ids, &[world.register_component::<C>(),]);
363
364        let e4 = world
365            .spawn(BundleWithIgnored {
366                c: C,
367                ignored: Ignored,
368            })
369            .id();
370
371        assert_eq!(world.get::<C>(e4).unwrap(), &C);
372        assert_eq!(world.get::<Ignored>(e4), None);
373
374        assert_eq!(
375            world.entity_mut(e4).take::<BundleWithIgnored>().unwrap(),
376            BundleWithIgnored {
377                c: C,
378                ignored: Ignored,
379            }
380        );
381    }
382
383    #[test]
384    fn despawn_table_storage() {
385        let mut world = World::new();
386        let e = world.spawn((TableStored("abc"), A(123))).id();
387        let f = world.spawn((TableStored("def"), A(456))).id();
388        assert_eq!(world.query::<&TableStored>().query(&world).count(), 2);
389        assert!(world.despawn(e));
390        assert_eq!(world.query::<&TableStored>().query(&world).count(), 1);
391        assert!(world.get::<TableStored>(e).is_none());
392        assert!(world.get::<A>(e).is_none());
393        assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
394        assert_eq!(world.get::<A>(f).unwrap().0, 456);
395    }
396
397    #[test]
398    fn despawn_mixed_storage() {
399        let mut world = World::new();
400
401        let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
402        let f = world.spawn((TableStored("def"), SparseStored(456))).id();
403        assert_eq!(world.query::<&TableStored>().query(&world).count(), 2);
404        assert!(world.despawn(e));
405        assert_eq!(world.query::<&TableStored>().query(&world).count(), 1);
406        assert!(world.get::<TableStored>(e).is_none());
407        assert!(world.get::<SparseStored>(e).is_none());
408        assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
409        assert_eq!(world.get::<SparseStored>(f).unwrap().0, 456);
410    }
411
412    #[test]
413    fn query_all() {
414        let mut world = World::new();
415        let e = world.spawn((TableStored("abc"), A(123))).id();
416        let f = world.spawn((TableStored("def"), A(456))).id();
417
418        let ents = world
419            .query::<(Entity, &A, &TableStored)>()
420            .iter(&world)
421            .map(|(e, &i, &s)| (e, i, s))
422            .collect::<Vec<_>>();
423        assert_eq!(
424            ents,
425            &[
426                (e, A(123), TableStored("abc")),
427                (f, A(456), TableStored("def"))
428            ]
429        );
430    }
431
432    #[test]
433    fn query_all_for_each() {
434        let mut world = World::new();
435        let e = world.spawn((TableStored("abc"), A(123))).id();
436        let f = world.spawn((TableStored("def"), A(456))).id();
437
438        let mut results = Vec::new();
439        world
440            .query::<(Entity, &A, &TableStored)>()
441            .iter(&world)
442            .for_each(|(e, &i, &s)| results.push((e, i, s)));
443        assert_eq!(
444            results,
445            &[
446                (e, A(123), TableStored("abc")),
447                (f, A(456), TableStored("def"))
448            ]
449        );
450    }
451
452    #[test]
453    fn query_single_component() {
454        let mut world = World::new();
455        let e = world.spawn((TableStored("abc"), A(123))).id();
456        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
457        let ents = world
458            .query::<(Entity, &A)>()
459            .iter(&world)
460            .map(|(e, &i)| (e, i))
461            .collect::<HashSet<_>>();
462        assert!(ents.contains(&(e, A(123))));
463        assert!(ents.contains(&(f, A(456))));
464    }
465
466    #[test]
467    fn stateful_query_handles_new_archetype() {
468        let mut world = World::new();
469        let e = world.spawn((TableStored("abc"), A(123))).id();
470        let mut query = world.query::<(Entity, &A)>();
471
472        let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
473        assert_eq!(ents, &[(e, A(123))]);
474
475        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
476        let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
477        assert_eq!(ents, &[(e, A(123)), (f, A(456))]);
478    }
479
480    #[test]
481    fn query_single_component_for_each() {
482        let mut world = World::new();
483        let e = world.spawn((TableStored("abc"), A(123))).id();
484        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
485        let mut results = <HashSet<_>>::default();
486        world
487            .query::<(Entity, &A)>()
488            .iter(&world)
489            .for_each(|(e, &i)| {
490                results.insert((e, i));
491            });
492        assert!(results.contains(&(e, A(123))));
493        assert!(results.contains(&(f, A(456))));
494    }
495
496    #[test]
497    fn par_for_each_dense() {
498        ComputeTaskPool::get_or_init(TaskPool::default);
499        let mut world = World::new();
500        let e1 = world.spawn(A(1)).id();
501        let e2 = world.spawn(A(2)).id();
502        let e3 = world.spawn(A(3)).id();
503        let e4 = world.spawn((A(4), B(1))).id();
504        let e5 = world.spawn((A(5), B(1))).id();
505        let results = Arc::new(Mutex::new(Vec::new()));
506        world
507            .query::<(Entity, &A)>()
508            .par_iter(&world)
509            .for_each(|(e, &A(i))| {
510                results.lock().unwrap().push((e, i));
511            });
512        results.lock().unwrap().sort();
513        let mut expected = [(e1, 1), (e2, 2), (e3, 3), (e4, 4), (e5, 5)];
514        expected.sort();
515        assert_eq!(&*results.lock().unwrap(), &expected);
516    }
517
518    #[test]
519    fn par_for_each_sparse() {
520        ComputeTaskPool::get_or_init(TaskPool::default);
521        let mut world = World::new();
522        let e1 = world.spawn(SparseStored(1)).id();
523        let e2 = world.spawn(SparseStored(2)).id();
524        let e3 = world.spawn(SparseStored(3)).id();
525        let e4 = world.spawn((SparseStored(4), A(1))).id();
526        let e5 = world.spawn((SparseStored(5), A(1))).id();
527        let results = Arc::new(Mutex::new(Vec::new()));
528        world
529            .query::<(Entity, &SparseStored)>()
530            .par_iter(&world)
531            .for_each(|(e, &SparseStored(i))| results.lock().unwrap().push((e, i)));
532        results.lock().unwrap().sort();
533        let mut expected = [(e1, 1), (e2, 2), (e3, 3), (e4, 4), (e5, 5)];
534        expected.sort();
535        assert_eq!(&*results.lock().unwrap(), &expected);
536    }
537
538    #[test]
539    fn query_missing_component() {
540        let mut world = World::new();
541        world.spawn((TableStored("abc"), A(123)));
542        world.spawn((TableStored("def"), A(456)));
543        assert!(world.query::<(&B, &A)>().iter(&world).next().is_none());
544    }
545
546    #[test]
547    fn query_sparse_component() {
548        let mut world = World::new();
549        world.spawn((TableStored("abc"), A(123)));
550        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
551        let ents = world
552            .query::<(Entity, &B)>()
553            .iter(&world)
554            .map(|(e, &b)| (e, b))
555            .collect::<Vec<_>>();
556        assert_eq!(ents, &[(f, B(1))]);
557    }
558
559    #[test]
560    fn query_filter_with() {
561        let mut world = World::new();
562        world.spawn((A(123), B(1)));
563        world.spawn(A(456));
564        let result = world
565            .query_filtered::<&A, With<B>>()
566            .iter(&world)
567            .cloned()
568            .collect::<Vec<_>>();
569        assert_eq!(result, vec![A(123)]);
570    }
571
572    #[test]
573    fn query_filter_with_for_each() {
574        let mut world = World::new();
575        world.spawn((A(123), B(1)));
576        world.spawn(A(456));
577
578        let mut results = Vec::new();
579        world
580            .query_filtered::<&A, With<B>>()
581            .iter(&world)
582            .for_each(|i| results.push(*i));
583        assert_eq!(results, vec![A(123)]);
584    }
585
586    #[test]
587    fn query_filter_with_sparse() {
588        let mut world = World::new();
589
590        world.spawn((A(123), SparseStored(321)));
591        world.spawn(A(456));
592        let result = world
593            .query_filtered::<&A, With<SparseStored>>()
594            .iter(&world)
595            .cloned()
596            .collect::<Vec<_>>();
597        assert_eq!(result, vec![A(123)]);
598    }
599
600    #[test]
601    fn query_filter_with_sparse_for_each() {
602        let mut world = World::new();
603
604        world.spawn((A(123), SparseStored(321)));
605        world.spawn(A(456));
606        let mut results = Vec::new();
607        world
608            .query_filtered::<&A, With<SparseStored>>()
609            .iter(&world)
610            .for_each(|i| results.push(*i));
611        assert_eq!(results, vec![A(123)]);
612    }
613
614    #[test]
615    fn query_filter_without() {
616        let mut world = World::new();
617        world.spawn((A(123), B(321)));
618        world.spawn(A(456));
619        let result = world
620            .query_filtered::<&A, Without<B>>()
621            .iter(&world)
622            .cloned()
623            .collect::<Vec<_>>();
624        assert_eq!(result, vec![A(456)]);
625    }
626
627    #[test]
628    fn query_optional_component_table() {
629        let mut world = World::new();
630        let e = world.spawn((TableStored("abc"), A(123))).id();
631        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
632        // this should be skipped
633        world.spawn(TableStored("abc"));
634        let ents = world
635            .query::<(Entity, Option<&B>, &A)>()
636            .iter(&world)
637            .map(|(e, b, &i)| (e, b.copied(), i))
638            .collect::<HashSet<_>>();
639        assert!(ents.contains(&(e, None, A(123))));
640        assert!(ents.contains(&(f, Some(B(1)), A(456))));
641    }
642
643    #[test]
644    fn query_optional_component_sparse() {
645        let mut world = World::new();
646
647        let e = world.spawn((TableStored("abc"), A(123))).id();
648        let f = world
649            .spawn((TableStored("def"), A(456), SparseStored(1)))
650            .id();
651        // this should be skipped
652        // world.spawn(SparseStored(1));
653        let ents = world
654            .query::<(Entity, Option<&SparseStored>, &A)>()
655            .iter(&world)
656            .map(|(e, b, &i)| (e, b.copied(), i))
657            .collect::<HashSet<_>>();
658        assert_eq!(
659            ents,
660            [(e, None, A(123)), (f, Some(SparseStored(1)), A(456))]
661                .into_iter()
662                .collect::<HashSet<_>>()
663        );
664    }
665
666    #[test]
667    fn query_optional_component_sparse_no_match() {
668        let mut world = World::new();
669
670        let e = world.spawn((TableStored("abc"), A(123))).id();
671        let f = world.spawn((TableStored("def"), A(456))).id();
672        // // this should be skipped
673        world.spawn(TableStored("abc"));
674        let ents = world
675            .query::<(Entity, Option<&SparseStored>, &A)>()
676            .iter(&world)
677            .map(|(e, b, &i)| (e, b.copied(), i))
678            .collect::<Vec<_>>();
679        assert_eq!(ents, &[(e, None, A(123)), (f, None, A(456))]);
680    }
681
682    #[test]
683    fn add_remove_components() {
684        let mut world = World::new();
685        let e1 = world.spawn((A(1), B(3), TableStored("abc"))).id();
686        let e2 = world.spawn((A(2), B(4), TableStored("xyz"))).id();
687
688        assert_eq!(
689            world
690                .query::<(Entity, &A, &B)>()
691                .iter(&world)
692                .map(|(e, &i, &b)| (e, i, b))
693                .collect::<HashSet<_>>(),
694            [(e1, A(1), B(3)), (e2, A(2), B(4))]
695                .into_iter()
696                .collect::<HashSet<_>>()
697        );
698        assert_eq!(world.entity_mut(e1).take::<A>(), Some(A(1)));
699        assert_eq!(
700            world
701                .query::<(Entity, &A, &B)>()
702                .iter(&world)
703                .map(|(e, &i, &b)| (e, i, b))
704                .collect::<Vec<_>>(),
705            &[(e2, A(2), B(4))]
706        );
707        assert_eq!(
708            world
709                .query::<(Entity, &B, &TableStored)>()
710                .iter(&world)
711                .map(|(e, &B(b), &TableStored(s))| (e, b, s))
712                .collect::<HashSet<_>>(),
713            [(e2, 4, "xyz"), (e1, 3, "abc")]
714                .into_iter()
715                .collect::<HashSet<_>>()
716        );
717        world.entity_mut(e1).insert(A(43));
718        assert_eq!(
719            world
720                .query::<(Entity, &A, &B)>()
721                .iter(&world)
722                .map(|(e, &i, &b)| (e, i, b))
723                .collect::<HashSet<_>>(),
724            [(e2, A(2), B(4)), (e1, A(43), B(3))]
725                .into_iter()
726                .collect::<HashSet<_>>()
727        );
728        world.entity_mut(e1).insert(C);
729        assert_eq!(
730            world
731                .query::<(Entity, &C)>()
732                .iter(&world)
733                .map(|(e, &f)| (e, f))
734                .collect::<Vec<_>>(),
735            &[(e1, C)]
736        );
737    }
738
739    #[test]
740    fn table_add_remove_many() {
741        let mut world = World::default();
742        #[cfg(miri)]
743        let (mut entities, to) = {
744            let to = 10;
745            (Vec::with_capacity(to), to)
746        };
747        #[cfg(not(miri))]
748        let (mut entities, to) = {
749            let to = 10_000;
750            (Vec::with_capacity(to), to)
751        };
752
753        for _ in 0..to {
754            entities.push(world.spawn(B(0)).id());
755        }
756
757        for (i, entity) in entities.iter().cloned().enumerate() {
758            world.entity_mut(entity).insert(A(i));
759        }
760
761        for (i, entity) in entities.iter().cloned().enumerate() {
762            assert_eq!(world.entity_mut(entity).take::<A>(), Some(A(i)));
763        }
764    }
765
766    #[test]
767    fn sparse_set_add_remove_many() {
768        let mut world = World::default();
769
770        let mut entities = Vec::with_capacity(1000);
771        for _ in 0..4 {
772            entities.push(world.spawn(A(2)).id());
773        }
774
775        for (i, entity) in entities.iter().cloned().enumerate() {
776            world.entity_mut(entity).insert(SparseStored(i as u32));
777        }
778
779        for (i, entity) in entities.iter().cloned().enumerate() {
780            assert_eq!(
781                world.entity_mut(entity).take::<SparseStored>(),
782                Some(SparseStored(i as u32))
783            );
784        }
785    }
786
787    #[test]
788    fn remove_missing() {
789        let mut world = World::new();
790        let e = world.spawn((TableStored("abc"), A(123))).id();
791        assert!(world.entity_mut(e).take::<B>().is_none());
792    }
793
794    #[test]
795    fn spawn_batch() {
796        let mut world = World::new();
797        world.spawn_batch((0..100).map(|x| (A(x), TableStored("abc"))));
798        let values = world
799            .query::<&A>()
800            .iter(&world)
801            .map(|v| v.0)
802            .collect::<Vec<_>>();
803        let expected = (0..100).collect::<Vec<_>>();
804        assert_eq!(values, expected);
805    }
806
807    #[test]
808    fn query_get() {
809        let mut world = World::new();
810        let a = world.spawn((TableStored("abc"), A(123))).id();
811        let b = world.spawn((TableStored("def"), A(456))).id();
812        let c = world.spawn((TableStored("ghi"), A(789), B(1))).id();
813
814        let mut i32_query = world.query::<&A>();
815        assert_eq!(i32_query.get(&world, a).unwrap().0, 123);
816        assert_eq!(i32_query.get(&world, b).unwrap().0, 456);
817
818        let mut i32_bool_query = world.query::<(&A, &B)>();
819        assert!(i32_bool_query.get(&world, a).is_err());
820        assert_eq!(i32_bool_query.get(&world, c).unwrap(), (&A(789), &B(1)));
821        assert!(world.despawn(a));
822        assert!(i32_query.get(&world, a).is_err());
823    }
824
825    #[test]
826    fn query_get_works_across_sparse_removal() {
827        // Regression test for: https://github.com/bevyengine/bevy/issues/6623
828        let mut world = World::new();
829        let a = world.spawn((TableStored("abc"), SparseStored(123))).id();
830        let b = world.spawn((TableStored("def"), SparseStored(456))).id();
831        let c = world
832            .spawn((TableStored("ghi"), SparseStored(789), B(1)))
833            .id();
834
835        let mut query = world.query::<&TableStored>();
836        assert_eq!(query.get(&world, a).unwrap(), &TableStored("abc"));
837        assert_eq!(query.get(&world, b).unwrap(), &TableStored("def"));
838        assert_eq!(query.get(&world, c).unwrap(), &TableStored("ghi"));
839
840        world.entity_mut(b).remove::<SparseStored>();
841        world.entity_mut(c).remove::<SparseStored>();
842
843        assert_eq!(query.get(&world, a).unwrap(), &TableStored("abc"));
844        assert_eq!(query.get(&world, b).unwrap(), &TableStored("def"));
845        assert_eq!(query.get(&world, c).unwrap(), &TableStored("ghi"));
846    }
847
848    #[test]
849    fn remove_tracking() {
850        let mut world = World::new();
851
852        let a = world.spawn((SparseStored(0), A(123))).id();
853        let b = world.spawn((SparseStored(1), A(123))).id();
854
855        world.entity_mut(a).despawn();
856        assert_eq!(
857            world.removed::<A>().collect::<Vec<_>>(),
858            &[a],
859            "despawning results in 'removed component' state for table components"
860        );
861        assert_eq!(
862            world.removed::<SparseStored>().collect::<Vec<_>>(),
863            &[a],
864            "despawning results in 'removed component' state for sparse set components"
865        );
866
867        world.entity_mut(b).insert(B(1));
868        assert_eq!(
869            world.removed::<A>().collect::<Vec<_>>(),
870            &[a],
871            "archetype moves does not result in 'removed component' state"
872        );
873
874        world.entity_mut(b).remove::<A>();
875        assert_eq!(
876            world.removed::<A>().collect::<Vec<_>>(),
877            &[a, b],
878            "removing a component results in a 'removed component' state"
879        );
880
881        world.clear_trackers();
882        assert_eq!(
883            world.removed::<A>().collect::<Vec<_>>(),
884            &[],
885            "clearing trackers clears removals"
886        );
887        assert_eq!(
888            world.removed::<SparseStored>().collect::<Vec<_>>(),
889            &[],
890            "clearing trackers clears removals"
891        );
892        assert_eq!(
893            world.removed::<B>().collect::<Vec<_>>(),
894            &[],
895            "clearing trackers clears removals"
896        );
897
898        // TODO: uncomment when world.clear() is implemented
899        // let c = world.spawn(("abc", 123)).id();
900        // let d = world.spawn(("abc", 123)).id();
901        // world.clear();
902        // assert_eq!(
903        //     world.removed::<i32>(),
904        //     &[c, d],
905        //     "world clears result in 'removed component' states"
906        // );
907        // assert_eq!(
908        //     world.removed::<&'static str>(),
909        //     &[c, d, b],
910        //     "world clears result in 'removed component' states"
911        // );
912        // assert_eq!(
913        //     world.removed::<f64>(),
914        //     &[b],
915        //     "world clears result in 'removed component' states"
916        // );
917    }
918
919    #[test]
920    fn added_tracking() {
921        let mut world = World::new();
922        let a = world.spawn(A(123)).id();
923
924        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
925        assert_eq!(
926            world.query_filtered::<(), Added<A>>().iter(&world).count(),
927            1
928        );
929        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
930        assert_eq!(
931            world.query_filtered::<(), Added<A>>().iter(&world).count(),
932            1
933        );
934        assert!(world.query::<&A>().get(&world, a).is_ok());
935        assert!(world
936            .query_filtered::<(), Added<A>>()
937            .get(&world, a)
938            .is_ok());
939        assert!(world.query::<&A>().get(&world, a).is_ok());
940        assert!(world
941            .query_filtered::<(), Added<A>>()
942            .get(&world, a)
943            .is_ok());
944
945        world.clear_trackers();
946
947        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
948        assert_eq!(
949            world.query_filtered::<(), Added<A>>().iter(&world).count(),
950            0
951        );
952        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
953        assert_eq!(
954            world.query_filtered::<(), Added<A>>().iter(&world).count(),
955            0
956        );
957        assert!(world.query::<&A>().get(&world, a).is_ok());
958        assert!(world
959            .query_filtered::<(), Added<A>>()
960            .get(&world, a)
961            .is_err());
962        assert!(world.query::<&A>().get(&world, a).is_ok());
963        assert!(world
964            .query_filtered::<(), Added<A>>()
965            .get(&world, a)
966            .is_err());
967    }
968
969    #[test]
970    fn added_queries() {
971        let mut world = World::default();
972        let e1 = world.spawn(A(0)).id();
973
974        fn get_added<Com: Component>(world: &mut World) -> Vec<Entity> {
975            world
976                .query_filtered::<Entity, Added<Com>>()
977                .iter(world)
978                .collect::<Vec<Entity>>()
979        }
980
981        assert_eq!(get_added::<A>(&mut world), vec![e1]);
982        world.entity_mut(e1).insert(B(0));
983        assert_eq!(get_added::<A>(&mut world), vec![e1]);
984        assert_eq!(get_added::<B>(&mut world), vec![e1]);
985
986        world.clear_trackers();
987        assert!(get_added::<A>(&mut world).is_empty());
988        let e2 = world.spawn((A(1), B(1))).id();
989        assert_eq!(get_added::<A>(&mut world), vec![e2]);
990        assert_eq!(get_added::<B>(&mut world), vec![e2]);
991
992        let added = world
993            .query_filtered::<Entity, (Added<A>, Added<B>)>()
994            .iter(&world)
995            .collect::<Vec<Entity>>();
996        assert_eq!(added, vec![e2]);
997    }
998
999    #[test]
1000    fn changed_trackers() {
1001        let mut world = World::default();
1002        let e1 = world.spawn((A(0), B(0))).id();
1003        let e2 = world.spawn((A(0), B(0))).id();
1004        let e3 = world.spawn((A(0), B(0))).id();
1005        world.spawn((A(0), B(0)));
1006
1007        world.clear_trackers();
1008
1009        for (i, mut a) in world.query::<&mut A>().iter_mut(&mut world).enumerate() {
1010            if i % 2 == 0 {
1011                a.0 += 1;
1012            }
1013        }
1014
1015        fn get_filtered<F: QueryFilter>(world: &mut World) -> HashSet<Entity> {
1016            world
1017                .query_filtered::<Entity, F>()
1018                .iter(world)
1019                .collect::<HashSet<Entity>>()
1020        }
1021
1022        assert_eq!(
1023            get_filtered::<Changed<A>>(&mut world),
1024            [e1, e3].into_iter().collect::<HashSet<_>>()
1025        );
1026
1027        // ensure changing an entity's archetypes also moves its changed state
1028        world.entity_mut(e1).insert(C);
1029
1030        assert_eq!(
1031            get_filtered::<Changed<A>>(&mut world),
1032            [e3, e1].into_iter().collect::<HashSet<_>>(),
1033            "changed entities list should not change"
1034        );
1035
1036        // spawning a new A entity should not change existing changed state
1037        world.entity_mut(e1).insert((A(0), B(0)));
1038
1039        assert_eq!(
1040            get_filtered::<Changed<A>>(&mut world),
1041            [e3, e1].into_iter().collect::<HashSet<_>>(),
1042            "changed entities list should not change"
1043        );
1044
1045        // removing an unchanged entity should not change changed state
1046        assert!(world.despawn(e2));
1047        assert_eq!(
1048            get_filtered::<Changed<A>>(&mut world),
1049            [e3, e1].into_iter().collect::<HashSet<_>>(),
1050            "changed entities list should not change"
1051        );
1052
1053        // removing a changed entity should remove it from enumeration
1054        assert!(world.despawn(e1));
1055        assert_eq!(
1056            get_filtered::<Changed<A>>(&mut world),
1057            [e3].into_iter().collect::<HashSet<_>>(),
1058            "e1 should no longer be returned"
1059        );
1060
1061        world.clear_trackers();
1062
1063        assert!(get_filtered::<Changed<A>>(&mut world).is_empty());
1064
1065        let e4 = world.spawn_empty().id();
1066
1067        world.entity_mut(e4).insert(A(0));
1068        assert_eq!(
1069            get_filtered::<Changed<A>>(&mut world),
1070            [e4].into_iter().collect::<HashSet<_>>()
1071        );
1072        assert_eq!(
1073            get_filtered::<Added<A>>(&mut world),
1074            [e4].into_iter().collect::<HashSet<_>>()
1075        );
1076
1077        world.entity_mut(e4).insert(A(1));
1078        assert_eq!(
1079            get_filtered::<Changed<A>>(&mut world),
1080            [e4].into_iter().collect::<HashSet<_>>()
1081        );
1082
1083        world.clear_trackers();
1084
1085        // ensure inserting multiple components set changed state for all components and set added
1086        // state for non existing components even when changing archetype.
1087        world.entity_mut(e4).insert((A(0), B(0)));
1088
1089        assert!(get_filtered::<Added<A>>(&mut world).is_empty());
1090        assert_eq!(
1091            get_filtered::<Changed<A>>(&mut world),
1092            [e4].into_iter().collect::<HashSet<_>>()
1093        );
1094        assert_eq!(
1095            get_filtered::<Added<B>>(&mut world),
1096            [e4].into_iter().collect::<HashSet<_>>()
1097        );
1098        assert_eq!(
1099            get_filtered::<Changed<B>>(&mut world),
1100            [e4].into_iter().collect::<HashSet<_>>()
1101        );
1102    }
1103
1104    #[test]
1105    fn changed_trackers_sparse() {
1106        let mut world = World::default();
1107        let e1 = world.spawn(SparseStored(0)).id();
1108        let e2 = world.spawn(SparseStored(0)).id();
1109        let e3 = world.spawn(SparseStored(0)).id();
1110        world.spawn(SparseStored(0));
1111
1112        world.clear_trackers();
1113
1114        for (i, mut a) in world
1115            .query::<&mut SparseStored>()
1116            .iter_mut(&mut world)
1117            .enumerate()
1118        {
1119            if i % 2 == 0 {
1120                a.0 += 1;
1121            }
1122        }
1123
1124        fn get_filtered<F: QueryFilter>(world: &mut World) -> HashSet<Entity> {
1125            world
1126                .query_filtered::<Entity, F>()
1127                .iter(world)
1128                .collect::<HashSet<Entity>>()
1129        }
1130
1131        assert_eq!(
1132            get_filtered::<Changed<SparseStored>>(&mut world),
1133            [e1, e3].into_iter().collect::<HashSet<_>>()
1134        );
1135
1136        // ensure changing an entity's archetypes also moves its changed state
1137        world.entity_mut(e1).insert(C);
1138
1139        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)");
1140
1141        // spawning a new SparseStored entity should not change existing changed state
1142        world.entity_mut(e1).insert(SparseStored(0));
1143        assert_eq!(
1144            get_filtered::<Changed<SparseStored>>(&mut world),
1145            [e3, e1].into_iter().collect::<HashSet<_>>(),
1146            "changed entities list should not change"
1147        );
1148
1149        // removing an unchanged entity should not change changed state
1150        assert!(world.despawn(e2));
1151        assert_eq!(
1152            get_filtered::<Changed<SparseStored>>(&mut world),
1153            [e3, e1].into_iter().collect::<HashSet<_>>(),
1154            "changed entities list should not change"
1155        );
1156
1157        // removing a changed entity should remove it from enumeration
1158        assert!(world.despawn(e1));
1159        assert_eq!(
1160            get_filtered::<Changed<SparseStored>>(&mut world),
1161            [e3].into_iter().collect::<HashSet<_>>(),
1162            "e1 should no longer be returned"
1163        );
1164
1165        world.clear_trackers();
1166
1167        assert!(get_filtered::<Changed<SparseStored>>(&mut world).is_empty());
1168
1169        let e4 = world.spawn_empty().id();
1170
1171        world.entity_mut(e4).insert(SparseStored(0));
1172        assert_eq!(
1173            get_filtered::<Changed<SparseStored>>(&mut world),
1174            [e4].into_iter().collect::<HashSet<_>>()
1175        );
1176        assert_eq!(
1177            get_filtered::<Added<SparseStored>>(&mut world),
1178            [e4].into_iter().collect::<HashSet<_>>()
1179        );
1180
1181        world.entity_mut(e4).insert(A(1));
1182        assert_eq!(
1183            get_filtered::<Changed<SparseStored>>(&mut world),
1184            [e4].into_iter().collect::<HashSet<_>>()
1185        );
1186
1187        world.clear_trackers();
1188
1189        // ensure inserting multiple components set changed state for all components and set added
1190        // state for non existing components even when changing archetype.
1191        world.entity_mut(e4).insert(SparseStored(0));
1192
1193        assert!(get_filtered::<Added<SparseStored>>(&mut world).is_empty());
1194        assert_eq!(
1195            get_filtered::<Changed<SparseStored>>(&mut world),
1196            [e4].into_iter().collect::<HashSet<_>>()
1197        );
1198    }
1199
1200    #[test]
1201    fn empty_spawn() {
1202        let mut world = World::default();
1203        let e = world.spawn_empty().id();
1204        let mut e_mut = world.entity_mut(e);
1205        e_mut.insert(A(0));
1206        assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
1207    }
1208
1209    #[test]
1210    fn reserve_and_spawn() {
1211        let mut world = World::default();
1212        let e = world.entities().reserve_entity();
1213        world.flush_entities();
1214        let mut e_mut = world.entity_mut(e);
1215        e_mut.insert(A(0));
1216        assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
1217    }
1218
1219    #[test]
1220    fn changed_query() {
1221        let mut world = World::default();
1222        let e1 = world.spawn((A(0), B(0))).id();
1223
1224        fn get_changed(world: &mut World) -> Vec<Entity> {
1225            world
1226                .query_filtered::<Entity, Changed<A>>()
1227                .iter(world)
1228                .collect::<Vec<Entity>>()
1229        }
1230        assert_eq!(get_changed(&mut world), vec![e1]);
1231        world.clear_trackers();
1232        assert_eq!(get_changed(&mut world), vec![]);
1233        *world.get_mut(e1).unwrap() = A(1);
1234        assert_eq!(get_changed(&mut world), vec![e1]);
1235    }
1236
1237    #[test]
1238    fn resource() {
1239        use crate::resource::Resource;
1240
1241        #[derive(Resource, PartialEq, Debug)]
1242        struct Num(i32);
1243
1244        #[derive(Resource, PartialEq, Debug)]
1245        struct BigNum(u64);
1246
1247        let mut world = World::default();
1248        assert!(world.get_resource::<Num>().is_none());
1249        assert!(!world.contains_resource::<Num>());
1250        assert!(!world.is_resource_added::<Num>());
1251        assert!(!world.is_resource_changed::<Num>());
1252
1253        world.insert_resource(Num(123));
1254        let resource_id = world
1255            .components()
1256            .get_resource_id(TypeId::of::<Num>())
1257            .unwrap();
1258
1259        assert_eq!(world.resource::<Num>().0, 123);
1260        assert!(world.contains_resource::<Num>());
1261        assert!(world.is_resource_added::<Num>());
1262        assert!(world.is_resource_changed::<Num>());
1263
1264        world.insert_resource(BigNum(456));
1265        assert_eq!(world.resource::<BigNum>().0, 456u64);
1266
1267        world.insert_resource(BigNum(789));
1268        assert_eq!(world.resource::<BigNum>().0, 789);
1269
1270        {
1271            let mut value = world.resource_mut::<BigNum>();
1272            assert_eq!(value.0, 789);
1273            value.0 = 10;
1274        }
1275
1276        assert_eq!(
1277            world.resource::<BigNum>().0,
1278            10,
1279            "resource changes are preserved"
1280        );
1281
1282        assert_eq!(
1283            world.remove_resource::<BigNum>(),
1284            Some(BigNum(10)),
1285            "removed resource has the correct value"
1286        );
1287        assert_eq!(
1288            world.get_resource::<BigNum>(),
1289            None,
1290            "removed resource no longer exists"
1291        );
1292        assert_eq!(
1293            world.remove_resource::<BigNum>(),
1294            None,
1295            "double remove returns nothing"
1296        );
1297
1298        world.insert_resource(BigNum(1));
1299        assert_eq!(
1300            world.get_resource::<BigNum>(),
1301            Some(&BigNum(1)),
1302            "re-inserting resources works"
1303        );
1304
1305        assert_eq!(
1306            world.get_resource::<Num>(),
1307            Some(&Num(123)),
1308            "other resources are unaffected"
1309        );
1310
1311        let current_resource_id = world
1312            .components()
1313            .get_resource_id(TypeId::of::<Num>())
1314            .unwrap();
1315        assert_eq!(
1316            resource_id, current_resource_id,
1317            "resource id does not change after removing / re-adding"
1318        );
1319    }
1320
1321    #[test]
1322    fn remove() {
1323        let mut world = World::default();
1324        let e1 = world.spawn((A(1), B(1), TableStored("a"))).id();
1325
1326        let mut e = world.entity_mut(e1);
1327        assert_eq!(e.get::<TableStored>(), Some(&TableStored("a")));
1328        assert_eq!(e.get::<A>(), Some(&A(1)));
1329        assert_eq!(e.get::<B>(), Some(&B(1)));
1330        assert_eq!(
1331            e.get::<C>(),
1332            None,
1333            "C is not in the entity, so it should not exist"
1334        );
1335
1336        e.remove::<(A, B, C)>();
1337        assert_eq!(
1338            e.get::<TableStored>(),
1339            Some(&TableStored("a")),
1340            "TableStored is not in the removed bundle, so it should exist"
1341        );
1342        assert_eq!(
1343            e.get::<A>(),
1344            None,
1345            "Num is in the removed bundle, so it should not exist"
1346        );
1347        assert_eq!(
1348            e.get::<B>(),
1349            None,
1350            "f64 is in the removed bundle, so it should not exist"
1351        );
1352        assert_eq!(
1353            e.get::<C>(),
1354            None,
1355            "usize is in the removed bundle, so it should not exist"
1356        );
1357    }
1358
1359    #[test]
1360    fn take() {
1361        let mut world = World::default();
1362        world.spawn((A(1), B(1), TableStored("1")));
1363        let e2 = world.spawn((A(2), B(2), TableStored("2"))).id();
1364        world.spawn((A(3), B(3), TableStored("3")));
1365
1366        let mut query = world.query::<(&B, &TableStored)>();
1367        let results = query
1368            .iter(&world)
1369            .map(|(a, b)| (a.0, b.0))
1370            .collect::<HashSet<_>>();
1371        assert_eq!(
1372            results,
1373            [(1, "1"), (2, "2"), (3, "3"),]
1374                .into_iter()
1375                .collect::<HashSet<_>>()
1376        );
1377
1378        let removed_bundle = world.entity_mut(e2).take::<(B, TableStored)>().unwrap();
1379        assert_eq!(removed_bundle, (B(2), TableStored("2")));
1380
1381        let results = query
1382            .iter(&world)
1383            .map(|(a, b)| (a.0, b.0))
1384            .collect::<HashSet<_>>();
1385        assert_eq!(
1386            results,
1387            [(1, "1"), (3, "3"),].into_iter().collect::<HashSet<_>>()
1388        );
1389
1390        let mut a_query = world.query::<&A>();
1391        let results = a_query.iter(&world).map(|a| a.0).collect::<HashSet<_>>();
1392        assert_eq!(results, [1, 3, 2].into_iter().collect::<HashSet<_>>());
1393
1394        let entity_ref = world.entity(e2);
1395        assert_eq!(
1396            entity_ref.get::<A>(),
1397            Some(&A(2)),
1398            "A is not in the removed bundle, so it should exist"
1399        );
1400        assert_eq!(
1401            entity_ref.get::<B>(),
1402            None,
1403            "B is in the removed bundle, so it should not exist"
1404        );
1405        assert_eq!(
1406            entity_ref.get::<TableStored>(),
1407            None,
1408            "TableStored is in the removed bundle, so it should not exist"
1409        );
1410    }
1411
1412    #[test]
1413    fn non_send_resource() {
1414        let mut world = World::default();
1415        world.insert_non_send_resource(123i32);
1416        world.insert_non_send_resource(456i64);
1417        assert_eq!(*world.non_send_resource::<i32>(), 123);
1418        assert_eq!(*world.non_send_resource_mut::<i64>(), 456);
1419    }
1420
1421    #[test]
1422    fn non_send_resource_points_to_distinct_data() {
1423        let mut world = World::default();
1424        world.insert_resource(A(123));
1425        world.insert_non_send_resource(A(456));
1426        assert_eq!(*world.resource::<A>(), A(123));
1427        assert_eq!(*world.non_send_resource::<A>(), A(456));
1428    }
1429
1430    #[test]
1431    #[should_panic]
1432    fn non_send_resource_panic() {
1433        let mut world = World::default();
1434        world.insert_non_send_resource(0i32);
1435        std::thread::spawn(move || {
1436            let _ = world.non_send_resource_mut::<i32>();
1437        })
1438        .join()
1439        .unwrap();
1440    }
1441
1442    #[test]
1443    fn exact_size_query() {
1444        let mut world = World::default();
1445        world.spawn((A(0), B(0)));
1446        world.spawn((A(0), B(0)));
1447        world.spawn((A(0), B(0), C));
1448        world.spawn(C);
1449
1450        let mut query = world.query::<(&A, &B)>();
1451        assert_eq!(query.iter(&world).len(), 3);
1452    }
1453
1454    #[test]
1455    #[should_panic]
1456    fn duplicate_components_panic() {
1457        let mut world = World::new();
1458        world.spawn((A(1), A(2)));
1459    }
1460
1461    #[test]
1462    #[should_panic]
1463    fn ref_and_mut_query_panic() {
1464        let mut world = World::new();
1465        world.query::<(&A, &mut A)>();
1466    }
1467
1468    #[test]
1469    #[should_panic]
1470    fn entity_ref_and_mut_query_panic() {
1471        let mut world = World::new();
1472        world.query::<(EntityRef, &mut A)>();
1473    }
1474
1475    #[test]
1476    #[should_panic]
1477    fn mut_and_ref_query_panic() {
1478        let mut world = World::new();
1479        world.query::<(&mut A, &A)>();
1480    }
1481
1482    #[test]
1483    #[should_panic]
1484    fn mut_and_entity_ref_query_panic() {
1485        let mut world = World::new();
1486        world.query::<(&mut A, EntityRef)>();
1487    }
1488
1489    #[test]
1490    #[should_panic]
1491    fn entity_ref_and_entity_mut_query_panic() {
1492        let mut world = World::new();
1493        world.query::<(EntityRef, EntityMut)>();
1494    }
1495
1496    #[test]
1497    #[should_panic]
1498    fn entity_mut_and_entity_mut_query_panic() {
1499        let mut world = World::new();
1500        world.query::<(EntityMut, EntityMut)>();
1501    }
1502
1503    #[test]
1504    fn entity_ref_and_entity_ref_query_no_panic() {
1505        let mut world = World::new();
1506        world.query::<(EntityRef, EntityRef)>();
1507    }
1508
1509    #[test]
1510    #[should_panic]
1511    fn mut_and_mut_query_panic() {
1512        let mut world = World::new();
1513        world.query::<(&mut A, &mut A)>();
1514    }
1515
1516    #[test]
1517    #[should_panic]
1518    fn multiple_worlds_same_query_iter() {
1519        let mut world_a = World::new();
1520        let world_b = World::new();
1521        let mut query = world_a.query::<&A>();
1522        query.iter(&world_a);
1523        query.iter(&world_b);
1524    }
1525
1526    #[test]
1527    fn query_filters_dont_collide_with_fetches() {
1528        let mut world = World::new();
1529        world.query_filtered::<&mut A, Changed<A>>();
1530    }
1531
1532    #[test]
1533    fn filtered_query_access() {
1534        let mut world = World::new();
1535        // We remove entity disabling so it doesn't affect our query filters
1536        world.remove_resource::<DefaultQueryFilters>();
1537        let query = world.query_filtered::<&mut A, Changed<B>>();
1538
1539        let mut expected = FilteredAccess::default();
1540        let a_id = world.components.get_id(TypeId::of::<A>()).unwrap();
1541        let b_id = world.components.get_id(TypeId::of::<B>()).unwrap();
1542        expected.add_component_write(a_id);
1543        expected.add_component_read(b_id);
1544        assert!(
1545            query.component_access.eq(&expected),
1546            "ComponentId access from query fetch and query filter should be combined"
1547        );
1548    }
1549
1550    #[test]
1551    #[should_panic]
1552    fn multiple_worlds_same_query_get() {
1553        let mut world_a = World::new();
1554        let world_b = World::new();
1555        let mut query = world_a.query::<&A>();
1556        let _ = query.get(&world_a, Entity::from_raw_u32(0).unwrap());
1557        let _ = query.get(&world_b, Entity::from_raw_u32(0).unwrap());
1558    }
1559
1560    #[test]
1561    #[should_panic]
1562    fn multiple_worlds_same_query_for_each() {
1563        let mut world_a = World::new();
1564        let world_b = World::new();
1565        let mut query = world_a.query::<&A>();
1566        query.iter(&world_a).for_each(|_| {});
1567        query.iter(&world_b).for_each(|_| {});
1568    }
1569
1570    #[test]
1571    fn resource_scope() {
1572        let mut world = World::default();
1573        assert!(world.try_resource_scope::<A, _>(|_, _| {}).is_none());
1574        world.insert_resource(A(0));
1575        world.resource_scope(|world: &mut World, mut value: Mut<A>| {
1576            value.0 += 1;
1577            assert!(!world.contains_resource::<A>());
1578        });
1579        assert_eq!(world.resource::<A>().0, 1);
1580    }
1581
1582    #[test]
1583    #[should_panic]
1584    fn non_send_resource_drop_from_different_thread() {
1585        let mut world = World::default();
1586        world.insert_non_send_resource(NonSendA::default());
1587
1588        let thread = std::thread::spawn(move || {
1589            // Dropping the non-send resource on a different thread
1590            // Should result in a panic
1591            drop(world);
1592        });
1593
1594        if let Err(err) = thread.join() {
1595            std::panic::resume_unwind(err);
1596        }
1597    }
1598
1599    #[test]
1600    fn non_send_resource_drop_from_same_thread() {
1601        let mut world = World::default();
1602        world.insert_non_send_resource(NonSendA::default());
1603        drop(world);
1604    }
1605
1606    #[test]
1607    fn insert_overwrite_drop() {
1608        let (dropck1, dropped1) = DropCk::new_pair();
1609        let (dropck2, dropped2) = DropCk::new_pair();
1610        let mut world = World::default();
1611        world.spawn(dropck1).insert(dropck2);
1612        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1613        assert_eq!(dropped2.load(Ordering::Relaxed), 0);
1614        drop(world);
1615        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1616        assert_eq!(dropped2.load(Ordering::Relaxed), 1);
1617    }
1618
1619    #[test]
1620    fn insert_overwrite_drop_sparse() {
1621        let (dropck1, dropped1) = DropCk::new_pair();
1622        let (dropck2, dropped2) = DropCk::new_pair();
1623        let mut world = World::default();
1624
1625        world
1626            .spawn(DropCkSparse(dropck1))
1627            .insert(DropCkSparse(dropck2));
1628        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1629        assert_eq!(dropped2.load(Ordering::Relaxed), 0);
1630        drop(world);
1631        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1632        assert_eq!(dropped2.load(Ordering::Relaxed), 1);
1633    }
1634
1635    #[test]
1636    fn clear_entities() {
1637        let mut world = World::default();
1638
1639        world.insert_resource(A(0));
1640        world.spawn(A(1));
1641        world.spawn(SparseStored(1));
1642
1643        let mut q1 = world.query::<&A>();
1644        let mut q2 = world.query::<&SparseStored>();
1645        let mut q3 = world.query::<()>();
1646
1647        assert_eq!(q1.query(&world).count(), 1);
1648        assert_eq!(q2.query(&world).count(), 1);
1649        assert_eq!(q3.query(&world).count(), 2);
1650
1651        world.clear_entities();
1652
1653        assert_eq!(
1654            q1.query(&world).count(),
1655            0,
1656            "world should not contain table components"
1657        );
1658        assert_eq!(
1659            q2.query(&world).count(),
1660            0,
1661            "world should not contain sparse set components"
1662        );
1663        assert_eq!(
1664            q3.query(&world).count(),
1665            0,
1666            "world should not have any entities"
1667        );
1668        assert_eq!(
1669            world.resource::<A>().0,
1670            0,
1671            "world should still contain resources"
1672        );
1673    }
1674
1675    #[test]
1676    fn test_is_archetypal_size_hints() {
1677        let mut world = World::default();
1678        macro_rules! query_min_size {
1679            ($query:ty, $filter:ty) => {
1680                world
1681                    .query_filtered::<$query, $filter>()
1682                    .iter(&world)
1683                    .size_hint()
1684                    .0
1685            };
1686        }
1687
1688        world.spawn((A(1), B(1), C));
1689        world.spawn((A(1), C));
1690        world.spawn((A(1), B(1)));
1691        world.spawn((B(1), C));
1692        world.spawn(A(1));
1693        world.spawn(C);
1694        assert_eq!(2, query_min_size![(), (With<A>, Without<B>)]);
1695        assert_eq!(3, query_min_size![&B, Or<(With<A>, With<C>)>]);
1696        assert_eq!(1, query_min_size![&B, (With<A>, With<C>)]);
1697        assert_eq!(1, query_min_size![(&A, &B), With<C>]);
1698        assert_eq!(4, query_min_size![&A, ()], "Simple Archetypal");
1699        assert_eq!(4, query_min_size![Ref<A>, ()]);
1700        // All the following should set minimum size to 0, as it's impossible to predict
1701        // how many entities the filters will trim.
1702        assert_eq!(0, query_min_size![(), Added<A>], "Simple Added");
1703        assert_eq!(0, query_min_size![(), Changed<A>], "Simple Changed");
1704        assert_eq!(0, query_min_size![(&A, &B), Changed<A>]);
1705        assert_eq!(0, query_min_size![&A, (Changed<A>, With<B>)]);
1706        assert_eq!(0, query_min_size![(&A, &B), Or<(Changed<A>, Changed<B>)>]);
1707    }
1708
1709    #[test]
1710    fn insert_batch() {
1711        let mut world = World::default();
1712        let e0 = world.spawn(A(0)).id();
1713        let e1 = world.spawn(B(0)).id();
1714
1715        let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1716
1717        world.insert_batch(values);
1718
1719        assert_eq!(
1720            world.get::<A>(e0),
1721            Some(&A(1)),
1722            "first entity's A component should have been replaced"
1723        );
1724        assert_eq!(
1725            world.get::<B>(e0),
1726            Some(&B(0)),
1727            "first entity should have received B component"
1728        );
1729        assert_eq!(
1730            world.get::<A>(e1),
1731            Some(&A(0)),
1732            "second entity should have received A component"
1733        );
1734        assert_eq!(
1735            world.get::<B>(e1),
1736            Some(&B(1)),
1737            "second entity's B component should have been replaced"
1738        );
1739    }
1740
1741    #[test]
1742    fn insert_batch_same_archetype() {
1743        let mut world = World::default();
1744        let e0 = world.spawn((A(0), B(0))).id();
1745        let e1 = world.spawn((A(0), B(0))).id();
1746        let e2 = world.spawn(B(0)).id();
1747
1748        let values = vec![(e0, (B(1), C)), (e1, (B(2), C)), (e2, (B(3), C))];
1749
1750        world.insert_batch(values);
1751        let mut query = world.query::<(Option<&A>, &B, &C)>();
1752        let component_values = query.get_many(&world, [e0, e1, e2]).unwrap();
1753
1754        assert_eq!(
1755            component_values,
1756            [(Some(&A(0)), &B(1), &C), (Some(&A(0)), &B(2), &C), (None, &B(3), &C)],
1757            "all entities should have had their B component replaced, received C component, and had their A component (or lack thereof) unchanged"
1758        );
1759    }
1760
1761    #[test]
1762    fn insert_batch_if_new() {
1763        let mut world = World::default();
1764        let e0 = world.spawn(A(0)).id();
1765        let e1 = world.spawn(B(0)).id();
1766
1767        let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1768
1769        world.insert_batch_if_new(values);
1770
1771        assert_eq!(
1772            world.get::<A>(e0),
1773            Some(&A(0)),
1774            "first entity's A component should not have been replaced"
1775        );
1776        assert_eq!(
1777            world.get::<B>(e0),
1778            Some(&B(0)),
1779            "first entity should have received B component"
1780        );
1781        assert_eq!(
1782            world.get::<A>(e1),
1783            Some(&A(0)),
1784            "second entity should have received A component"
1785        );
1786        assert_eq!(
1787            world.get::<B>(e1),
1788            Some(&B(0)),
1789            "second entity's B component should not have been replaced"
1790        );
1791    }
1792
1793    #[test]
1794    fn try_insert_batch() {
1795        let mut world = World::default();
1796        let e0 = world.spawn(A(0)).id();
1797        let e1 = Entity::from_raw_u32(1).unwrap();
1798
1799        let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1800
1801        let error = world.try_insert_batch(values).unwrap_err();
1802
1803        assert_eq!(e1, error.entities[0]);
1804
1805        assert_eq!(
1806            world.get::<A>(e0),
1807            Some(&A(1)),
1808            "first entity's A component should have been replaced"
1809        );
1810        assert_eq!(
1811            world.get::<B>(e0),
1812            Some(&B(0)),
1813            "first entity should have received B component"
1814        );
1815    }
1816
1817    #[test]
1818    fn try_insert_batch_if_new() {
1819        let mut world = World::default();
1820        let e0 = world.spawn(A(0)).id();
1821        let e1 = Entity::from_raw_u32(1).unwrap();
1822
1823        let values = vec![(e0, (A(1), B(0))), (e1, (A(0), B(1)))];
1824
1825        let error = world.try_insert_batch_if_new(values).unwrap_err();
1826
1827        assert_eq!(e1, error.entities[0]);
1828
1829        assert_eq!(
1830            world.get::<A>(e0),
1831            Some(&A(0)),
1832            "first entity's A component should not have been replaced"
1833        );
1834        assert_eq!(
1835            world.get::<B>(e0),
1836            Some(&B(0)),
1837            "first entity should have received B component"
1838        );
1839    }
1840
1841    #[derive(Default)]
1842    struct CaptureMapper(Vec<Entity>);
1843    impl EntityMapper for CaptureMapper {
1844        fn get_mapped(&mut self, source: Entity) -> Entity {
1845            self.0.push(source);
1846            source
1847        }
1848
1849        fn set_mapped(&mut self, _source: Entity, _target: Entity) {}
1850    }
1851
1852    #[test]
1853    fn map_struct_entities() {
1854        #[derive(Component)]
1855        #[expect(
1856            unused,
1857            reason = "extra fields are used to ensure the derive works properly"
1858        )]
1859        struct Foo(usize, #[entities] Entity);
1860
1861        #[derive(Component)]
1862        #[expect(
1863            unused,
1864            reason = "extra fields are used to ensure the derive works properly"
1865        )]
1866        struct Bar {
1867            #[entities]
1868            a: Entity,
1869            b: usize,
1870            #[entities]
1871            c: Vec<Entity>,
1872        }
1873
1874        let mut world = World::new();
1875        let e1 = world.spawn_empty().id();
1876        let e2 = world.spawn_empty().id();
1877        let e3 = world.spawn_empty().id();
1878
1879        let mut foo = Foo(1, e1);
1880        let mut mapper = CaptureMapper::default();
1881        Component::map_entities(&mut foo, &mut mapper);
1882        assert_eq!(&mapper.0, &[e1]);
1883
1884        let mut bar = Bar {
1885            a: e1,
1886            b: 1,
1887            c: vec![e2, e3],
1888        };
1889        let mut mapper = CaptureMapper::default();
1890        Component::map_entities(&mut bar, &mut mapper);
1891        assert_eq!(&mapper.0, &[e1, e2, e3]);
1892    }
1893
1894    #[test]
1895    fn map_enum_entities() {
1896        #[derive(Component)]
1897        #[expect(
1898            unused,
1899            reason = "extra fields are used to ensure the derive works properly"
1900        )]
1901        enum Foo {
1902            Bar(usize, #[entities] Entity),
1903            Baz {
1904                #[entities]
1905                a: Entity,
1906                b: usize,
1907                #[entities]
1908                c: Vec<Entity>,
1909            },
1910        }
1911
1912        let mut world = World::new();
1913        let e1 = world.spawn_empty().id();
1914        let e2 = world.spawn_empty().id();
1915        let e3 = world.spawn_empty().id();
1916
1917        let mut foo = Foo::Bar(1, e1);
1918        let mut mapper = CaptureMapper::default();
1919        Component::map_entities(&mut foo, &mut mapper);
1920        assert_eq!(&mapper.0, &[e1]);
1921
1922        let mut foo = Foo::Baz {
1923            a: e1,
1924            b: 1,
1925            c: vec![e2, e3],
1926        };
1927        let mut mapper = CaptureMapper::default();
1928        Component::map_entities(&mut foo, &mut mapper);
1929        assert_eq!(&mapper.0, &[e1, e2, e3]);
1930    }
1931
1932    #[expect(
1933        dead_code,
1934        reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1935    )]
1936    #[derive(Component)]
1937    struct ComponentA(u32);
1938
1939    #[expect(
1940        dead_code,
1941        reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1942    )]
1943    #[derive(Component)]
1944    struct ComponentB(u32);
1945
1946    #[derive(Bundle)]
1947    struct Simple(ComponentA);
1948
1949    #[expect(
1950        dead_code,
1951        reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1952    )]
1953    #[derive(Bundle)]
1954    struct Tuple(Simple, ComponentB);
1955
1956    #[expect(
1957        dead_code,
1958        reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1959    )]
1960    #[derive(Bundle)]
1961    struct Record {
1962        field0: Simple,
1963        field1: ComponentB,
1964    }
1965
1966    #[expect(
1967        dead_code,
1968        reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1969    )]
1970    #[derive(Component)]
1971    struct MyEntities {
1972        #[entities]
1973        entities: Vec<Entity>,
1974        #[entities]
1975        another_one: Entity,
1976        #[entities]
1977        maybe_entity: Option<Entity>,
1978        something_else: String,
1979    }
1980
1981    #[expect(
1982        dead_code,
1983        reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1984    )]
1985    #[derive(Component)]
1986    struct MyEntitiesTuple(#[entities] Vec<Entity>, #[entities] Entity, usize);
1987
1988    #[test]
1989    fn clone_entities() {
1990        use crate::entity::{ComponentCloneCtx, SourceComponent};
1991
1992        #[expect(
1993            dead_code,
1994            reason = "This struct is used as a compilation test to test the derive macros, and as such this field is intentionally never used."
1995        )]
1996        #[derive(Component)]
1997        #[component(clone_behavior = Ignore)]
1998        struct IgnoreClone;
1999
2000        #[expect(
2001            dead_code,
2002            reason = "This struct is used as a compilation test to test the derive macros, and as such this field is intentionally never used."
2003        )]
2004        #[derive(Component)]
2005        #[component(clone_behavior = Default)]
2006        struct DefaultClone;
2007
2008        #[expect(
2009            dead_code,
2010            reason = "This struct is used as a compilation test to test the derive macros, and as such this field is intentionally never used."
2011        )]
2012        #[derive(Component)]
2013        #[component(clone_behavior = Custom(custom_clone))]
2014        struct CustomClone;
2015
2016        #[expect(
2017            dead_code,
2018            reason = "This struct is used as a compilation test to test the derive macros, and as such this field is intentionally never used."
2019        )]
2020        #[derive(Component, Clone)]
2021        #[component(clone_behavior = clone::<Self>())]
2022        struct CloneFunction;
2023
2024        #[expect(
2025            dead_code,
2026            reason = "This struct is used as a compilation test to test the derive macros, and as such this field is intentionally never used."
2027        )]
2028        fn custom_clone(_source: &SourceComponent, _ctx: &mut ComponentCloneCtx) {}
2029    }
2030
2031    #[test]
2032    fn queue_register_component_toctou() {
2033        for _ in 0..1000 {
2034            let w = World::new();
2035
2036            std::thread::scope(|s| {
2037                let c1 = s.spawn(|| w.components_queue().queue_register_component::<A>());
2038                let c2 = s.spawn(|| w.components_queue().queue_register_component::<A>());
2039                assert_eq!(c1.join().unwrap(), c2.join().unwrap());
2040            });
2041        }
2042    }
2043}