Skip to main content

oxide_ecs/
lib.rs

1#![allow(clippy::type_complexity)]
2
3extern crate self as oxide_ecs;
4
5pub use oxide_ecs_derive::{Component, Resource, ScheduleLabel};
6
7pub mod component {
8    pub trait Component: 'static {}
9}
10
11pub mod resource {
12    pub trait Resource: 'static {}
13}
14
15pub mod entity {
16    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
17    pub struct Entity {
18        pub(crate) index: u32,
19        pub(crate) generation: u32,
20    }
21
22    impl Entity {
23        pub fn index(self) -> u32 {
24            self.index
25        }
26
27        pub fn generation(self) -> u32 {
28            self.generation
29        }
30    }
31}
32
33pub mod query {
34    use std::marker::PhantomData;
35
36    pub struct With<T>(pub(crate) PhantomData<T>);
37    pub struct Without<T>(pub(crate) PhantomData<T>);
38
39    impl<T> Default for With<T> {
40        fn default() -> Self {
41            Self(PhantomData)
42        }
43    }
44
45    impl<T> Default for Without<T> {
46        fn default() -> Self {
47            Self(PhantomData)
48        }
49    }
50}
51
52pub mod schedule {
53    use super::world::World;
54
55    pub trait ScheduleLabel: 'static {}
56
57    pub type SystemFn = fn(&mut World);
58
59    #[derive(Default)]
60    pub struct Schedule {
61        systems: Vec<SystemFn>,
62    }
63
64    impl Schedule {
65        pub fn new() -> Self {
66            Self::default()
67        }
68
69        pub fn add_system(&mut self, system: SystemFn) {
70            self.systems.push(system);
71        }
72
73        pub fn run(&mut self, world: &mut World) {
74            for system in &self.systems {
75                system(world);
76            }
77        }
78    }
79}
80
81pub mod system {
82    use std::marker::PhantomData;
83    use std::ops::{Deref, DerefMut};
84
85    use crate::component::Component;
86    use crate::entity::Entity;
87    use crate::resource::Resource;
88    use crate::world::{Bundle, World};
89
90    pub trait SystemParam: Sized {
91        /// Fetches this parameter from raw world and command-queue pointers.
92        ///
93        /// # Safety
94        /// `world` and `commands` must be valid pointers for the duration of the call and must
95        /// originate from the currently executing schedule stage.
96        unsafe fn fetch(world: *mut World, commands: *mut CommandQueue) -> Self;
97    }
98
99    trait DeferredCommand {
100        fn apply(self: Box<Self>, world: &mut World);
101    }
102
103    impl<F> DeferredCommand for F
104    where
105        F: FnOnce(&mut World) + 'static,
106    {
107        fn apply(self: Box<Self>, world: &mut World) {
108            (*self)(world);
109        }
110    }
111
112    #[derive(Default)]
113    pub struct CommandQueue {
114        commands: Vec<Box<dyn DeferredCommand>>,
115    }
116
117    impl CommandQueue {
118        pub fn new() -> Self {
119            Self::default()
120        }
121
122        pub fn push<F>(&mut self, command: F)
123        where
124            F: FnOnce(&mut World) + 'static,
125        {
126            self.commands.push(Box::new(command));
127        }
128
129        pub fn is_empty(&self) -> bool {
130            self.commands.is_empty()
131        }
132
133        pub fn apply(&mut self, world: &mut World) {
134            let commands = std::mem::take(&mut self.commands);
135            for command in commands {
136                command.apply(world);
137            }
138        }
139    }
140
141    pub struct Commands {
142        queue: *mut CommandQueue,
143    }
144
145    impl Commands {
146        pub fn new(queue: *mut CommandQueue) -> Self {
147            Self { queue }
148        }
149
150        pub fn spawn<B>(&mut self, bundle: B)
151        where
152            B: Bundle + 'static,
153        {
154            unsafe { &mut *self.queue }.push(move |world| {
155                let _ = world.spawn(bundle);
156            });
157        }
158
159        pub fn entity(&mut self, entity: Entity) -> EntityCommands {
160            EntityCommands {
161                entity,
162                queue: self.queue,
163            }
164        }
165
166        pub fn despawn(&mut self, entity: Entity) {
167            unsafe { &mut *self.queue }.push(move |world| {
168                let _ = world.despawn(entity);
169            });
170        }
171    }
172
173    pub struct EntityCommands {
174        entity: Entity,
175        queue: *mut CommandQueue,
176    }
177
178    impl EntityCommands {
179        pub fn insert<B>(&mut self, bundle: B) -> &mut Self
180        where
181            B: Bundle + 'static,
182        {
183            let entity = self.entity;
184            unsafe { &mut *self.queue }.push(move |world| {
185                if world.contains(entity) {
186                    world.entity_mut(entity).insert(bundle);
187                }
188            });
189            self
190        }
191
192        pub fn remove<T>(&mut self) -> &mut Self
193        where
194            T: Component,
195        {
196            let entity = self.entity;
197            unsafe { &mut *self.queue }.push(move |world| {
198                if world.contains(entity) {
199                    let _ = world.remove::<T>(entity);
200                }
201            });
202            self
203        }
204
205        pub fn despawn(&mut self) -> &mut Self {
206            let entity = self.entity;
207            unsafe { &mut *self.queue }.push(move |world| {
208                let _ = world.despawn(entity);
209            });
210            self
211        }
212    }
213
214    pub struct Res<T>(*const T, PhantomData<T>);
215
216    impl<T> Deref for Res<T> {
217        type Target = T;
218
219        fn deref(&self) -> &Self::Target {
220            unsafe { &*self.0 }
221        }
222    }
223
224    pub struct ResMut<T>(*mut T, PhantomData<T>);
225
226    impl<T> Deref for ResMut<T> {
227        type Target = T;
228
229        fn deref(&self) -> &Self::Target {
230            unsafe { &*self.0 }
231        }
232    }
233
234    impl<T> DerefMut for ResMut<T> {
235        fn deref_mut(&mut self) -> &mut Self::Target {
236            unsafe { &mut *self.0 }
237        }
238    }
239
240    pub struct Query<Q> {
241        world: *mut World,
242        marker: PhantomData<Q>,
243    }
244
245    impl<Q> Query<Q> {
246        fn new(world: *mut World) -> Self {
247            Self {
248                world,
249                marker: PhantomData,
250            }
251        }
252    }
253
254    impl<T: Component> Query<&T> {
255        pub fn iter(&mut self) -> impl Iterator<Item = &T> {
256            let world = unsafe { &mut *self.world };
257            let mut query = world.query::<&T>();
258            query.iter(&*world).collect::<Vec<_>>().into_iter()
259        }
260    }
261
262    impl<T: Component> Query<&mut T> {
263        pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
264            let world = unsafe { &mut *self.world };
265            let mut query = world.query::<&mut T>();
266            query.iter_mut(world).collect::<Vec<_>>().into_iter()
267        }
268    }
269
270    impl<A: Component, B: Component> Query<(&A, &B)> {
271        pub fn iter(&mut self) -> impl Iterator<Item = (&A, &B)> {
272            let world = unsafe { &mut *self.world };
273            let mut query = world.query::<(&A, &B)>();
274            query.iter(&*world).collect::<Vec<_>>().into_iter()
275        }
276    }
277
278    impl<A: Component, B: Component> Query<(&mut A, &mut B)> {
279        pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut A, &mut B)> {
280            let world = unsafe { &mut *self.world };
281            let mut query = world.query::<(&mut A, &mut B)>();
282            query.iter_mut(world).collect::<Vec<_>>().into_iter()
283        }
284    }
285
286    impl<A: Component, B: Component> Query<(&mut A, &B)> {
287        pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut A, &B)> {
288            let world = unsafe { &mut *self.world };
289            let mut query = world.query::<(&mut A, &B)>();
290            query.iter_mut(world).collect::<Vec<_>>().into_iter()
291        }
292    }
293
294    impl<A: Component, B: Component> Query<(&A, &mut B)> {
295        pub fn iter_mut(&mut self) -> impl Iterator<Item = (&A, &mut B)> {
296            let world = unsafe { &mut *self.world };
297            let mut query = world.query::<(&A, &mut B)>();
298            query.iter_mut(world).collect::<Vec<_>>().into_iter()
299        }
300    }
301
302    impl<T: 'static> SystemParam for Res<T> {
303        unsafe fn fetch(world: *mut World, _commands: *mut CommandQueue) -> Self {
304            let world = unsafe { &mut *world };
305            let value = world.resource::<T>() as *const T;
306            Res(value, PhantomData)
307        }
308    }
309
310    impl<T: 'static> SystemParam for ResMut<T> {
311        unsafe fn fetch(world: *mut World, _commands: *mut CommandQueue) -> Self {
312            let world = unsafe { &mut *world };
313            let value = world.resource_mut::<T>() as *mut T;
314            ResMut(value, PhantomData)
315        }
316    }
317
318    impl<Q: 'static> SystemParam for Query<Q> {
319        unsafe fn fetch(world: *mut World, _commands: *mut CommandQueue) -> Self {
320            Query::new(world)
321        }
322    }
323
324    impl SystemParam for Commands {
325        unsafe fn fetch(_world: *mut World, commands: *mut CommandQueue) -> Self {
326            Commands::new(commands)
327        }
328    }
329
330    #[derive(Clone, Debug)]
331    pub struct State<T> {
332        current: T,
333        next: Option<T>,
334    }
335
336    impl<T> State<T> {
337        pub fn new(initial: T) -> Self {
338            Self {
339                current: initial,
340                next: None,
341            }
342        }
343
344        pub fn current(&self) -> &T {
345            &self.current
346        }
347
348        pub fn next(&self) -> Option<&T> {
349            self.next.as_ref()
350        }
351
352        pub fn set(&mut self, value: T) {
353            self.current = value;
354            self.next = None;
355        }
356
357        pub fn set_next(&mut self, value: T) {
358            self.next = Some(value);
359        }
360
361        pub fn apply_transition(&mut self) -> bool {
362            if let Some(next) = self.next.take() {
363                self.current = next;
364                true
365            } else {
366                false
367            }
368        }
369    }
370
371    impl<T: 'static> Resource for State<T> {}
372
373    pub struct System {
374        run: Box<dyn FnMut(&mut World, &mut CommandQueue)>,
375        run_condition: Option<Box<dyn FnMut(&World) -> bool>>,
376    }
377
378    impl System {
379        pub fn new<F>(run: F) -> Self
380        where
381            F: FnMut(&mut World, &mut CommandQueue) + 'static,
382        {
383            Self {
384                run: Box::new(run),
385                run_condition: None,
386            }
387        }
388
389        pub fn with_condition<F>(mut self, condition: F) -> Self
390        where
391            F: FnMut(&World) -> bool + 'static,
392        {
393            self.run_condition = Some(Box::new(condition));
394            self
395        }
396
397        pub fn run(&mut self, world: &mut World, commands: &mut CommandQueue) {
398            if let Some(condition) = self.run_condition.as_mut() {
399                if !(condition)(&*world) {
400                    return;
401                }
402            }
403
404            (self.run)(world, commands);
405        }
406    }
407
408    pub trait IntoSystem<Marker = ()> {
409        fn into_system(self) -> System;
410    }
411
412    impl IntoSystem for System {
413        fn into_system(self) -> System {
414            self
415        }
416    }
417
418    impl<F> IntoSystem<fn(&mut World)> for F
419    where
420        F: FnMut(&mut World) + 'static,
421    {
422        fn into_system(mut self) -> System {
423            System::new(move |world, _commands| self(world))
424        }
425    }
426
427    macro_rules! impl_into_system {
428        ($($param:ident),+) => {
429            impl<Func, $($param),+> IntoSystem<fn($($param),+)> for Func
430            where
431                Func: FnMut($($param),+) + 'static,
432                $($param: SystemParam + 'static),+
433            {
434                #[allow(non_snake_case)]
435                fn into_system(mut self) -> System {
436                    System::new(move |world, commands| {
437                        let world_ptr = world as *mut World;
438                        let commands_ptr = commands as *mut CommandQueue;
439                        unsafe {
440                            $(let $param = <$param as SystemParam>::fetch(world_ptr, commands_ptr);)+
441                            self($($param),+);
442                        }
443                    })
444                }
445            }
446        };
447    }
448
449    impl_into_system!(A);
450    impl_into_system!(A, B);
451    impl_into_system!(A, B, C);
452    impl_into_system!(A, B, C, D);
453    impl_into_system!(A, B, C, D, E);
454
455    pub trait IntoSystemExt<Marker>: IntoSystem<Marker> + Sized {
456        fn run_if<C>(self, condition: C) -> System
457        where
458            C: FnMut(&World) -> bool + 'static,
459        {
460            self.into_system().with_condition(condition)
461        }
462    }
463
464    impl<T, Marker> IntoSystemExt<Marker> for T where T: IntoSystem<Marker> + Sized {}
465
466    pub fn in_state<T>(target: T) -> impl FnMut(&World) -> bool
467    where
468        T: Clone + PartialEq + 'static,
469    {
470        move |world: &World| world.resource::<State<T>>().current().eq(&target)
471    }
472}
473
474pub mod world {
475    use super::component::Component;
476    use super::entity::Entity;
477    use super::query::{With, Without};
478    use std::any::{Any, TypeId};
479    use std::collections::HashMap;
480    use std::marker::PhantomData;
481
482    trait StorageDyn: Any {
483        fn remove_entity(&mut self, entity: Entity);
484        fn as_any(&self) -> &dyn Any;
485        fn as_any_mut(&mut self) -> &mut dyn Any;
486    }
487
488    struct Storage<T: Component> {
489        sparse: Vec<Option<usize>>,
490        dense_entities: Vec<Entity>,
491        dense_data: Vec<T>,
492    }
493
494    impl<T: Component> Default for Storage<T> {
495        fn default() -> Self {
496            Self {
497                sparse: Vec::new(),
498                dense_entities: Vec::new(),
499                dense_data: Vec::new(),
500            }
501        }
502    }
503
504    impl<T: Component> Storage<T> {
505        fn ensure_sparse_capacity(&mut self, entity: Entity) {
506            let index = entity.index as usize;
507            if self.sparse.len() <= index {
508                self.sparse.resize(index + 1, None);
509            }
510        }
511
512        fn insert(&mut self, entity: Entity, component: T) {
513            self.ensure_sparse_capacity(entity);
514            let index = entity.index as usize;
515
516            if let Some(dense_index) = self.sparse[index] {
517                if self.dense_entities.get(dense_index).copied() == Some(entity) {
518                    self.dense_data[dense_index] = component;
519                    return;
520                }
521            }
522
523            let dense_index = self.dense_data.len();
524            self.dense_entities.push(entity);
525            self.dense_data.push(component);
526            self.sparse[index] = Some(dense_index);
527        }
528
529        fn get(&self, entity: Entity) -> Option<&T> {
530            let dense_index = self.sparse.get(entity.index as usize).copied().flatten()?;
531            if self.dense_entities.get(dense_index).copied() == Some(entity) {
532                self.dense_data.get(dense_index)
533            } else {
534                None
535            }
536        }
537
538        fn get_mut(&mut self, entity: Entity) -> Option<&mut T> {
539            let dense_index = self.sparse.get(entity.index as usize).copied().flatten()?;
540            if self.dense_entities.get(dense_index).copied() == Some(entity) {
541                self.dense_data.get_mut(dense_index)
542            } else {
543                None
544            }
545        }
546
547        fn get_mut_ptr(&mut self, entity: Entity) -> Option<*mut T> {
548            self.get_mut(entity).map(|value| value as *mut T)
549        }
550
551        fn remove(&mut self, entity: Entity) -> Option<T> {
552            let index = entity.index as usize;
553            let dense_index = self.sparse.get(index).copied().flatten()?;
554
555            if self.dense_entities.get(dense_index).copied() != Some(entity) {
556                return None;
557            }
558
559            self.sparse[index] = None;
560
561            let removed_entity = self.dense_entities.swap_remove(dense_index);
562            let removed_component = self.dense_data.swap_remove(dense_index);
563
564            debug_assert_eq!(removed_entity, entity);
565
566            if dense_index < self.dense_entities.len() {
567                let moved_entity = self.dense_entities[dense_index];
568                self.sparse[moved_entity.index as usize] = Some(dense_index);
569            }
570
571            Some(removed_component)
572        }
573
574        fn entities(&self) -> &[Entity] {
575            &self.dense_entities
576        }
577
578        fn values(&self) -> impl Iterator<Item = &T> {
579            self.dense_data.iter()
580        }
581
582        fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
583            self.dense_data.iter_mut()
584        }
585
586        fn contains_entity(&self, entity: Entity) -> bool {
587            self.get(entity).is_some()
588        }
589    }
590
591    impl<T: Component> StorageDyn for Storage<T> {
592        fn remove_entity(&mut self, entity: Entity) {
593            self.remove(entity);
594        }
595
596        fn as_any(&self) -> &dyn Any {
597            self
598        }
599
600        fn as_any_mut(&mut self) -> &mut dyn Any {
601            self
602        }
603    }
604
605    pub trait Bundle {
606        fn insert_into(self, world: &mut World, entity: Entity);
607    }
608
609    impl<C: Component> Bundle for C {
610        fn insert_into(self, world: &mut World, entity: Entity) {
611            world.insert_component(entity, self);
612        }
613    }
614
615    macro_rules! impl_bundle_tuple {
616        ($($name:ident),+) => {
617            impl<$($name: Component),+> Bundle for ($($name,)+) {
618                #[allow(non_snake_case)]
619                fn insert_into(self, world: &mut World, entity: Entity) {
620                    let ($($name,)+) = self;
621                    $(world.insert_component(entity, $name);)+
622                }
623            }
624        };
625    }
626
627    impl_bundle_tuple!(A, B);
628    impl_bundle_tuple!(A, B, C);
629    impl_bundle_tuple!(A, B, C, D);
630    impl_bundle_tuple!(A, B, C, D, E);
631
632    pub struct World {
633        next_index: u32,
634        generations: Vec<u32>,
635        free_indices: Vec<u32>,
636        storages: HashMap<TypeId, Box<dyn StorageDyn>>,
637        resources: HashMap<TypeId, Box<dyn Any>>,
638        non_send_resources: HashMap<TypeId, Box<dyn Any>>,
639    }
640
641    impl Default for World {
642        fn default() -> Self {
643            Self::new()
644        }
645    }
646
647    impl World {
648        pub fn new() -> Self {
649            Self {
650                next_index: 0,
651                generations: Vec::new(),
652                free_indices: Vec::new(),
653                storages: HashMap::new(),
654                resources: HashMap::new(),
655                non_send_resources: HashMap::new(),
656            }
657        }
658
659        pub fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityMut<'_> {
660            let entity = self.alloc_entity();
661            bundle.insert_into(self, entity);
662            EntityMut {
663                world: self,
664                entity,
665            }
666        }
667
668        pub fn entity_mut(&mut self, entity: Entity) -> EntityMut<'_> {
669            assert!(self.contains(entity), "entity {:?} is not alive", entity);
670            EntityMut {
671                world: self,
672                entity,
673            }
674        }
675
676        pub fn contains(&self, entity: Entity) -> bool {
677            self.generations
678                .get(entity.index as usize)
679                .map(|g| *g == entity.generation)
680                .unwrap_or(false)
681        }
682
683        pub fn despawn(&mut self, entity: Entity) -> bool {
684            if !self.contains(entity) {
685                return false;
686            }
687            for storage in self.storages.values_mut() {
688                storage.remove_entity(entity);
689            }
690            if let Some(generation) = self.generations.get_mut(entity.index as usize) {
691                *generation = generation.saturating_add(1);
692            }
693            self.free_indices.push(entity.index);
694            true
695        }
696
697        pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {
698            if !self.contains(entity) {
699                return None;
700            }
701            self.storage::<T>()?.get(entity)
702        }
703
704        pub fn get_mut<T: Component>(&mut self, entity: Entity) -> Option<&mut T> {
705            if !self.contains(entity) {
706                return None;
707            }
708            self.storage_mut::<T>()?.get_mut(entity)
709        }
710
711        pub fn remove<T: Component>(&mut self, entity: Entity) -> Option<T> {
712            if !self.contains(entity) {
713                return None;
714            }
715            self.storage_mut::<T>()?.remove(entity)
716        }
717
718        pub fn insert_resource<T: 'static>(&mut self, value: T) {
719            self.resources.insert(TypeId::of::<T>(), Box::new(value));
720        }
721
722        pub fn resource<T: 'static>(&self) -> &T {
723            self.resources
724                .get(&TypeId::of::<T>())
725                .and_then(|boxed| boxed.downcast_ref::<T>())
726                .expect("resource not found")
727        }
728
729        pub fn resource_mut<T: 'static>(&mut self) -> &mut T {
730            self.resources
731                .get_mut(&TypeId::of::<T>())
732                .and_then(|boxed| boxed.downcast_mut::<T>())
733                .expect("resource not found")
734        }
735
736        pub fn init_resource<T: Default + 'static>(&mut self) {
737            if !self.resources.contains_key(&TypeId::of::<T>()) {
738                self.insert_resource(T::default());
739            }
740        }
741
742        pub fn contains_resource<T: 'static>(&self) -> bool {
743            self.resources.contains_key(&TypeId::of::<T>())
744        }
745
746        pub fn insert_non_send_resource<T: 'static>(&mut self, value: T) {
747            self.non_send_resources
748                .insert(TypeId::of::<T>(), Box::new(value));
749        }
750
751        pub fn get_non_send_resource<T: 'static>(&self) -> Option<&T> {
752            self.non_send_resources
753                .get(&TypeId::of::<T>())
754                .and_then(|boxed| boxed.downcast_ref::<T>())
755        }
756
757        pub fn get_non_send_resource_mut<T: 'static>(&mut self) -> Option<&mut T> {
758            self.non_send_resources
759                .get_mut(&TypeId::of::<T>())
760                .and_then(|boxed| boxed.downcast_mut::<T>())
761        }
762
763        pub fn query<Q>(&mut self) -> QueryState<Q> {
764            QueryState {
765                marker: PhantomData,
766            }
767        }
768
769        pub fn query_filtered<Q, F>(&mut self) -> FilteredQueryState<Q, F> {
770            FilteredQueryState {
771                marker: PhantomData,
772            }
773        }
774
775        fn alloc_entity(&mut self) -> Entity {
776            if let Some(index) = self.free_indices.pop() {
777                let generation = self.generations[index as usize];
778                return Entity { index, generation };
779            }
780
781            let index = self.next_index;
782            self.next_index += 1;
783            self.generations.push(0);
784            Entity {
785                index,
786                generation: 0,
787            }
788        }
789
790        fn insert_component<T: Component>(&mut self, entity: Entity, component: T) {
791            assert!(self.contains(entity), "entity {:?} is not alive", entity);
792            self.ensure_storage::<T>().insert(entity, component);
793        }
794
795        fn ensure_storage<T: Component>(&mut self) -> &mut Storage<T> {
796            let type_id = TypeId::of::<T>();
797            self.storages
798                .entry(type_id)
799                .or_insert_with(|| Box::new(Storage::<T>::default()));
800            self.storage_mut::<T>().expect("storage created")
801        }
802
803        fn storage<T: Component>(&self) -> Option<&Storage<T>> {
804            self.storages
805                .get(&TypeId::of::<T>())
806                .and_then(|storage| storage.as_any().downcast_ref::<Storage<T>>())
807        }
808
809        fn storage_mut<T: Component>(&mut self) -> Option<&mut Storage<T>> {
810            self.storages
811                .get_mut(&TypeId::of::<T>())
812                .and_then(|storage| storage.as_any_mut().downcast_mut::<Storage<T>>())
813        }
814    }
815
816    pub struct EntityMut<'w> {
817        world: &'w mut World,
818        entity: Entity,
819    }
820
821    impl<'w> EntityMut<'w> {
822        pub fn id(&self) -> Entity {
823            self.entity
824        }
825
826        pub fn insert<B: Bundle>(&mut self, bundle: B) -> &mut Self {
827            bundle.insert_into(self.world, self.entity);
828            self
829        }
830
831        pub fn get<T: Component>(&self) -> Option<&T> {
832            self.world.get::<T>(self.entity)
833        }
834
835        pub fn get_mut<T: Component>(&mut self) -> Option<&mut T> {
836            self.world.get_mut::<T>(self.entity)
837        }
838
839        pub fn remove<T: Component>(&mut self) -> Option<T> {
840            self.world.remove::<T>(self.entity)
841        }
842    }
843
844    pub struct QueryState<Q> {
845        marker: PhantomData<Q>,
846    }
847
848    impl<T: Component> QueryState<&T> {
849        pub fn iter<'w>(&mut self, world: &'w World) -> impl Iterator<Item = &'w T> {
850            world
851                .storage::<T>()
852                .map(|storage| storage.values())
853                .into_iter()
854                .flatten()
855        }
856    }
857
858    impl<T: Component> QueryState<&mut T> {
859        pub fn iter_mut<'w>(&mut self, world: &'w mut World) -> impl Iterator<Item = &'w mut T> {
860            world
861                .storage_mut::<T>()
862                .map(|storage| storage.values_mut())
863                .into_iter()
864                .flatten()
865        }
866    }
867
868    pub struct TupleIter2<'w, A: Component, B: Component> {
869        entities: Vec<Entity>,
870        index: usize,
871        a: Option<&'w Storage<A>>,
872        b: Option<&'w Storage<B>>,
873    }
874
875    impl<'w, A: Component, B: Component> Iterator for TupleIter2<'w, A, B> {
876        type Item = (&'w A, &'w B);
877
878        fn next(&mut self) -> Option<Self::Item> {
879            let (Some(a_storage), Some(b_storage)) = (self.a, self.b) else {
880                return None;
881            };
882
883            while self.index < self.entities.len() {
884                let entity = self.entities[self.index];
885                self.index += 1;
886                if let (Some(a), Some(b)) = (a_storage.get(entity), b_storage.get(entity)) {
887                    return Some((a, b));
888                }
889            }
890            None
891        }
892    }
893
894    pub struct TupleIterMut2<'w, A: Component, B: Component> {
895        entities: Vec<Entity>,
896        index: usize,
897        a: *mut Storage<A>,
898        b: *mut Storage<B>,
899        marker: PhantomData<&'w mut (A, B)>,
900    }
901
902    impl<'w, A: Component, B: Component> Iterator for TupleIterMut2<'w, A, B> {
903        type Item = (&'w mut A, &'w mut B);
904
905        fn next(&mut self) -> Option<Self::Item> {
906            if self.a.is_null() || self.b.is_null() {
907                return None;
908            }
909
910            while self.index < self.entities.len() {
911                let entity = self.entities[self.index];
912                self.index += 1;
913                unsafe {
914                    let a_storage = &mut *self.a;
915                    let b_storage = &mut *self.b;
916                    let a_ptr = match a_storage.get_mut_ptr(entity) {
917                        Some(value) => value,
918                        None => continue,
919                    };
920                    let b_ptr = match b_storage.get_mut_ptr(entity) {
921                        Some(value) => value,
922                        None => continue,
923                    };
924                    return Some((&mut *a_ptr, &mut *b_ptr));
925                }
926            }
927            None
928        }
929    }
930
931    impl<A: Component, B: Component> QueryState<(&A, &B)> {
932        pub fn iter<'w>(&mut self, world: &'w World) -> TupleIter2<'w, A, B> {
933            let a_storage = world.storage::<A>();
934            let b_storage = world.storage::<B>();
935
936            let entities = a_storage
937                .map(|storage| storage.entities().to_vec())
938                .unwrap_or_default();
939
940            TupleIter2 {
941                entities,
942                index: 0,
943                a: a_storage,
944                b: b_storage,
945            }
946        }
947    }
948
949    impl<A: Component, B: Component> QueryState<(&mut A, &mut B)> {
950        pub fn iter_mut<'w>(&mut self, world: &'w mut World) -> TupleIterMut2<'w, A, B> {
951            assert_ne!(
952                TypeId::of::<A>(),
953                TypeId::of::<B>(),
954                "duplicate mutable query type"
955            );
956
957            let a_type = TypeId::of::<A>();
958            let b_type = TypeId::of::<B>();
959
960            let a_storage = {
961                let Some(a_dyn) = world.storages.get_mut(&a_type) else {
962                    return TupleIterMut2 {
963                        entities: Vec::new(),
964                        index: 0,
965                        a: std::ptr::null_mut(),
966                        b: std::ptr::null_mut(),
967                        marker: PhantomData,
968                    };
969                };
970
971                a_dyn
972                    .as_any_mut()
973                    .downcast_mut::<Storage<A>>()
974                    .expect("storage type mismatch") as *mut Storage<A>
975            };
976
977            let b_storage = {
978                let Some(b_dyn) = world.storages.get_mut(&b_type) else {
979                    return TupleIterMut2 {
980                        entities: Vec::new(),
981                        index: 0,
982                        a: std::ptr::null_mut(),
983                        b: std::ptr::null_mut(),
984                        marker: PhantomData,
985                    };
986                };
987
988                b_dyn
989                    .as_any_mut()
990                    .downcast_mut::<Storage<B>>()
991                    .expect("storage type mismatch") as *mut Storage<B>
992            };
993
994            if a_storage.is_null() || b_storage.is_null() {
995                return TupleIterMut2 {
996                    entities: Vec::new(),
997                    index: 0,
998                    a: std::ptr::null_mut(),
999                    b: std::ptr::null_mut(),
1000                    marker: PhantomData,
1001                };
1002            }
1003
1004            let entities = unsafe { (&*a_storage).entities().to_vec() };
1005
1006            TupleIterMut2 {
1007                entities,
1008                index: 0,
1009                a: a_storage,
1010                b: b_storage,
1011                marker: PhantomData,
1012            }
1013        }
1014    }
1015
1016    pub struct TupleIterMutRef2<'w, A: Component, B: Component> {
1017        entities: Vec<Entity>,
1018        index: usize,
1019        a: *mut Storage<A>,
1020        b: *const Storage<B>,
1021        marker: PhantomData<(&'w mut A, &'w B)>,
1022    }
1023
1024    impl<'w, A: Component, B: Component> Iterator for TupleIterMutRef2<'w, A, B> {
1025        type Item = (&'w mut A, &'w B);
1026
1027        fn next(&mut self) -> Option<Self::Item> {
1028            if self.a.is_null() || self.b.is_null() {
1029                return None;
1030            }
1031
1032            while self.index < self.entities.len() {
1033                let entity = self.entities[self.index];
1034                self.index += 1;
1035                unsafe {
1036                    let a_storage = &mut *self.a;
1037                    let b_storage = &*self.b;
1038                    let a_ptr = match a_storage.get_mut_ptr(entity) {
1039                        Some(value) => value,
1040                        None => continue,
1041                    };
1042                    let b_ref = match b_storage.get(entity) {
1043                        Some(value) => value,
1044                        None => continue,
1045                    };
1046                    return Some((&mut *a_ptr, b_ref));
1047                }
1048            }
1049            None
1050        }
1051    }
1052
1053    impl<A: Component, B: Component> QueryState<(&mut A, &B)> {
1054        pub fn iter_mut<'w>(&mut self, world: &'w mut World) -> TupleIterMutRef2<'w, A, B> {
1055            assert_ne!(
1056                TypeId::of::<A>(),
1057                TypeId::of::<B>(),
1058                "mixed mutable/immutable query cannot use the same component type"
1059            );
1060
1061            let a_type = TypeId::of::<A>();
1062            let b_type = TypeId::of::<B>();
1063
1064            let a_storage = {
1065                let Some(a_dyn) = world.storages.get_mut(&a_type) else {
1066                    return TupleIterMutRef2 {
1067                        entities: Vec::new(),
1068                        index: 0,
1069                        a: std::ptr::null_mut(),
1070                        b: std::ptr::null(),
1071                        marker: PhantomData,
1072                    };
1073                };
1074
1075                a_dyn
1076                    .as_any_mut()
1077                    .downcast_mut::<Storage<A>>()
1078                    .expect("storage type mismatch") as *mut Storage<A>
1079            };
1080
1081            let b_storage = {
1082                let Some(b_dyn) = world.storages.get(&b_type) else {
1083                    return TupleIterMutRef2 {
1084                        entities: Vec::new(),
1085                        index: 0,
1086                        a: std::ptr::null_mut(),
1087                        b: std::ptr::null(),
1088                        marker: PhantomData,
1089                    };
1090                };
1091
1092                b_dyn
1093                    .as_any()
1094                    .downcast_ref::<Storage<B>>()
1095                    .expect("storage type mismatch") as *const Storage<B>
1096            };
1097
1098            let entities = unsafe { (&*a_storage).entities().to_vec() };
1099
1100            TupleIterMutRef2 {
1101                entities,
1102                index: 0,
1103                a: a_storage,
1104                b: b_storage,
1105                marker: PhantomData,
1106            }
1107        }
1108    }
1109
1110    pub struct TupleIterRefMut2<'w, A: Component, B: Component> {
1111        entities: Vec<Entity>,
1112        index: usize,
1113        a: *const Storage<A>,
1114        b: *mut Storage<B>,
1115        marker: PhantomData<(&'w A, &'w mut B)>,
1116    }
1117
1118    impl<'w, A: Component, B: Component> Iterator for TupleIterRefMut2<'w, A, B> {
1119        type Item = (&'w A, &'w mut B);
1120
1121        fn next(&mut self) -> Option<Self::Item> {
1122            if self.a.is_null() || self.b.is_null() {
1123                return None;
1124            }
1125
1126            while self.index < self.entities.len() {
1127                let entity = self.entities[self.index];
1128                self.index += 1;
1129                unsafe {
1130                    let a_storage = &*self.a;
1131                    let b_storage = &mut *self.b;
1132                    let a_ref = match a_storage.get(entity) {
1133                        Some(value) => value,
1134                        None => continue,
1135                    };
1136                    let b_ptr = match b_storage.get_mut_ptr(entity) {
1137                        Some(value) => value,
1138                        None => continue,
1139                    };
1140                    return Some((a_ref, &mut *b_ptr));
1141                }
1142            }
1143            None
1144        }
1145    }
1146
1147    impl<A: Component, B: Component> QueryState<(&A, &mut B)> {
1148        pub fn iter_mut<'w>(&mut self, world: &'w mut World) -> TupleIterRefMut2<'w, A, B> {
1149            assert_ne!(
1150                TypeId::of::<A>(),
1151                TypeId::of::<B>(),
1152                "mixed immutable/mutable query cannot use the same component type"
1153            );
1154
1155            let a_type = TypeId::of::<A>();
1156            let b_type = TypeId::of::<B>();
1157
1158            let a_storage = {
1159                let Some(a_dyn) = world.storages.get(&a_type) else {
1160                    return TupleIterRefMut2 {
1161                        entities: Vec::new(),
1162                        index: 0,
1163                        a: std::ptr::null(),
1164                        b: std::ptr::null_mut(),
1165                        marker: PhantomData,
1166                    };
1167                };
1168
1169                a_dyn
1170                    .as_any()
1171                    .downcast_ref::<Storage<A>>()
1172                    .expect("storage type mismatch") as *const Storage<A>
1173            };
1174
1175            let b_storage = {
1176                let Some(b_dyn) = world.storages.get_mut(&b_type) else {
1177                    return TupleIterRefMut2 {
1178                        entities: Vec::new(),
1179                        index: 0,
1180                        a: std::ptr::null(),
1181                        b: std::ptr::null_mut(),
1182                        marker: PhantomData,
1183                    };
1184                };
1185
1186                b_dyn
1187                    .as_any_mut()
1188                    .downcast_mut::<Storage<B>>()
1189                    .expect("storage type mismatch") as *mut Storage<B>
1190            };
1191
1192            let entities = unsafe { (&*a_storage).entities().to_vec() };
1193
1194            TupleIterRefMut2 {
1195                entities,
1196                index: 0,
1197                a: a_storage,
1198                b: b_storage,
1199                marker: PhantomData,
1200            }
1201        }
1202    }
1203
1204    pub struct FilteredQueryState<Q, F> {
1205        marker: PhantomData<(Q, F)>,
1206    }
1207
1208    pub struct EntityWithWithoutIter {
1209        entities: Vec<Entity>,
1210        index: usize,
1211    }
1212
1213    impl Iterator for EntityWithWithoutIter {
1214        type Item = Entity;
1215
1216        fn next(&mut self) -> Option<Self::Item> {
1217            if self.index >= self.entities.len() {
1218                return None;
1219            }
1220            let item = self.entities[self.index];
1221            self.index += 1;
1222            Some(item)
1223        }
1224    }
1225
1226    impl<T: Component, U: Component> FilteredQueryState<Entity, (With<T>, Without<U>)> {
1227        pub fn iter(&mut self, world: &World) -> EntityWithWithoutIter {
1228            let mut entities = Vec::new();
1229            if let Some(with_storage) = world.storage::<T>() {
1230                for entity in with_storage.entities().iter().copied() {
1231                    let has_without = world
1232                        .storage::<U>()
1233                        .map(|storage| storage.contains_entity(entity))
1234                        .unwrap_or(false);
1235                    if !has_without {
1236                        entities.push(entity);
1237                    }
1238                }
1239            }
1240            EntityWithWithoutIter { entities, index: 0 }
1241        }
1242    }
1243}
1244
1245pub mod prelude {
1246    pub use crate::component::Component;
1247    pub use crate::entity::Entity;
1248    pub use crate::query::{With, Without};
1249    pub use crate::resource::Resource;
1250    pub use crate::schedule::ScheduleLabel;
1251    pub use crate::system::{
1252        in_state, CommandQueue, Commands, IntoSystem, IntoSystemExt, Query, Res, ResMut, State,
1253        System, SystemParam,
1254    };
1255    pub use crate::world::World;
1256}
1257
1258#[cfg(test)]
1259mod tests {
1260    use crate::query::{With, Without};
1261    use crate::system::{
1262        in_state, CommandQueue, Commands, IntoSystem, IntoSystemExt, Query, ResMut, State,
1263    };
1264    use crate::world::World;
1265    use crate::{Component, Resource};
1266
1267    #[derive(Component, Debug, PartialEq)]
1268    struct Position(i32);
1269
1270    #[derive(Component, Debug, PartialEq)]
1271    struct Velocity(i32);
1272
1273    #[derive(Resource, Default)]
1274    struct Tick(u64);
1275
1276    #[test]
1277    fn spawn_insert_remove_and_despawn_work() {
1278        let mut world = World::new();
1279        let entity = world.spawn((Position(1), Velocity(2))).id();
1280
1281        assert_eq!(world.get::<Position>(entity).map(|v| v.0), Some(1));
1282        assert_eq!(world.get::<Velocity>(entity).map(|v| v.0), Some(2));
1283
1284        let removed = world.remove::<Velocity>(entity);
1285        assert_eq!(removed.map(|v| v.0), Some(2));
1286        assert!(world.get::<Velocity>(entity).is_none());
1287
1288        assert!(world.despawn(entity));
1289        assert!(!world.contains(entity));
1290        assert!(world.get::<Position>(entity).is_none());
1291    }
1292
1293    #[test]
1294    fn resources_and_non_send_resources_work() {
1295        let mut world = World::new();
1296        world.init_resource::<Tick>();
1297        world.resource_mut::<Tick>().0 = 7;
1298        assert_eq!(world.resource::<Tick>().0, 7);
1299
1300        world.insert_non_send_resource(String::from("watcher"));
1301        assert_eq!(
1302            world.get_non_send_resource::<String>().map(String::as_str),
1303            Some("watcher")
1304        );
1305    }
1306
1307    #[test]
1308    fn query_and_filtered_query_work() {
1309        let mut world = World::new();
1310        let a = world.spawn((Position(1), Velocity(10))).id();
1311        let b = world.spawn(Position(2)).id();
1312
1313        {
1314            let mut query = world.query::<(&mut Position, &mut Velocity)>();
1315            for (position, velocity) in query.iter_mut(&mut world) {
1316                position.0 += velocity.0;
1317            }
1318        }
1319
1320        assert_eq!(world.get::<Position>(a).map(|v| v.0), Some(11));
1321        assert_eq!(world.get::<Position>(b).map(|v| v.0), Some(2));
1322
1323        let mut filtered =
1324            world.query_filtered::<crate::entity::Entity, (With<Position>, Without<Velocity>)>();
1325        let entities: Vec<_> = filtered.iter(&world).collect();
1326        assert_eq!(entities, vec![b]);
1327    }
1328
1329    fn movement_system(mut tick: ResMut<Tick>, mut query: Query<(&mut Position, &Velocity)>) {
1330        tick.0 += 1;
1331        for (position, velocity) in query.iter_mut() {
1332            position.0 += velocity.0;
1333        }
1334    }
1335
1336    #[test]
1337    fn into_system_extracts_params_from_signature() {
1338        let mut world = World::new();
1339        world.insert_resource(Tick::default());
1340        let entity = world.spawn((Position(1), Velocity(2))).id();
1341
1342        let mut system = movement_system.into_system();
1343        let mut commands = CommandQueue::new();
1344        system.run(&mut world, &mut commands);
1345        commands.apply(&mut world);
1346
1347        assert_eq!(world.resource::<Tick>().0, 1);
1348        assert_eq!(world.get::<Position>(entity).map(|p| p.0), Some(3));
1349    }
1350
1351    fn spawn_with_commands(mut commands: Commands) {
1352        commands.spawn(Position(42));
1353    }
1354
1355    #[test]
1356    fn commands_are_deferred_until_applied() {
1357        let mut world = World::new();
1358
1359        let mut system = spawn_with_commands.into_system();
1360        let mut queue = CommandQueue::new();
1361        system.run(&mut world, &mut queue);
1362
1363        {
1364            let mut query = world.query::<&Position>();
1365            assert!(query.iter(&world).next().is_none());
1366        }
1367
1368        queue.apply(&mut world);
1369
1370        let mut query = world.query::<&Position>();
1371        assert_eq!(query.iter(&world).count(), 1);
1372    }
1373
1374    #[derive(Clone, Debug, PartialEq, Eq)]
1375    enum AppState {
1376        Menu,
1377        Playing,
1378    }
1379
1380    fn gated_tick(mut tick: ResMut<Tick>) {
1381        tick.0 += 1;
1382    }
1383
1384    #[test]
1385    fn run_if_in_state_gates_system_execution() {
1386        let mut world = World::new();
1387        world.insert_resource(Tick::default());
1388        world.insert_resource(State::new(AppState::Menu));
1389
1390        let mut system = gated_tick.run_if(in_state(AppState::Playing));
1391        let mut queue = CommandQueue::new();
1392
1393        system.run(&mut world, &mut queue);
1394        assert_eq!(world.resource::<Tick>().0, 0);
1395
1396        world
1397            .resource_mut::<State<AppState>>()
1398            .set(AppState::Playing);
1399        system.run(&mut world, &mut queue);
1400        assert_eq!(world.resource::<Tick>().0, 1);
1401    }
1402}