bevy_ecs/
lib.rs

1// FIXME(11590): remove this once the lint is fixed
2#![allow(unsafe_op_in_unsafe_fn)]
3#![doc = include_str!("../README.md")]
4#![cfg_attr(docsrs, feature(doc_auto_cfg))]
5#![allow(unsafe_code)]
6#![doc(
7    html_logo_url = "https://bevyengine.org/assets/icon.png",
8    html_favicon_url = "https://bevyengine.org/assets/icon.png"
9)]
10
11#[cfg(target_pointer_width = "16")]
12compile_error!("bevy_ecs cannot safely compile for a 16-bit platform.");
13
14pub mod archetype;
15pub mod batching;
16pub mod bundle;
17pub mod change_detection;
18pub mod component;
19pub mod entity;
20pub mod event;
21pub mod identifier;
22pub mod intern;
23pub mod label;
24pub mod observer;
25pub mod query;
26#[cfg(feature = "bevy_reflect")]
27pub mod reflect;
28pub mod removal_detection;
29pub mod schedule;
30pub mod storage;
31pub mod system;
32pub mod world;
33
34pub use bevy_ptr as ptr;
35
36/// Most commonly used re-exported types.
37pub mod prelude {
38    #[doc(hidden)]
39    #[cfg(feature = "bevy_reflect")]
40    pub use crate::reflect::{
41        AppTypeRegistry, ReflectComponent, ReflectFromWorld, ReflectResource,
42    };
43    #[doc(hidden)]
44    pub use crate::{
45        bundle::Bundle,
46        change_detection::{DetectChanges, DetectChangesMut, Mut, Ref},
47        component::Component,
48        entity::{Entity, EntityMapper},
49        event::{Event, EventReader, EventWriter, Events, ShouldUpdateEvents},
50        observer::{Observer, Trigger},
51        query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without},
52        removal_detection::RemovedComponents,
53        schedule::{
54            apply_deferred, common_conditions::*, Condition, IntoSystemConfigs, IntoSystemSet,
55            IntoSystemSetConfigs, Schedule, Schedules, SystemSet,
56        },
57        system::{
58            Commands, Deferred, In, IntoSystem, Local, NonSend, NonSendMut, ParallelCommands,
59            ParamSet, Query, ReadOnlySystem, Res, ResMut, Resource, System, SystemBuilder,
60            SystemParamFunction,
61        },
62        world::{
63            EntityMut, EntityRef, EntityWorldMut, FromWorld, OnAdd, OnInsert, OnRemove, World,
64        },
65    };
66}
67
68#[cfg(test)]
69mod tests {
70    use crate as bevy_ecs;
71    use crate::prelude::Or;
72    use crate::{
73        bundle::Bundle,
74        change_detection::Ref,
75        component::{Component, ComponentId},
76        entity::Entity,
77        query::{Added, Changed, FilteredAccess, QueryFilter, With, Without},
78        system::Resource,
79        world::{EntityRef, Mut, World},
80    };
81    use bevy_tasks::{ComputeTaskPool, TaskPool};
82    use std::num::NonZeroU32;
83    use std::{
84        any::TypeId,
85        marker::PhantomData,
86        sync::{
87            atomic::{AtomicUsize, Ordering},
88            Arc, Mutex,
89        },
90    };
91
92    #[derive(Component, Resource, Debug, PartialEq, Eq, Clone, Copy)]
93    struct A(usize);
94    #[derive(Component, Debug, PartialEq, Eq, Clone, Copy)]
95    struct B(usize);
96    #[derive(Component, Debug, PartialEq, Eq, Clone, Copy)]
97    struct C;
98
99    #[allow(dead_code)]
100    #[derive(Default)]
101    struct NonSendA(usize, PhantomData<*mut ()>);
102
103    #[derive(Component, Clone, Debug)]
104    struct DropCk(Arc<AtomicUsize>);
105    impl DropCk {
106        fn new_pair() -> (Self, Arc<AtomicUsize>) {
107            let atomic = Arc::new(AtomicUsize::new(0));
108            (DropCk(atomic.clone()), atomic)
109        }
110    }
111
112    impl Drop for DropCk {
113        fn drop(&mut self) {
114            self.0.as_ref().fetch_add(1, Ordering::Relaxed);
115        }
116    }
117
118    // TODO: The compiler says the Debug and Clone are removed during dead code analysis. Investigate.
119    #[allow(dead_code)]
120    #[derive(Component, Clone, Debug)]
121    #[component(storage = "SparseSet")]
122    struct DropCkSparse(DropCk);
123
124    #[derive(Component, Copy, Clone, PartialEq, Eq, Debug)]
125    #[component(storage = "Table")]
126    struct TableStored(&'static str);
127    #[derive(Component, Copy, Clone, PartialEq, Eq, Debug)]
128    #[component(storage = "SparseSet")]
129    struct SparseStored(u32);
130
131    #[test]
132    fn random_access() {
133        let mut world = World::new();
134
135        let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
136        let f = world
137            .spawn((TableStored("def"), SparseStored(456), A(1)))
138            .id();
139        assert_eq!(world.get::<TableStored>(e).unwrap().0, "abc");
140        assert_eq!(world.get::<SparseStored>(e).unwrap().0, 123);
141        assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
142        assert_eq!(world.get::<SparseStored>(f).unwrap().0, 456);
143
144        // test archetype get_mut()
145        world.get_mut::<TableStored>(e).unwrap().0 = "xyz";
146        assert_eq!(world.get::<TableStored>(e).unwrap().0, "xyz");
147
148        // test sparse set get_mut()
149        world.get_mut::<SparseStored>(f).unwrap().0 = 42;
150        assert_eq!(world.get::<SparseStored>(f).unwrap().0, 42);
151    }
152
153    #[test]
154    fn bundle_derive() {
155        let mut world = World::new();
156
157        #[derive(Bundle, PartialEq, Debug)]
158        struct FooBundle {
159            x: TableStored,
160            y: SparseStored,
161        }
162        let mut ids = Vec::new();
163        <FooBundle as Bundle>::component_ids(
164            &mut world.components,
165            &mut world.storages,
166            &mut |id| {
167                ids.push(id);
168            },
169        );
170
171        assert_eq!(
172            ids,
173            &[
174                world.init_component::<TableStored>(),
175                world.init_component::<SparseStored>(),
176            ]
177        );
178
179        let e1 = world
180            .spawn(FooBundle {
181                x: TableStored("abc"),
182                y: SparseStored(123),
183            })
184            .id();
185        let e2 = world
186            .spawn((TableStored("def"), SparseStored(456), A(1)))
187            .id();
188        assert_eq!(world.get::<TableStored>(e1).unwrap().0, "abc");
189        assert_eq!(world.get::<SparseStored>(e1).unwrap().0, 123);
190        assert_eq!(world.get::<TableStored>(e2).unwrap().0, "def");
191        assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 456);
192
193        // test archetype get_mut()
194        world.get_mut::<TableStored>(e1).unwrap().0 = "xyz";
195        assert_eq!(world.get::<TableStored>(e1).unwrap().0, "xyz");
196
197        // test sparse set get_mut()
198        world.get_mut::<SparseStored>(e2).unwrap().0 = 42;
199        assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 42);
200
201        assert_eq!(
202            world.entity_mut(e1).take::<FooBundle>().unwrap(),
203            FooBundle {
204                x: TableStored("xyz"),
205                y: SparseStored(123),
206            }
207        );
208
209        #[derive(Bundle, PartialEq, Debug)]
210        struct NestedBundle {
211            a: A,
212            foo: FooBundle,
213            b: B,
214        }
215
216        let mut ids = Vec::new();
217        <NestedBundle as Bundle>::component_ids(
218            &mut world.components,
219            &mut world.storages,
220            &mut |id| {
221                ids.push(id);
222            },
223        );
224
225        assert_eq!(
226            ids,
227            &[
228                world.init_component::<A>(),
229                world.init_component::<TableStored>(),
230                world.init_component::<SparseStored>(),
231                world.init_component::<B>(),
232            ]
233        );
234
235        let e3 = world
236            .spawn(NestedBundle {
237                a: A(1),
238                foo: FooBundle {
239                    x: TableStored("ghi"),
240                    y: SparseStored(789),
241                },
242                b: B(2),
243            })
244            .id();
245
246        assert_eq!(world.get::<TableStored>(e3).unwrap().0, "ghi");
247        assert_eq!(world.get::<SparseStored>(e3).unwrap().0, 789);
248        assert_eq!(world.get::<A>(e3).unwrap().0, 1);
249        assert_eq!(world.get::<B>(e3).unwrap().0, 2);
250        assert_eq!(
251            world.entity_mut(e3).take::<NestedBundle>().unwrap(),
252            NestedBundle {
253                a: A(1),
254                foo: FooBundle {
255                    x: TableStored("ghi"),
256                    y: SparseStored(789),
257                },
258                b: B(2),
259            }
260        );
261
262        #[derive(Default, Component, PartialEq, Debug)]
263        struct Ignored;
264
265        #[derive(Bundle, PartialEq, Debug)]
266        struct BundleWithIgnored {
267            c: C,
268            #[bundle(ignore)]
269            ignored: Ignored,
270        }
271
272        let mut ids = Vec::new();
273        <BundleWithIgnored as Bundle>::component_ids(
274            &mut world.components,
275            &mut world.storages,
276            &mut |id| {
277                ids.push(id);
278            },
279        );
280
281        assert_eq!(ids, &[world.init_component::<C>(),]);
282
283        let e4 = world
284            .spawn(BundleWithIgnored {
285                c: C,
286                ignored: Ignored,
287            })
288            .id();
289
290        assert_eq!(world.get::<C>(e4).unwrap(), &C);
291        assert_eq!(world.get::<Ignored>(e4), None);
292
293        assert_eq!(
294            world.entity_mut(e4).take::<BundleWithIgnored>().unwrap(),
295            BundleWithIgnored {
296                c: C,
297                ignored: Ignored,
298            }
299        );
300    }
301
302    #[test]
303    fn despawn_table_storage() {
304        let mut world = World::new();
305        let e = world.spawn((TableStored("abc"), A(123))).id();
306        let f = world.spawn((TableStored("def"), A(456))).id();
307        assert_eq!(world.entities.len(), 2);
308        assert!(world.despawn(e));
309        assert_eq!(world.entities.len(), 1);
310        assert!(world.get::<TableStored>(e).is_none());
311        assert!(world.get::<A>(e).is_none());
312        assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
313        assert_eq!(world.get::<A>(f).unwrap().0, 456);
314    }
315
316    #[test]
317    fn despawn_mixed_storage() {
318        let mut world = World::new();
319
320        let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
321        let f = world.spawn((TableStored("def"), SparseStored(456))).id();
322        assert_eq!(world.entities.len(), 2);
323        assert!(world.despawn(e));
324        assert_eq!(world.entities.len(), 1);
325        assert!(world.get::<TableStored>(e).is_none());
326        assert!(world.get::<SparseStored>(e).is_none());
327        assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
328        assert_eq!(world.get::<SparseStored>(f).unwrap().0, 456);
329    }
330
331    #[test]
332    fn query_all() {
333        let mut world = World::new();
334        let e = world.spawn((TableStored("abc"), A(123))).id();
335        let f = world.spawn((TableStored("def"), A(456))).id();
336
337        let ents = world
338            .query::<(Entity, &A, &TableStored)>()
339            .iter(&world)
340            .map(|(e, &i, &s)| (e, i, s))
341            .collect::<Vec<_>>();
342        assert_eq!(
343            ents,
344            &[
345                (e, A(123), TableStored("abc")),
346                (f, A(456), TableStored("def"))
347            ]
348        );
349    }
350
351    #[test]
352    fn query_all_for_each() {
353        let mut world = World::new();
354        let e = world.spawn((TableStored("abc"), A(123))).id();
355        let f = world.spawn((TableStored("def"), A(456))).id();
356
357        let mut results = Vec::new();
358        world
359            .query::<(Entity, &A, &TableStored)>()
360            .iter(&world)
361            .for_each(|(e, &i, &s)| results.push((e, i, s)));
362        assert_eq!(
363            results,
364            &[
365                (e, A(123), TableStored("abc")),
366                (f, A(456), TableStored("def"))
367            ]
368        );
369    }
370
371    #[test]
372    fn query_single_component() {
373        let mut world = World::new();
374        let e = world.spawn((TableStored("abc"), A(123))).id();
375        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
376        let ents = world
377            .query::<(Entity, &A)>()
378            .iter(&world)
379            .map(|(e, &i)| (e, i))
380            .collect::<Vec<_>>();
381        assert_eq!(ents, &[(e, A(123)), (f, A(456))]);
382    }
383
384    #[test]
385    fn stateful_query_handles_new_archetype() {
386        let mut world = World::new();
387        let e = world.spawn((TableStored("abc"), A(123))).id();
388        let mut query = world.query::<(Entity, &A)>();
389
390        let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
391        assert_eq!(ents, &[(e, A(123))]);
392
393        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
394        let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
395        assert_eq!(ents, &[(e, A(123)), (f, A(456))]);
396    }
397
398    #[test]
399    fn query_single_component_for_each() {
400        let mut world = World::new();
401        let e = world.spawn((TableStored("abc"), A(123))).id();
402        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
403        let mut results = Vec::new();
404        world
405            .query::<(Entity, &A)>()
406            .iter(&world)
407            .for_each(|(e, &i)| results.push((e, i)));
408        assert_eq!(results, &[(e, A(123)), (f, A(456))]);
409    }
410
411    #[test]
412    fn par_for_each_dense() {
413        ComputeTaskPool::get_or_init(TaskPool::default);
414        let mut world = World::new();
415        let e1 = world.spawn(A(1)).id();
416        let e2 = world.spawn(A(2)).id();
417        let e3 = world.spawn(A(3)).id();
418        let e4 = world.spawn((A(4), B(1))).id();
419        let e5 = world.spawn((A(5), B(1))).id();
420        let results = Arc::new(Mutex::new(Vec::new()));
421        world
422            .query::<(Entity, &A)>()
423            .par_iter(&world)
424            .for_each(|(e, &A(i))| {
425                results.lock().unwrap().push((e, i));
426            });
427        results.lock().unwrap().sort();
428        assert_eq!(
429            &*results.lock().unwrap(),
430            &[(e1, 1), (e2, 2), (e3, 3), (e4, 4), (e5, 5)]
431        );
432    }
433
434    #[test]
435    fn par_for_each_sparse() {
436        ComputeTaskPool::get_or_init(TaskPool::default);
437        let mut world = World::new();
438        let e1 = world.spawn(SparseStored(1)).id();
439        let e2 = world.spawn(SparseStored(2)).id();
440        let e3 = world.spawn(SparseStored(3)).id();
441        let e4 = world.spawn((SparseStored(4), A(1))).id();
442        let e5 = world.spawn((SparseStored(5), A(1))).id();
443        let results = Arc::new(Mutex::new(Vec::new()));
444        world
445            .query::<(Entity, &SparseStored)>()
446            .par_iter(&world)
447            .for_each(|(e, &SparseStored(i))| results.lock().unwrap().push((e, i)));
448        results.lock().unwrap().sort();
449        assert_eq!(
450            &*results.lock().unwrap(),
451            &[(e1, 1), (e2, 2), (e3, 3), (e4, 4), (e5, 5)]
452        );
453    }
454
455    #[test]
456    fn query_missing_component() {
457        let mut world = World::new();
458        world.spawn((TableStored("abc"), A(123)));
459        world.spawn((TableStored("def"), A(456)));
460        assert!(world.query::<(&B, &A)>().iter(&world).next().is_none());
461    }
462
463    #[test]
464    fn query_sparse_component() {
465        let mut world = World::new();
466        world.spawn((TableStored("abc"), A(123)));
467        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
468        let ents = world
469            .query::<(Entity, &B)>()
470            .iter(&world)
471            .map(|(e, &b)| (e, b))
472            .collect::<Vec<_>>();
473        assert_eq!(ents, &[(f, B(1))]);
474    }
475
476    #[test]
477    fn query_filter_with() {
478        let mut world = World::new();
479        world.spawn((A(123), B(1)));
480        world.spawn(A(456));
481        let result = world
482            .query_filtered::<&A, With<B>>()
483            .iter(&world)
484            .cloned()
485            .collect::<Vec<_>>();
486        assert_eq!(result, vec![A(123)]);
487    }
488
489    #[test]
490    fn query_filter_with_for_each() {
491        let mut world = World::new();
492        world.spawn((A(123), B(1)));
493        world.spawn(A(456));
494
495        let mut results = Vec::new();
496        world
497            .query_filtered::<&A, With<B>>()
498            .iter(&world)
499            .for_each(|i| results.push(*i));
500        assert_eq!(results, vec![A(123)]);
501    }
502
503    #[test]
504    fn query_filter_with_sparse() {
505        let mut world = World::new();
506
507        world.spawn((A(123), SparseStored(321)));
508        world.spawn(A(456));
509        let result = world
510            .query_filtered::<&A, With<SparseStored>>()
511            .iter(&world)
512            .cloned()
513            .collect::<Vec<_>>();
514        assert_eq!(result, vec![A(123)]);
515    }
516
517    #[test]
518    fn query_filter_with_sparse_for_each() {
519        let mut world = World::new();
520
521        world.spawn((A(123), SparseStored(321)));
522        world.spawn(A(456));
523        let mut results = Vec::new();
524        world
525            .query_filtered::<&A, With<SparseStored>>()
526            .iter(&world)
527            .for_each(|i| results.push(*i));
528        assert_eq!(results, vec![A(123)]);
529    }
530
531    #[test]
532    fn query_filter_without() {
533        let mut world = World::new();
534        world.spawn((A(123), B(321)));
535        world.spawn(A(456));
536        let result = world
537            .query_filtered::<&A, Without<B>>()
538            .iter(&world)
539            .cloned()
540            .collect::<Vec<_>>();
541        assert_eq!(result, vec![A(456)]);
542    }
543
544    #[test]
545    fn query_optional_component_table() {
546        let mut world = World::new();
547        let e = world.spawn((TableStored("abc"), A(123))).id();
548        let f = world.spawn((TableStored("def"), A(456), B(1))).id();
549        // this should be skipped
550        world.spawn(TableStored("abc"));
551        let ents = world
552            .query::<(Entity, Option<&B>, &A)>()
553            .iter(&world)
554            .map(|(e, b, &i)| (e, b.copied(), i))
555            .collect::<Vec<_>>();
556        assert_eq!(ents, &[(e, None, A(123)), (f, Some(B(1)), A(456))]);
557    }
558
559    #[test]
560    fn query_optional_component_sparse() {
561        let mut world = World::new();
562
563        let e = world.spawn((TableStored("abc"), A(123))).id();
564        let f = world
565            .spawn((TableStored("def"), A(456), SparseStored(1)))
566            .id();
567        // this should be skipped
568        // world.spawn(SparseStored(1));
569        let ents = world
570            .query::<(Entity, Option<&SparseStored>, &A)>()
571            .iter(&world)
572            .map(|(e, b, &i)| (e, b.copied(), i))
573            .collect::<Vec<_>>();
574        assert_eq!(
575            ents,
576            &[(e, None, A(123)), (f, Some(SparseStored(1)), A(456))]
577        );
578    }
579
580    #[test]
581    fn query_optional_component_sparse_no_match() {
582        let mut world = World::new();
583
584        let e = world.spawn((TableStored("abc"), A(123))).id();
585        let f = world.spawn((TableStored("def"), A(456))).id();
586        // // this should be skipped
587        world.spawn(TableStored("abc"));
588        let ents = world
589            .query::<(Entity, Option<&SparseStored>, &A)>()
590            .iter(&world)
591            .map(|(e, b, &i)| (e, b.copied(), i))
592            .collect::<Vec<_>>();
593        assert_eq!(ents, &[(e, None, A(123)), (f, None, A(456))]);
594    }
595
596    #[test]
597    fn add_remove_components() {
598        let mut world = World::new();
599        let e1 = world.spawn((A(1), B(3), TableStored("abc"))).id();
600        let e2 = world.spawn((A(2), B(4), TableStored("xyz"))).id();
601
602        assert_eq!(
603            world
604                .query::<(Entity, &A, &B)>()
605                .iter(&world)
606                .map(|(e, &i, &b)| (e, i, b))
607                .collect::<Vec<_>>(),
608            &[(e1, A(1), B(3)), (e2, A(2), B(4))]
609        );
610
611        assert_eq!(world.entity_mut(e1).take::<A>(), Some(A(1)));
612        assert_eq!(
613            world
614                .query::<(Entity, &A, &B)>()
615                .iter(&world)
616                .map(|(e, &i, &b)| (e, i, b))
617                .collect::<Vec<_>>(),
618            &[(e2, A(2), B(4))]
619        );
620        assert_eq!(
621            world
622                .query::<(Entity, &B, &TableStored)>()
623                .iter(&world)
624                .map(|(e, &B(b), &TableStored(s))| (e, b, s))
625                .collect::<Vec<_>>(),
626            &[(e2, 4, "xyz"), (e1, 3, "abc")]
627        );
628        world.entity_mut(e1).insert(A(43));
629        assert_eq!(
630            world
631                .query::<(Entity, &A, &B)>()
632                .iter(&world)
633                .map(|(e, &i, &b)| (e, i, b))
634                .collect::<Vec<_>>(),
635            &[(e2, A(2), B(4)), (e1, A(43), B(3))]
636        );
637        world.entity_mut(e1).insert(C);
638        assert_eq!(
639            world
640                .query::<(Entity, &C)>()
641                .iter(&world)
642                .map(|(e, &f)| (e, f))
643                .collect::<Vec<_>>(),
644            &[(e1, C)]
645        );
646    }
647
648    #[test]
649    fn table_add_remove_many() {
650        let mut world = World::default();
651        #[cfg(miri)]
652        let (mut entities, to) = {
653            let to = 10;
654            (Vec::with_capacity(to), to)
655        };
656        #[cfg(not(miri))]
657        let (mut entities, to) = {
658            let to = 10_000;
659            (Vec::with_capacity(to), to)
660        };
661
662        for _ in 0..to {
663            entities.push(world.spawn(B(0)).id());
664        }
665
666        for (i, entity) in entities.iter().cloned().enumerate() {
667            world.entity_mut(entity).insert(A(i));
668        }
669
670        for (i, entity) in entities.iter().cloned().enumerate() {
671            assert_eq!(world.entity_mut(entity).take::<A>(), Some(A(i)));
672        }
673    }
674
675    #[test]
676    fn sparse_set_add_remove_many() {
677        let mut world = World::default();
678
679        let mut entities = Vec::with_capacity(1000);
680        for _ in 0..4 {
681            entities.push(world.spawn(A(2)).id());
682        }
683
684        for (i, entity) in entities.iter().cloned().enumerate() {
685            world.entity_mut(entity).insert(SparseStored(i as u32));
686        }
687
688        for (i, entity) in entities.iter().cloned().enumerate() {
689            assert_eq!(
690                world.entity_mut(entity).take::<SparseStored>(),
691                Some(SparseStored(i as u32))
692            );
693        }
694    }
695
696    #[test]
697    fn remove_missing() {
698        let mut world = World::new();
699        let e = world.spawn((TableStored("abc"), A(123))).id();
700        assert!(world.entity_mut(e).take::<B>().is_none());
701    }
702
703    #[test]
704    fn spawn_batch() {
705        let mut world = World::new();
706        world.spawn_batch((0..100).map(|x| (A(x), TableStored("abc"))));
707        let values = world
708            .query::<&A>()
709            .iter(&world)
710            .map(|v| v.0)
711            .collect::<Vec<_>>();
712        let expected = (0..100).collect::<Vec<_>>();
713        assert_eq!(values, expected);
714    }
715
716    #[test]
717    fn query_get() {
718        let mut world = World::new();
719        let a = world.spawn((TableStored("abc"), A(123))).id();
720        let b = world.spawn((TableStored("def"), A(456))).id();
721        let c = world.spawn((TableStored("ghi"), A(789), B(1))).id();
722
723        let mut i32_query = world.query::<&A>();
724        assert_eq!(i32_query.get(&world, a).unwrap().0, 123);
725        assert_eq!(i32_query.get(&world, b).unwrap().0, 456);
726
727        let mut i32_bool_query = world.query::<(&A, &B)>();
728        assert!(i32_bool_query.get(&world, a).is_err());
729        assert_eq!(i32_bool_query.get(&world, c).unwrap(), (&A(789), &B(1)));
730        assert!(world.despawn(a));
731        assert!(i32_query.get(&world, a).is_err());
732    }
733
734    #[test]
735    fn query_get_works_across_sparse_removal() {
736        // Regression test for: https://github.com/bevyengine/bevy/issues/6623
737        let mut world = World::new();
738        let a = world.spawn((TableStored("abc"), SparseStored(123))).id();
739        let b = world.spawn((TableStored("def"), SparseStored(456))).id();
740        let c = world
741            .spawn((TableStored("ghi"), SparseStored(789), B(1)))
742            .id();
743
744        let mut query = world.query::<&TableStored>();
745        assert_eq!(query.get(&world, a).unwrap(), &TableStored("abc"));
746        assert_eq!(query.get(&world, b).unwrap(), &TableStored("def"));
747        assert_eq!(query.get(&world, c).unwrap(), &TableStored("ghi"));
748
749        world.entity_mut(b).remove::<SparseStored>();
750        world.entity_mut(c).remove::<SparseStored>();
751
752        assert_eq!(query.get(&world, a).unwrap(), &TableStored("abc"));
753        assert_eq!(query.get(&world, b).unwrap(), &TableStored("def"));
754        assert_eq!(query.get(&world, c).unwrap(), &TableStored("ghi"));
755    }
756
757    #[test]
758    fn remove_tracking() {
759        let mut world = World::new();
760
761        let a = world.spawn((SparseStored(0), A(123))).id();
762        let b = world.spawn((SparseStored(1), A(123))).id();
763
764        world.entity_mut(a).despawn();
765        assert_eq!(
766            world.removed::<A>().collect::<Vec<_>>(),
767            &[a],
768            "despawning results in 'removed component' state for table components"
769        );
770        assert_eq!(
771            world.removed::<SparseStored>().collect::<Vec<_>>(),
772            &[a],
773            "despawning results in 'removed component' state for sparse set components"
774        );
775
776        world.entity_mut(b).insert(B(1));
777        assert_eq!(
778            world.removed::<A>().collect::<Vec<_>>(),
779            &[a],
780            "archetype moves does not result in 'removed component' state"
781        );
782
783        world.entity_mut(b).remove::<A>();
784        assert_eq!(
785            world.removed::<A>().collect::<Vec<_>>(),
786            &[a, b],
787            "removing a component results in a 'removed component' state"
788        );
789
790        world.clear_trackers();
791        assert_eq!(
792            world.removed::<A>().collect::<Vec<_>>(),
793            &[],
794            "clearing trackers clears removals"
795        );
796        assert_eq!(
797            world.removed::<SparseStored>().collect::<Vec<_>>(),
798            &[],
799            "clearing trackers clears removals"
800        );
801        assert_eq!(
802            world.removed::<B>().collect::<Vec<_>>(),
803            &[],
804            "clearing trackers clears removals"
805        );
806
807        // TODO: uncomment when world.clear() is implemented
808        // let c = world.spawn(("abc", 123)).id();
809        // let d = world.spawn(("abc", 123)).id();
810        // world.clear();
811        // assert_eq!(
812        //     world.removed::<i32>(),
813        //     &[c, d],
814        //     "world clears result in 'removed component' states"
815        // );
816        // assert_eq!(
817        //     world.removed::<&'static str>(),
818        //     &[c, d, b],
819        //     "world clears result in 'removed component' states"
820        // );
821        // assert_eq!(
822        //     world.removed::<f64>(),
823        //     &[b],
824        //     "world clears result in 'removed component' states"
825        // );
826    }
827
828    #[test]
829    fn added_tracking() {
830        let mut world = World::new();
831        let a = world.spawn(A(123)).id();
832
833        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
834        assert_eq!(
835            world.query_filtered::<(), Added<A>>().iter(&world).count(),
836            1
837        );
838        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
839        assert_eq!(
840            world.query_filtered::<(), Added<A>>().iter(&world).count(),
841            1
842        );
843        assert!(world.query::<&A>().get(&world, a).is_ok());
844        assert!(world
845            .query_filtered::<(), Added<A>>()
846            .get(&world, a)
847            .is_ok());
848        assert!(world.query::<&A>().get(&world, a).is_ok());
849        assert!(world
850            .query_filtered::<(), Added<A>>()
851            .get(&world, a)
852            .is_ok());
853
854        world.clear_trackers();
855
856        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
857        assert_eq!(
858            world.query_filtered::<(), Added<A>>().iter(&world).count(),
859            0
860        );
861        assert_eq!(world.query::<&A>().iter(&world).count(), 1);
862        assert_eq!(
863            world.query_filtered::<(), Added<A>>().iter(&world).count(),
864            0
865        );
866        assert!(world.query::<&A>().get(&world, a).is_ok());
867        assert!(world
868            .query_filtered::<(), Added<A>>()
869            .get(&world, a)
870            .is_err());
871        assert!(world.query::<&A>().get(&world, a).is_ok());
872        assert!(world
873            .query_filtered::<(), Added<A>>()
874            .get(&world, a)
875            .is_err());
876    }
877
878    #[test]
879    fn added_queries() {
880        let mut world = World::default();
881        let e1 = world.spawn(A(0)).id();
882
883        fn get_added<Com: Component>(world: &mut World) -> Vec<Entity> {
884            world
885                .query_filtered::<Entity, Added<Com>>()
886                .iter(world)
887                .collect::<Vec<Entity>>()
888        }
889
890        assert_eq!(get_added::<A>(&mut world), vec![e1]);
891        world.entity_mut(e1).insert(B(0));
892        assert_eq!(get_added::<A>(&mut world), vec![e1]);
893        assert_eq!(get_added::<B>(&mut world), vec![e1]);
894
895        world.clear_trackers();
896        assert!(get_added::<A>(&mut world).is_empty());
897        let e2 = world.spawn((A(1), B(1))).id();
898        assert_eq!(get_added::<A>(&mut world), vec![e2]);
899        assert_eq!(get_added::<B>(&mut world), vec![e2]);
900
901        let added = world
902            .query_filtered::<Entity, (Added<A>, Added<B>)>()
903            .iter(&world)
904            .collect::<Vec<Entity>>();
905        assert_eq!(added, vec![e2]);
906    }
907
908    #[test]
909    fn changed_trackers() {
910        let mut world = World::default();
911        let e1 = world.spawn((A(0), B(0))).id();
912        let e2 = world.spawn((A(0), B(0))).id();
913        let e3 = world.spawn((A(0), B(0))).id();
914        world.spawn((A(0), B(0)));
915
916        world.clear_trackers();
917
918        for (i, mut a) in world.query::<&mut A>().iter_mut(&mut world).enumerate() {
919            if i % 2 == 0 {
920                a.0 += 1;
921            }
922        }
923
924        fn get_filtered<F: QueryFilter>(world: &mut World) -> Vec<Entity> {
925            world
926                .query_filtered::<Entity, F>()
927                .iter(world)
928                .collect::<Vec<Entity>>()
929        }
930
931        assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e1, e3]);
932
933        // ensure changing an entity's archetypes also moves its changed state
934        world.entity_mut(e1).insert(C);
935
936        assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)");
937
938        // spawning a new A entity should not change existing changed state
939        world.entity_mut(e1).insert((A(0), B(0)));
940        assert_eq!(
941            get_filtered::<Changed<A>>(&mut world),
942            vec![e3, e1],
943            "changed entities list should not change"
944        );
945
946        // removing an unchanged entity should not change changed state
947        assert!(world.despawn(e2));
948        assert_eq!(
949            get_filtered::<Changed<A>>(&mut world),
950            vec![e3, e1],
951            "changed entities list should not change"
952        );
953
954        // removing a changed entity should remove it from enumeration
955        assert!(world.despawn(e1));
956        assert_eq!(
957            get_filtered::<Changed<A>>(&mut world),
958            vec![e3],
959            "e1 should no longer be returned"
960        );
961
962        world.clear_trackers();
963
964        assert!(get_filtered::<Changed<A>>(&mut world).is_empty());
965
966        let e4 = world.spawn_empty().id();
967
968        world.entity_mut(e4).insert(A(0));
969        assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
970        assert_eq!(get_filtered::<Added<A>>(&mut world), vec![e4]);
971
972        world.entity_mut(e4).insert(A(1));
973        assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
974
975        world.clear_trackers();
976
977        // ensure inserting multiple components set changed state for all components and set added
978        // state for non existing components even when changing archetype.
979        world.entity_mut(e4).insert((A(0), B(0)));
980
981        assert!(get_filtered::<Added<A>>(&mut world).is_empty());
982        assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
983        assert_eq!(get_filtered::<Added<B>>(&mut world), vec![e4]);
984        assert_eq!(get_filtered::<Changed<B>>(&mut world), vec![e4]);
985    }
986
987    #[test]
988    fn changed_trackers_sparse() {
989        let mut world = World::default();
990        let e1 = world.spawn(SparseStored(0)).id();
991        let e2 = world.spawn(SparseStored(0)).id();
992        let e3 = world.spawn(SparseStored(0)).id();
993        world.spawn(SparseStored(0));
994
995        world.clear_trackers();
996
997        for (i, mut a) in world
998            .query::<&mut SparseStored>()
999            .iter_mut(&mut world)
1000            .enumerate()
1001        {
1002            if i % 2 == 0 {
1003                a.0 += 1;
1004            }
1005        }
1006
1007        fn get_filtered<F: QueryFilter>(world: &mut World) -> Vec<Entity> {
1008            world
1009                .query_filtered::<Entity, F>()
1010                .iter(world)
1011                .collect::<Vec<Entity>>()
1012        }
1013
1014        assert_eq!(
1015            get_filtered::<Changed<SparseStored>>(&mut world),
1016            vec![e1, e3]
1017        );
1018
1019        // ensure changing an entity's archetypes also moves its changed state
1020        world.entity_mut(e1).insert(C);
1021
1022        assert_eq!(get_filtered::<Changed<SparseStored>>(&mut world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)");
1023
1024        // spawning a new SparseStored entity should not change existing changed state
1025        world.entity_mut(e1).insert(SparseStored(0));
1026        assert_eq!(
1027            get_filtered::<Changed<SparseStored>>(&mut world),
1028            vec![e3, e1],
1029            "changed entities list should not change"
1030        );
1031
1032        // removing an unchanged entity should not change changed state
1033        assert!(world.despawn(e2));
1034        assert_eq!(
1035            get_filtered::<Changed<SparseStored>>(&mut world),
1036            vec![e3, e1],
1037            "changed entities list should not change"
1038        );
1039
1040        // removing a changed entity should remove it from enumeration
1041        assert!(world.despawn(e1));
1042        assert_eq!(
1043            get_filtered::<Changed<SparseStored>>(&mut world),
1044            vec![e3],
1045            "e1 should no longer be returned"
1046        );
1047
1048        world.clear_trackers();
1049
1050        assert!(get_filtered::<Changed<SparseStored>>(&mut world).is_empty());
1051
1052        let e4 = world.spawn_empty().id();
1053
1054        world.entity_mut(e4).insert(SparseStored(0));
1055        assert_eq!(get_filtered::<Changed<SparseStored>>(&mut world), vec![e4]);
1056        assert_eq!(get_filtered::<Added<SparseStored>>(&mut world), vec![e4]);
1057
1058        world.entity_mut(e4).insert(A(1));
1059        assert_eq!(get_filtered::<Changed<SparseStored>>(&mut world), vec![e4]);
1060
1061        world.clear_trackers();
1062
1063        // ensure inserting multiple components set changed state for all components and set added
1064        // state for non existing components even when changing archetype.
1065        world.entity_mut(e4).insert(SparseStored(0));
1066
1067        assert!(get_filtered::<Added<SparseStored>>(&mut world).is_empty());
1068        assert_eq!(get_filtered::<Changed<SparseStored>>(&mut world), vec![e4]);
1069    }
1070
1071    #[test]
1072    fn empty_spawn() {
1073        let mut world = World::default();
1074        let e = world.spawn_empty().id();
1075        let mut e_mut = world.entity_mut(e);
1076        e_mut.insert(A(0));
1077        assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
1078    }
1079
1080    #[test]
1081    fn reserve_and_spawn() {
1082        let mut world = World::default();
1083        let e = world.entities().reserve_entity();
1084        world.flush_entities();
1085        let mut e_mut = world.entity_mut(e);
1086        e_mut.insert(A(0));
1087        assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
1088    }
1089
1090    #[test]
1091    fn changed_query() {
1092        let mut world = World::default();
1093        let e1 = world.spawn((A(0), B(0))).id();
1094
1095        fn get_changed(world: &mut World) -> Vec<Entity> {
1096            world
1097                .query_filtered::<Entity, Changed<A>>()
1098                .iter(world)
1099                .collect::<Vec<Entity>>()
1100        }
1101        assert_eq!(get_changed(&mut world), vec![e1]);
1102        world.clear_trackers();
1103        assert_eq!(get_changed(&mut world), vec![]);
1104        *world.get_mut(e1).unwrap() = A(1);
1105        assert_eq!(get_changed(&mut world), vec![e1]);
1106    }
1107
1108    #[test]
1109    fn resource() {
1110        use crate::system::Resource;
1111
1112        #[derive(Resource, PartialEq, Debug)]
1113        struct Num(i32);
1114
1115        #[derive(Resource, PartialEq, Debug)]
1116        struct BigNum(u64);
1117
1118        let mut world = World::default();
1119        assert!(world.get_resource::<Num>().is_none());
1120        assert!(!world.contains_resource::<Num>());
1121        assert!(!world.is_resource_added::<Num>());
1122        assert!(!world.is_resource_changed::<Num>());
1123
1124        world.insert_resource(Num(123));
1125        let resource_id = world
1126            .components()
1127            .get_resource_id(TypeId::of::<Num>())
1128            .unwrap();
1129        let archetype_component_id = world.storages().resources.get(resource_id).unwrap().id();
1130
1131        assert_eq!(world.resource::<Num>().0, 123);
1132        assert!(world.contains_resource::<Num>());
1133        assert!(world.is_resource_added::<Num>());
1134        assert!(world.is_resource_changed::<Num>());
1135
1136        world.insert_resource(BigNum(456));
1137        assert_eq!(world.resource::<BigNum>().0, 456u64);
1138
1139        world.insert_resource(BigNum(789));
1140        assert_eq!(world.resource::<BigNum>().0, 789);
1141
1142        {
1143            let mut value = world.resource_mut::<BigNum>();
1144            assert_eq!(value.0, 789);
1145            value.0 = 10;
1146        }
1147
1148        assert_eq!(
1149            world.resource::<BigNum>().0,
1150            10,
1151            "resource changes are preserved"
1152        );
1153
1154        assert_eq!(
1155            world.remove_resource::<BigNum>(),
1156            Some(BigNum(10)),
1157            "removed resource has the correct value"
1158        );
1159        assert_eq!(
1160            world.get_resource::<BigNum>(),
1161            None,
1162            "removed resource no longer exists"
1163        );
1164        assert_eq!(
1165            world.remove_resource::<BigNum>(),
1166            None,
1167            "double remove returns nothing"
1168        );
1169
1170        world.insert_resource(BigNum(1));
1171        assert_eq!(
1172            world.get_resource::<BigNum>(),
1173            Some(&BigNum(1)),
1174            "re-inserting resources works"
1175        );
1176
1177        assert_eq!(
1178            world.get_resource::<Num>(),
1179            Some(&Num(123)),
1180            "other resources are unaffected"
1181        );
1182
1183        let current_resource_id = world
1184            .components()
1185            .get_resource_id(TypeId::of::<Num>())
1186            .unwrap();
1187        assert_eq!(
1188            resource_id, current_resource_id,
1189            "resource id does not change after removing / re-adding"
1190        );
1191
1192        let current_archetype_component_id =
1193            world.storages().resources.get(resource_id).unwrap().id();
1194
1195        assert_eq!(
1196            archetype_component_id, current_archetype_component_id,
1197            "resource archetype component id does not change after removing / re-adding"
1198        );
1199    }
1200
1201    #[test]
1202    fn remove() {
1203        let mut world = World::default();
1204        let e1 = world.spawn((A(1), B(1), TableStored("a"))).id();
1205
1206        let mut e = world.entity_mut(e1);
1207        assert_eq!(e.get::<TableStored>(), Some(&TableStored("a")));
1208        assert_eq!(e.get::<A>(), Some(&A(1)));
1209        assert_eq!(e.get::<B>(), Some(&B(1)));
1210        assert_eq!(
1211            e.get::<C>(),
1212            None,
1213            "C is not in the entity, so it should not exist"
1214        );
1215
1216        e.remove::<(A, B, C)>();
1217        assert_eq!(
1218            e.get::<TableStored>(),
1219            Some(&TableStored("a")),
1220            "TableStored is not in the removed bundle, so it should exist"
1221        );
1222        assert_eq!(
1223            e.get::<A>(),
1224            None,
1225            "Num is in the removed bundle, so it should not exist"
1226        );
1227        assert_eq!(
1228            e.get::<B>(),
1229            None,
1230            "f64 is in the removed bundle, so it should not exist"
1231        );
1232        assert_eq!(
1233            e.get::<C>(),
1234            None,
1235            "usize is in the removed bundle, so it should not exist"
1236        );
1237    }
1238
1239    #[test]
1240    fn take() {
1241        let mut world = World::default();
1242        world.spawn((A(1), B(1), TableStored("1")));
1243        let e2 = world.spawn((A(2), B(2), TableStored("2"))).id();
1244        world.spawn((A(3), B(3), TableStored("3")));
1245
1246        let mut query = world.query::<(&B, &TableStored)>();
1247        let results = query
1248            .iter(&world)
1249            .map(|(a, b)| (a.0, b.0))
1250            .collect::<Vec<_>>();
1251        assert_eq!(results, vec![(1, "1"), (2, "2"), (3, "3"),]);
1252
1253        let removed_bundle = world.entity_mut(e2).take::<(B, TableStored)>().unwrap();
1254        assert_eq!(removed_bundle, (B(2), TableStored("2")));
1255
1256        let results = query
1257            .iter(&world)
1258            .map(|(a, b)| (a.0, b.0))
1259            .collect::<Vec<_>>();
1260        assert_eq!(results, vec![(1, "1"), (3, "3"),]);
1261
1262        let mut a_query = world.query::<&A>();
1263        let results = a_query.iter(&world).map(|a| a.0).collect::<Vec<_>>();
1264        assert_eq!(results, vec![1, 3, 2]);
1265
1266        let entity_ref = world.entity(e2);
1267        assert_eq!(
1268            entity_ref.get::<A>(),
1269            Some(&A(2)),
1270            "A is not in the removed bundle, so it should exist"
1271        );
1272        assert_eq!(
1273            entity_ref.get::<B>(),
1274            None,
1275            "B is in the removed bundle, so it should not exist"
1276        );
1277        assert_eq!(
1278            entity_ref.get::<TableStored>(),
1279            None,
1280            "TableStored is in the removed bundle, so it should not exist"
1281        );
1282    }
1283
1284    #[test]
1285    fn non_send_resource() {
1286        let mut world = World::default();
1287        world.insert_non_send_resource(123i32);
1288        world.insert_non_send_resource(456i64);
1289        assert_eq!(*world.non_send_resource::<i32>(), 123);
1290        assert_eq!(*world.non_send_resource_mut::<i64>(), 456);
1291    }
1292
1293    #[test]
1294    fn non_send_resource_points_to_distinct_data() {
1295        let mut world = World::default();
1296        world.insert_resource(A(123));
1297        world.insert_non_send_resource(A(456));
1298        assert_eq!(*world.resource::<A>(), A(123));
1299        assert_eq!(*world.non_send_resource::<A>(), A(456));
1300    }
1301
1302    #[test]
1303    #[should_panic]
1304    fn non_send_resource_panic() {
1305        let mut world = World::default();
1306        world.insert_non_send_resource(0i32);
1307        std::thread::spawn(move || {
1308            let _ = world.non_send_resource_mut::<i32>();
1309        })
1310        .join()
1311        .unwrap();
1312    }
1313
1314    #[test]
1315    fn exact_size_query() {
1316        let mut world = World::default();
1317        world.spawn((A(0), B(0)));
1318        world.spawn((A(0), B(0)));
1319        world.spawn((A(0), B(0), C));
1320        world.spawn(C);
1321
1322        let mut query = world.query::<(&A, &B)>();
1323        assert_eq!(query.iter(&world).len(), 3);
1324    }
1325
1326    #[test]
1327    #[should_panic]
1328    fn duplicate_components_panic() {
1329        let mut world = World::new();
1330        world.spawn((A(1), A(2)));
1331    }
1332
1333    #[test]
1334    #[should_panic]
1335    fn ref_and_mut_query_panic() {
1336        let mut world = World::new();
1337        world.query::<(&A, &mut A)>();
1338    }
1339
1340    #[test]
1341    #[should_panic]
1342    fn entity_ref_and_mut_query_panic() {
1343        let mut world = World::new();
1344        world.query::<(EntityRef, &mut A)>();
1345    }
1346
1347    #[test]
1348    #[should_panic]
1349    fn mut_and_ref_query_panic() {
1350        let mut world = World::new();
1351        world.query::<(&mut A, &A)>();
1352    }
1353
1354    #[test]
1355    #[should_panic]
1356    fn mut_and_entity_ref_query_panic() {
1357        let mut world = World::new();
1358        world.query::<(&mut A, EntityRef)>();
1359    }
1360
1361    #[test]
1362    #[should_panic]
1363    fn mut_and_mut_query_panic() {
1364        let mut world = World::new();
1365        world.query::<(&mut A, &mut A)>();
1366    }
1367
1368    #[test]
1369    #[should_panic]
1370    fn multiple_worlds_same_query_iter() {
1371        let mut world_a = World::new();
1372        let world_b = World::new();
1373        let mut query = world_a.query::<&A>();
1374        query.iter(&world_a);
1375        query.iter(&world_b);
1376    }
1377
1378    #[test]
1379    fn query_filters_dont_collide_with_fetches() {
1380        let mut world = World::new();
1381        world.query_filtered::<&mut A, Changed<A>>();
1382    }
1383
1384    #[test]
1385    fn filtered_query_access() {
1386        let mut world = World::new();
1387        let query = world.query_filtered::<&mut A, Changed<B>>();
1388
1389        let mut expected = FilteredAccess::<ComponentId>::default();
1390        let a_id = world.components.get_id(TypeId::of::<A>()).unwrap();
1391        let b_id = world.components.get_id(TypeId::of::<B>()).unwrap();
1392        expected.add_write(a_id);
1393        expected.add_read(b_id);
1394        assert!(
1395            query.component_access.eq(&expected),
1396            "ComponentId access from query fetch and query filter should be combined"
1397        );
1398    }
1399
1400    #[test]
1401    #[should_panic]
1402    fn multiple_worlds_same_query_get() {
1403        let mut world_a = World::new();
1404        let world_b = World::new();
1405        let mut query = world_a.query::<&A>();
1406        let _ = query.get(&world_a, Entity::from_raw(0));
1407        let _ = query.get(&world_b, Entity::from_raw(0));
1408    }
1409
1410    #[test]
1411    #[should_panic]
1412    fn multiple_worlds_same_query_for_each() {
1413        let mut world_a = World::new();
1414        let world_b = World::new();
1415        let mut query = world_a.query::<&A>();
1416        query.iter(&world_a).for_each(|_| {});
1417        query.iter(&world_b).for_each(|_| {});
1418    }
1419
1420    #[test]
1421    fn resource_scope() {
1422        let mut world = World::default();
1423        world.insert_resource(A(0));
1424        world.resource_scope(|world: &mut World, mut value: Mut<A>| {
1425            value.0 += 1;
1426            assert!(!world.contains_resource::<A>());
1427        });
1428        assert_eq!(world.resource::<A>().0, 1);
1429    }
1430
1431    #[test]
1432    #[should_panic(
1433        expected = "Attempted to access or drop non-send resource bevy_ecs::tests::NonSendA from thread"
1434    )]
1435    fn non_send_resource_drop_from_different_thread() {
1436        let mut world = World::default();
1437        world.insert_non_send_resource(NonSendA::default());
1438
1439        let thread = std::thread::spawn(move || {
1440            // Dropping the non-send resource on a different thread
1441            // Should result in a panic
1442            drop(world);
1443        });
1444
1445        if let Err(err) = thread.join() {
1446            std::panic::resume_unwind(err);
1447        }
1448    }
1449
1450    #[test]
1451    fn non_send_resource_drop_from_same_thread() {
1452        let mut world = World::default();
1453        world.insert_non_send_resource(NonSendA::default());
1454        drop(world);
1455    }
1456
1457    #[test]
1458    fn insert_overwrite_drop() {
1459        let (dropck1, dropped1) = DropCk::new_pair();
1460        let (dropck2, dropped2) = DropCk::new_pair();
1461        let mut world = World::default();
1462        world.spawn(dropck1).insert(dropck2);
1463        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1464        assert_eq!(dropped2.load(Ordering::Relaxed), 0);
1465        drop(world);
1466        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1467        assert_eq!(dropped2.load(Ordering::Relaxed), 1);
1468    }
1469
1470    #[test]
1471    fn insert_overwrite_drop_sparse() {
1472        let (dropck1, dropped1) = DropCk::new_pair();
1473        let (dropck2, dropped2) = DropCk::new_pair();
1474        let mut world = World::default();
1475
1476        world
1477            .spawn(DropCkSparse(dropck1))
1478            .insert(DropCkSparse(dropck2));
1479        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1480        assert_eq!(dropped2.load(Ordering::Relaxed), 0);
1481        drop(world);
1482        assert_eq!(dropped1.load(Ordering::Relaxed), 1);
1483        assert_eq!(dropped2.load(Ordering::Relaxed), 1);
1484    }
1485
1486    #[test]
1487    fn clear_entities() {
1488        let mut world = World::default();
1489
1490        world.insert_resource(A(0));
1491        world.spawn(A(1));
1492        world.spawn(SparseStored(1));
1493
1494        let mut q1 = world.query::<&A>();
1495        let mut q2 = world.query::<&SparseStored>();
1496
1497        assert_eq!(q1.iter(&world).len(), 1);
1498        assert_eq!(q2.iter(&world).len(), 1);
1499        assert_eq!(world.entities().len(), 2);
1500
1501        world.clear_entities();
1502
1503        assert_eq!(
1504            q1.iter(&world).len(),
1505            0,
1506            "world should not contain table components"
1507        );
1508        assert_eq!(
1509            q2.iter(&world).len(),
1510            0,
1511            "world should not contain sparse set components"
1512        );
1513        assert_eq!(
1514            world.entities().len(),
1515            0,
1516            "world should not have any entities"
1517        );
1518        assert_eq!(
1519            world.resource::<A>().0,
1520            0,
1521            "world should still contain resources"
1522        );
1523    }
1524
1525    #[test]
1526    fn test_is_archetypal_size_hints() {
1527        let mut world = World::default();
1528        macro_rules! query_min_size {
1529            ($query:ty, $filter:ty) => {
1530                world
1531                    .query_filtered::<$query, $filter>()
1532                    .iter(&world)
1533                    .size_hint()
1534                    .0
1535            };
1536        }
1537
1538        world.spawn((A(1), B(1), C));
1539        world.spawn((A(1), C));
1540        world.spawn((A(1), B(1)));
1541        world.spawn((B(1), C));
1542        world.spawn(A(1));
1543        world.spawn(C);
1544        assert_eq!(2, query_min_size![(), (With<A>, Without<B>)]);
1545        assert_eq!(3, query_min_size![&B, Or<(With<A>, With<C>)>]);
1546        assert_eq!(1, query_min_size![&B, (With<A>, With<C>)]);
1547        assert_eq!(1, query_min_size![(&A, &B), With<C>]);
1548        assert_eq!(4, query_min_size![&A, ()], "Simple Archetypal");
1549        assert_eq!(4, query_min_size![Ref<A>, ()]);
1550        // All the following should set minimum size to 0, as it's impossible to predict
1551        // how many entities the filters will trim.
1552        assert_eq!(0, query_min_size![(), Added<A>], "Simple Added");
1553        assert_eq!(0, query_min_size![(), Changed<A>], "Simple Changed");
1554        assert_eq!(0, query_min_size![(&A, &B), Changed<A>]);
1555        assert_eq!(0, query_min_size![&A, (Changed<A>, With<B>)]);
1556        assert_eq!(0, query_min_size![(&A, &B), Or<(Changed<A>, Changed<B>)>]);
1557    }
1558
1559    #[test]
1560    fn reserve_entities_across_worlds() {
1561        let mut world_a = World::default();
1562        let mut world_b = World::default();
1563
1564        let e1 = world_a.spawn(A(1)).id();
1565        let e2 = world_a.spawn(A(2)).id();
1566        let e3 = world_a.entities().reserve_entity();
1567        world_a.flush_entities();
1568
1569        let world_a_max_entities = world_a.entities().len();
1570        world_b.entities.reserve_entities(world_a_max_entities);
1571        world_b.entities.flush_as_invalid();
1572
1573        let e4 = world_b.spawn(A(4)).id();
1574        assert_eq!(
1575            e4,
1576            Entity::from_raw(3),
1577            "new entity is created immediately after world_a's max entity"
1578        );
1579        assert!(world_b.get::<A>(e1).is_none());
1580        assert!(world_b.get_entity(e1).is_none());
1581
1582        assert!(world_b.get::<A>(e2).is_none());
1583        assert!(world_b.get_entity(e2).is_none());
1584
1585        assert!(world_b.get::<A>(e3).is_none());
1586        assert!(world_b.get_entity(e3).is_none());
1587
1588        world_b.get_or_spawn(e1).unwrap().insert(B(1));
1589        assert_eq!(
1590            world_b.get::<B>(e1),
1591            Some(&B(1)),
1592            "spawning into 'world_a' entities works"
1593        );
1594
1595        world_b.get_or_spawn(e4).unwrap().insert(B(4));
1596        assert_eq!(
1597            world_b.get::<B>(e4),
1598            Some(&B(4)),
1599            "spawning into existing `world_b` entities works"
1600        );
1601        assert_eq!(
1602            world_b.get::<A>(e4),
1603            Some(&A(4)),
1604            "spawning into existing `world_b` entities works"
1605        );
1606
1607        let e4_mismatched_generation =
1608            Entity::from_raw_and_generation(3, NonZeroU32::new(2).unwrap());
1609        assert!(
1610            world_b.get_or_spawn(e4_mismatched_generation).is_none(),
1611            "attempting to spawn on top of an entity with a mismatched entity generation fails"
1612        );
1613        assert_eq!(
1614            world_b.get::<B>(e4),
1615            Some(&B(4)),
1616            "failed mismatched spawn doesn't change existing entity"
1617        );
1618        assert_eq!(
1619            world_b.get::<A>(e4),
1620            Some(&A(4)),
1621            "failed mismatched spawn doesn't change existing entity"
1622        );
1623
1624        let high_non_existent_entity = Entity::from_raw(6);
1625        world_b
1626            .get_or_spawn(high_non_existent_entity)
1627            .unwrap()
1628            .insert(B(10));
1629        assert_eq!(
1630            world_b.get::<B>(high_non_existent_entity),
1631            Some(&B(10)),
1632            "inserting into newly allocated high / non-continuous entity id works"
1633        );
1634
1635        let high_non_existent_but_reserved_entity = Entity::from_raw(5);
1636        assert!(
1637            world_b.get_entity(high_non_existent_but_reserved_entity).is_none(),
1638            "entities between high-newly allocated entity and continuous block of existing entities don't exist"
1639        );
1640
1641        let reserved_entities = vec![
1642            world_b.entities().reserve_entity(),
1643            world_b.entities().reserve_entity(),
1644            world_b.entities().reserve_entity(),
1645            world_b.entities().reserve_entity(),
1646        ];
1647
1648        assert_eq!(
1649            reserved_entities,
1650            vec![
1651                Entity::from_raw(5),
1652                Entity::from_raw(4),
1653                Entity::from_raw(7),
1654                Entity::from_raw(8),
1655            ],
1656            "space between original entities and high entities is used for new entity ids"
1657        );
1658    }
1659
1660    #[test]
1661    fn insert_or_spawn_batch() {
1662        let mut world = World::default();
1663        let e0 = world.spawn(A(0)).id();
1664        let e1 = Entity::from_raw(1);
1665
1666        let values = vec![(e0, (B(0), C)), (e1, (B(1), C))];
1667
1668        world.insert_or_spawn_batch(values).unwrap();
1669
1670        assert_eq!(
1671            world.get::<A>(e0),
1672            Some(&A(0)),
1673            "existing component was preserved"
1674        );
1675        assert_eq!(
1676            world.get::<B>(e0),
1677            Some(&B(0)),
1678            "pre-existing entity received correct B component"
1679        );
1680        assert_eq!(
1681            world.get::<B>(e1),
1682            Some(&B(1)),
1683            "new entity was spawned and received correct B component"
1684        );
1685        assert_eq!(
1686            world.get::<C>(e0),
1687            Some(&C),
1688            "pre-existing entity received C component"
1689        );
1690        assert_eq!(
1691            world.get::<C>(e1),
1692            Some(&C),
1693            "new entity was spawned and received C component"
1694        );
1695    }
1696
1697    #[test]
1698    fn insert_or_spawn_batch_invalid() {
1699        let mut world = World::default();
1700        let e0 = world.spawn(A(0)).id();
1701        let e1 = Entity::from_raw(1);
1702        let e2 = world.spawn_empty().id();
1703        let invalid_e2 = Entity::from_raw_and_generation(e2.index(), NonZeroU32::new(2).unwrap());
1704
1705        let values = vec![(e0, (B(0), C)), (e1, (B(1), C)), (invalid_e2, (B(2), C))];
1706
1707        let result = world.insert_or_spawn_batch(values);
1708
1709        assert_eq!(
1710            result,
1711            Err(vec![invalid_e2]),
1712            "e2 failed to be spawned or inserted into"
1713        );
1714
1715        assert_eq!(
1716            world.get::<A>(e0),
1717            Some(&A(0)),
1718            "existing component was preserved"
1719        );
1720        assert_eq!(
1721            world.get::<B>(e0),
1722            Some(&B(0)),
1723            "pre-existing entity received correct B component"
1724        );
1725        assert_eq!(
1726            world.get::<B>(e1),
1727            Some(&B(1)),
1728            "new entity was spawned and received correct B component"
1729        );
1730        assert_eq!(
1731            world.get::<C>(e0),
1732            Some(&C),
1733            "pre-existing entity received C component"
1734        );
1735        assert_eq!(
1736            world.get::<C>(e1),
1737            Some(&C),
1738            "new entity was spawned and received C component"
1739        );
1740    }
1741
1742    // These fields are never read so we get a dead code lint here.
1743    #[allow(dead_code)]
1744    #[derive(Component)]
1745    struct ComponentA(u32);
1746
1747    #[allow(dead_code)]
1748    #[derive(Component)]
1749    struct ComponentB(u32);
1750
1751    #[derive(Bundle)]
1752    struct Simple(ComponentA);
1753
1754    #[derive(Bundle)]
1755    struct Tuple(Simple, ComponentB);
1756
1757    #[derive(Bundle)]
1758    struct Record {
1759        field0: Simple,
1760        field1: ComponentB,
1761    }
1762}