pyro/
lib.rs

1//! # What is an Entity Component System?
2//! An Entity Component System or *ECS* is very similar to a relational database like *SQL*. The
3//! [`World`] is the data store where game objects (also known as [`Entity`]) live. An [`Entity`]
4//! contains data or [`Component`]s.
5//! The *ECS* can efficiently query those components.
6//!
7//! > Give me all entities that have a position and velocity component, and then update the position
8//! based on the velocity.
9//!
10//! ```rust,ignore
11//! type PosVelQuery = (Write<Pos>, Read<Vel>);
12//! //                  ^^^^^       ^^^^
13//! //                  Mutable     Immutable
14//! world.matcher::<All<PosVelQuery>>().for_each(|(pos, vel)|{
15//!     pos += vel;
16//! })
17//! ```
18//!
19//! # Internals
20//! ## Overview
21//! * Iteration is always **linear**.
22//! * Different component combinations live in a separate storage
23//! * Removing entities does not create holes.
24//! * All operations are designed to be used in bulk.
25//! * Borrow rules are enforced at runtime. See [`RuntimeBorrow`]
26//! * [`Entity`] is using a wrapping generational index. See [`Entity::version`]
27//!
28//! ```ignore
29//!// A Storage that contains `Pos`, `Vel`, `Health`.
30//!(
31//!    [Pos1, Pos2, Pos3, .., PosN],
32//!    [Vel1, Vel2, Vel3, .., VelN],
33//!    [Health1, Health2, Health3, .., HealthN],
34//!)
35//!
36//!// A Storage that contains `Pos`, `Vel`.
37//!(
38//!    [Pos1, Pos2, Pos3, .., PosM]
39//!    [Vel1, Vel2, Vel3, .., VelM]
40//!)
41//!
42//! ```
43//!
44//! Iteration is fully linear with the exception of jumping to different storages.
45//!
46//! The iteration pattern from the query above would be
47//!
48//!
49//! ```ignore
50//! positions:  [Pos1, Pos2, Pos3, .., PosN], [Pos1, Pos2, Pos3, .., PosM]
51//! velocities: [Vel1, Vel2, Vel3, .., VelN], [Vel1, Vel2, Vel3, .., VelM]
52//!                                         ^
53//!                                         Jump occurs here
54//! ```
55//! The jump is something like a chain of two iterators. We look at all the storages
56//! that match specific query. If the query would be `Write<Position>`, then we would
57//! look for all the storages that contain a position array, extract the iterators and chain them
58//!
59//! Every combination of components will be in a separate storage. This guarantees that iteration
60//! will always be linear.
61//!
62//! # Benchmarks
63//!
64//! ![](https://raw.githubusercontent.com/MaikKlein/ecs_bench/master/graph/all.png)
65//!
66//! # Getting started
67//!
68//! ```
69//! extern crate pyro;
70//! use pyro::{ World, Entity, Read, Write, All, SoaStorage };
71//! struct Position;
72//! struct Velocity;
73//!
74//!
75//! // By default creates a world backed by a [`SoaStorage`]
76//! let mut world: World<SoaStorage> = World::new();
77//! let add_pos_vel = (0..99).map(|_| (Position{}, Velocity{}));
78//! //                                 ^^^^^^^^^^^^^^^^^^^^^^^^
79//! //                                 A tuple of (Position, Velocity),
80//! //                                 Note: Order does *not* matter
81//!
82//! // Appends 99 entities with a Position and Velocity component.
83//! world.append_components(add_pos_vel);
84//!
85//! // Appends a single entity
86//! world.append_components(Some((Position{}, Velocity{})));
87//!
88//! // Requests a mutable borrow to Position, and an immutable borrow to Velocity.
89//! // Common queries can be reused with a typedef like this but it is not necessary.
90//! type PosVelQuery = (Write<Position>, Read<Velocity>);
91//!
92//! // Retrieves all entities that have a Position and Velocity component as an iterator.
93//! world.matcher::<All<PosVelQuery>>().for_each(|(pos, vel)|{
94//!    // ...
95//! });
96//!
97//! // The same query as above but also retrieves the entities and collects the entities into a
98//! // `Vec<Entity>`.
99//! let entities: Vec<Entity> =
100//!     world.matcher_with_entities::<All<PosVelQuery>>()
101//!     .filter_map(|(entity, (pos, vel))|{
102//!         Some(entity)
103//!     }).collect();
104//!
105//! // Removes all the entities
106//! world.remove_entities(entities);
107//! let count = world.matcher::<All<PosVelQuery>>().count();
108//! assert_eq!(count, 0);
109//! ```
110extern crate downcast_rs;
111extern crate itertools;
112extern crate log;
113extern crate parking_lot;
114extern crate rayon;
115extern crate typedef;
116extern crate vec_map;
117use downcast_rs::{impl_downcast, Downcast};
118use itertools::{multizip, Zip};
119use log::debug;
120use parking_lot::Mutex;
121use std::any::TypeId;
122use std::cell::UnsafeCell;
123use std::collections::{HashMap, HashSet};
124use std::iter::FusedIterator;
125use std::marker::PhantomData;
126use std::num::Wrapping;
127use typedef::TypeDef;
128use vec_map::VecMap;
129
130pub type StorageId = u16;
131pub type ComponentId = u32;
132pub type Version = u16;
133
134/// The [`Iterator`] is used to end a borrow from a query like [`World::matcher`].
135pub struct BorrowIter<'s, S, I> {
136    world: &'s World<S>,
137    iter: I,
138}
139
140impl<'s, S, I> Iterator for BorrowIter<'s, S, I>
141where
142    I: Iterator,
143{
144    type Item = I::Item;
145    #[inline]
146    fn size_hint(&self) -> (usize, Option<usize>) {
147        self.iter.size_hint()
148    }
149    #[inline]
150    fn next(&mut self) -> Option<Self::Item> {
151        self.iter.next()
152    }
153}
154
155impl<'s, S, I> FusedIterator for BorrowIter<'s, S, I> where I: FusedIterator {}
156
157impl<'s, S, I> ExactSizeIterator for BorrowIter<'s, S, I>
158where
159    I: ExactSizeIterator,
160{
161    fn len(&self) -> usize {
162        self.iter.len()
163    }
164}
165
166impl<'s, S, I> Drop for BorrowIter<'s, S, I> {
167    fn drop(&mut self) {
168        self.world.runtime_borrow.lock().pop_access();
169    }
170}
171
172/// Serves as an ID to lookup components for entities which can be in
173/// different storages.
174// [TODO]: Make `Entity` generic.
175#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
176pub struct Entity {
177    /// Removing entities will increment the versioning. Accessing an [`Entity`] with an
178    /// outdated version will result in a `panic`. `version` does wrap on overflow.
179    version: Wrapping<Version>,
180    /// The id of the storage where the [`Entity`] lives in
181    storage_id: StorageId,
182    /// The actual id inside a storage
183    id: ComponentId,
184}
185
186/// [`World`] is the heart of this library. It owns all the [`Component`]s and [`Storage`]s.
187/// It also manages entities and allows [`Component`]s to be safely queried.
188pub struct World<S = SoaStorage> {
189    /// Storages need to be linear, that is why deletion will use [`Vec::swap_remove`] under the
190    /// hood. But this moves the components around and we need to keep track of those swaps. This
191    /// map is then used to find the correct [`ComponentId`] for an [`Entity`]. This maps the
192    /// entity id to the real storage id.
193    component_map: Vec<VecMap<ComponentId>>,
194    /// This is the opposite of `component_map`. This maps the storage id to the entity id.
195    component_map_inv: Vec<VecMap<ComponentId>>,
196    /// When we remove an [`Entity`], we will put it in this free map to be reused.
197    free_map: Vec<Vec<ComponentId>>,
198    version: Vec<Vec<Wrapping<Version>>>,
199    storages: Vec<S>,
200    /// The runtime borrow system. See [`RuntimeBorrow`] for more information. It is also wrapped
201    /// in a Mutex so that we can keep track of multiple borrows on different threads.
202    runtime_borrow: Mutex<RuntimeBorrow>,
203}
204
205impl<S> Default for World<S> {
206    fn default() -> Self {
207        Self::new()
208    }
209}
210
211impl<S> World<S> {
212    /// Creates an empty [`World`].
213    pub fn new() -> Self {
214        World {
215            runtime_borrow: Mutex::new(RuntimeBorrow::new()),
216            component_map: Vec::new(),
217            component_map_inv: Vec::new(),
218            free_map: Vec::new(),
219            version: Vec::new(),
220            storages: Vec::new(),
221        }
222    }
223}
224
225impl<S> World<S>
226where
227    S: Storage,
228{
229    /// Creates an `Iterator` over every [`Entity`] inside [`World`]. The entities are
230    /// not ordered.
231    pub fn entities<'s>(&'s self) -> impl Iterator<Item = Entity> + 's {
232        self.component_map
233            .iter()
234            .enumerate()
235            .flat_map(move |(idx, inner)| {
236                let storage_id = idx as StorageId;
237                inner.keys().map(move |component_id| Entity {
238                    storage_id,
239                    id: component_id as ComponentId,
240                    version: self.version[storage_id as usize][component_id as usize],
241                })
242            })
243    }
244
245    fn entities_storage<'s>(&'s self, storage_id: StorageId) -> impl Iterator<Item = Entity> + 's {
246        // We iterate with the `component_map_inv`, because that is the order of the real storage.
247        self.component_map_inv[storage_id as usize]
248            .values()
249            .map(move |&id| Entity {
250                storage_id,
251                id,
252                version: self.version[storage_id as usize][id as usize],
253            })
254    }
255
256    /// Pushes a new borrow on the stack and checks if there are any illegal overlapping borrows
257    /// such as Write/Write and Read/Write.
258    fn borrow_and_validate<Borrow: RegisterBorrow>(&self) {
259        let mut borrow = self.runtime_borrow.lock();
260        borrow.push_access::<Borrow>();
261        // TODO: Implement a better error message.
262        if let Err(overlapping_borrows) = borrow.validate() {
263            panic!("Detected multiple active borrows of: {:?}", {
264                overlapping_borrows
265                    .iter()
266                    .map(|ty| ty.get_str())
267                    .collect::<Vec<_>>()
268            });
269        }
270    }
271    /// Uses [`Query`] and [`Matcher`] to access the correct components. [`Read`] will borrow the
272    /// component immutable while [`Write`] will borrow the component mutable.
273    /// ```rust,ignore
274    /// fn update(world: &mut World) {
275    ///    world
276    ///        .matcher::<All<(Write<Position>, Read<Velocity>)>>()
277    ///        .for_each(|(p, v)| {
278    ///            p.x += v.dx;
279    ///            p.y += v.dy;
280    ///        });
281    /// }
282    /// ```
283    pub fn matcher<'s, Q>(
284        &'s self,
285    ) -> impl Iterator<Item = <<Q as Query<'s>>::Iter as Iterator>::Item> + 's
286    where
287        Q: Query<'s> + Matcher,
288        Q::Borrow: RegisterBorrow,
289    {
290        self.borrow_and_validate::<Q::Borrow>();
291        let iter = unsafe {
292            self.storages
293                .iter()
294                .filter(|&storage| Q::is_match(storage))
295                .map(|storage| Q::query(storage))
296                .flat_map(|iter| iter)
297        };
298        // [FIXME]: BorrowIter is more than 2x slower, than just returning `iter` here for the
299        // `ecs_bench`. Maybe the benchmark is too simple?
300        BorrowIter { world: self, iter }
301    }
302    /// Same as [`World::matcher`] but also returns the corresponding [`Entity`].
303    /// ```rust,ignore
304    /// fn update(world: &mut World) {
305    ///    world
306    ///        .matcher_with_entities::<All<(Write<Position>, Read<Velocity>)>>()
307    ///        .for_each(|(entity, (p, v))| {
308    ///            p.x += v.dx;
309    ///            p.y += v.dy;
310    ///        });
311    /// }
312    /// ```
313    pub fn matcher_with_entities<'s, Q>(
314        &'s self,
315    ) -> impl Iterator<Item = (Entity, <<Q as Query<'s>>::Iter as Iterator>::Item)> + 's
316    where
317        Q: Query<'s> + Matcher,
318        Q::Borrow: RegisterBorrow,
319    {
320        self.borrow_and_validate::<Q::Borrow>();
321        let iter = self
322            .storages
323            .iter()
324            .enumerate()
325            .filter(|&(_, storage)| Q::is_match(storage))
326            .flat_map(move |(id, storage)| {
327                let query = unsafe { Q::query(storage) };
328                let entities = self.entities_storage(id as StorageId);
329                Iterator::zip(entities, query)
330            });
331        BorrowIter { world: self, iter }
332    }
333}
334impl<S> World<S>
335where
336    S: Storage + RegisterComponent,
337{
338    /// Appends the components and also creates the necessary [`Entity`]s behind the scenes.
339    /// If you only want to append a single set of components then you can do
340    /// ```rust,ignore
341    /// world.append_components(Some((a, b, c)));
342    /// ```
343    pub fn append_components<A, I>(&mut self, i: I)
344    where
345        A: AppendComponents + BuildStorage,
346        I: IntoIterator<Item = A>,
347    {
348        // Try to find a matching storage, and insert the components
349        let (storage_id, insert_count) = if let Some(storage) = self
350            .storages
351            .iter_mut()
352            .find(|storage| A::is_match::<S>(storage))
353        {
354            let len = A::append_components(i, storage);
355            (storage.id(), len)
356        } else {
357            // if we did not find a storage, we need to create one
358            let id = self.storages.len() as StorageId;
359            let mut storage = <A as BuildStorage>::build::<S>(id).access();
360            let len = A::append_components(i, &mut storage);
361            self.storages.push(storage);
362            // Also we need to add an entity Vec for that storage
363            self.component_map.push(VecMap::default());
364            self.component_map_inv.push(VecMap::default());
365            self.free_map.push(Vec::new());
366            self.version.push(Vec::new());
367            (id, len)
368        };
369        let storage_index = storage_id as usize;
370        if insert_count == 0 {
371            return;
372        }
373        // Inserting components is not enough, we also need to create the entity ids
374        // for those components.
375        let start_len = self.component_map[storage_index].len() as ComponentId;
376        let end_len = start_len + insert_count as ComponentId;
377        debug!("Append to Storage: {}", storage_id);
378        debug!("- Insert count: {}", insert_count);
379        debug!(
380            "- Map length before: {}",
381            self.component_map[storage_id as usize].len()
382        );
383        for component_id in start_len..end_len {
384            if let Some(insert_at) = self.free_map[storage_index].pop() {
385                // When we create a new entity that has already been deleted once, we need to
386                // increment the version.
387                self.insert_component_map(storage_id, insert_at, component_id);
388            } else {
389                // If the free list is empty, then we can insert it at the end.
390                let insert_at = self.component_map[storage_index].len() as ComponentId;
391                self.version[storage_index].push(Wrapping(0));
392                self.insert_component_map(storage_id, insert_at, component_id);
393            }
394        }
395        assert_eq!(
396            self.component_map[storage_index].len(),
397            self.storages[storage_index].len(),
398            "The size of the component map and storage map should be equal"
399        );
400    }
401
402    /// Compares the version of the entity with the version in [`World`] and returns true if they
403    /// match. Because `version` wraps around this is not a hard guarantee.
404    pub fn is_entity_valid(&self, entity: Entity) -> bool {
405        self.version[entity.storage_id as usize]
406            .get(entity.id as usize)
407            .map(|&version| version == entity.version)
408            .unwrap_or(false)
409    }
410
411    fn insert_component_map(
412        &mut self,
413        storage_id: StorageId,
414        id: ComponentId,
415        component_id: ComponentId,
416    ) {
417        self.component_map[storage_id as usize].insert(id as usize, component_id);
418        self.component_map_inv[storage_id as usize].insert(component_id as usize, id);
419    }
420
421
422    /// Returns true if the entity owns the requested component.
423    pub fn has_component<C: Component>(&self, e: Entity) -> bool {
424        self.get_component::<C>(e).is_some()
425    }
426
427    /// Retrieves a component for a specific [`Entity`].
428    pub fn get_component<C: Component>(&self, e: Entity) -> Option<&C> {
429        unsafe {
430            let storage = &self.storages[e.storage_id as usize];
431            if !storage.contains::<C>() || !self.is_entity_valid(e) {
432                return None;
433            }
434            let component_id = self.component_map[e.storage_id as usize][e.id as usize];
435            storage.component::<C>().get(component_id as usize)
436        }
437    }
438
439    /// Same as [`World::get_component`] but mutable.
440    // [TODO]: Possibly make this immutable and add the runtime borrow system if &mut isn't
441    // flexible enough.
442    pub fn get_component_mut<C: Component>(&mut self, e: Entity) -> Option<&mut C> {
443        unsafe {
444            let storage = &self.storages[e.storage_id as usize];
445            if !storage.contains::<C>() || !self.is_entity_valid(e) {
446                return None;
447            }
448            let component_id = self.component_map[e.storage_id as usize][e.id as usize];
449            storage.component_mut::<C>().get_mut(component_id as usize)
450        }
451    }
452
453    /// Removes the specified entities from [`World`]. Those entities are now considered invalid,
454    /// which can be checked with [`World::is_entity_valid`].
455    pub fn remove_entities<I>(&mut self, entities: I)
456    where
457        I: IntoIterator<Item = Entity>,
458    {
459        for entity in entities {
460            debug!("Removing {:?}", entity);
461            let storage_id = entity.storage_id as usize;
462            let is_valid = self.is_entity_valid(entity);
463            if !is_valid {
464                continue;
465            }
466            let component_id = *self.component_map[storage_id]
467                .get(entity.id as usize)
468                .expect("component id");
469            // [FIXME]: This uses dynamic dispatch so we might want to batch entities
470            // together to reduce the overhead.
471            let swap = self.storages[storage_id].remove(component_id) as ComponentId;
472            // We need to keep track which entity was deleted and which was swapped.
473            debug!(
474                "- Entitiy id: {}, Component id: {}, Swap: {}, Map length: {}, Storage length: {}",
475                entity.id,
476                component_id,
477                swap,
478                self.storages[storage_id].len() + 1,
479                self.component_map[storage_id].len()
480            );
481            // We need to look up the id that got swapped
482            let key = self.component_map_inv[storage_id][swap as usize];
483            debug!("- Updating {} to {}", key, component_id);
484            // The id that was swapped should now point to the component_id that was removed
485            self.insert_component_map(storage_id as StorageId, key, component_id);
486
487            debug!("- Removing {} from `component_map`", entity.id);
488            // Now we consider the id to be deleted and remove it from the `component_map`.
489            self.component_map[storage_id as usize].remove(entity.id as usize);
490            // We also need to update our `component_inverse_map`. `swap` was the real location
491            // that was deleted in the underlying `storage` and we need to remove it.
492            self.component_map_inv[storage_id as usize].remove(swap as usize);
493            // And we need to append the remove id to the free map so we can reuse it again when we
494            // `append_components`.
495            self.free_map[storage_id].push(entity.id);
496            self.version[storage_id][entity.id as usize] += Wrapping(1);
497        }
498    }
499}
500
501pub trait RegisterBorrow {
502    /// Creates a new borrow
503    fn register_borrow() -> Borrow;
504}
505
506/// Is implemented for [`Read`] and [`Write`] and is used to insert reads and writes into the
507/// correct [`HashSet`].
508pub trait PushBorrow {
509    /// Inserts a new borrow and returns true if it was successful.
510    fn push_borrow(acccess: &mut Borrow) -> bool;
511}
512impl<T: Component> PushBorrow for Write<T> {
513    /// If a `Write` was already in a set, then we have detected multiple writes and this is not
514    /// allows.
515    fn push_borrow(borrow: &mut Borrow) -> bool {
516        borrow.writes.insert(TypeDef::of::<T>())
517    }
518}
519
520impl<T: Component> PushBorrow for Read<T> {
521    /// Multiple reads are always allowed and therefor we can always return true
522    fn push_borrow(borrow: &mut Borrow) -> bool {
523        borrow.reads.insert(TypeDef::of::<T>());
524        true
525    }
526}
527
528macro_rules! impl_register_borrow{
529    ($($ty: ident),*) => {
530        impl<$($ty,)*> RegisterBorrow for ($($ty,)*)
531        where
532            $(
533                $ty: PushBorrow,
534            )*
535        {
536            fn register_borrow() -> Borrow {
537                let mut borrow = Borrow::new();
538                let success =
539                $(
540                    $ty::push_borrow(&mut borrow)
541                )&&*;
542                // TODO: Output a more meaningful error
543                assert!(success, "Detected multiple writes");
544                borrow
545            }
546        }
547    }
548}
549
550impl_register_borrow!(A);
551impl_register_borrow!(A, B);
552impl_register_borrow!(A, B, C);
553impl_register_borrow!(A, B, C, D);
554impl_register_borrow!(A, B, C, D, E);
555impl_register_borrow!(A, B, C, D, E, F);
556impl_register_borrow!(A, B, C, D, E, F, G);
557impl_register_borrow!(A, B, C, D, E, F, G, H);
558
559/// Rust's borrowing rules are not flexible enough for an *ECS*. Often it would preferred to nest multiple
560/// queries like [`World::matcher`], but this is not possible if both borrows would be mutable.
561/// Instead we track active borrows at runtime. Multiple reads are allowed but `read/write` and
562/// `write/write` are not.
563pub struct RuntimeBorrow {
564    borrows: Vec<Borrow>,
565}
566
567impl Default for RuntimeBorrow {
568    fn default() -> Self {
569        Self::new()
570    }
571}
572
573impl RuntimeBorrow {
574    pub fn new() -> Self {
575        Self {
576            borrows: Vec::new(),
577        }
578    }
579
580    /// Creates and pushes an [`Borrow`] on to the stack.
581    pub fn push_access<R: RegisterBorrow>(&mut self) {
582        let borrow = R::register_borrow();
583        self.borrows.push(borrow);
584    }
585    /// Removes latest [`Borrow`]. This is usually called when an [`BorrowIter`] is dropped.
586    pub fn pop_access(&mut self) {
587        self.borrows.pop();
588    }
589    /// Validates the borrows. Multiple reads are allowed but Read/Write and Write/Write are not.
590    pub fn validate(&self) -> Result<(), Vec<TypeDef>> {
591        let overlapping_borrows: Vec<_> = self
592            .borrows
593            .iter()
594            .enumerate()
595            .flat_map(|(idx, borrow)| {
596                let reads = borrow.writes.intersection(&borrow.reads).cloned();
597                let rest: Vec<_> = self
598                    .borrows
599                    .iter()
600                    .skip(idx + 1)
601                    .flat_map(|next_access| {
602                        let writes = borrow.writes.intersection(&next_access.writes).cloned();
603                        let reads = borrow.writes.intersection(&next_access.reads).cloned();
604                        writes.chain(reads)
605                    })
606                    .collect();
607                reads.chain(rest)
608            })
609            .collect();
610        if overlapping_borrows.is_empty() {
611            Ok(())
612        } else {
613            Err(overlapping_borrows)
614        }
615    }
616}
617
618pub struct Borrow {
619    reads: HashSet<TypeDef>,
620    writes: HashSet<TypeDef>,
621}
622
623impl Default for Borrow {
624    fn default() -> Self {
625        Self::new()
626    }
627}
628
629impl Borrow {
630    pub fn new() -> Self {
631        Self {
632            reads: HashSet::new(),
633            writes: HashSet::new(),
634        }
635    }
636}
637pub trait Component: Send + 'static {}
638impl<C: 'static + Send> Component for C {}
639
640/// Implements [`Fetch`] and allows components to be borrowed immutable.
641pub struct Read<C>(PhantomData<C>);
642/// Implements [`Fetch`] and allows components to be borrowed mutable.
643pub struct Write<C>(PhantomData<C>);
644/// A helper trait that works in lockstep with [`Read`] and [`Write`] to borrow components either
645/// mutable or immutable.
646pub trait Fetch<'s> {
647    type Component: Component;
648    type Iter: ExactSizeIterator + 's;
649    unsafe fn fetch<S: Storage>(storage: &'s S) -> Self::Iter;
650}
651
652impl<'s, C: Component> Fetch<'s> for Read<C> {
653    type Component = C;
654    type Iter = std::slice::Iter<'s, C>;
655    unsafe fn fetch<S: Storage>(storage: &'s S) -> Self::Iter {
656        storage.component::<C>().iter()
657    }
658}
659
660impl<'s, C: Component> Fetch<'s> for Write<C> {
661    type Component = C;
662    type Iter = std::slice::IterMut<'s, C>;
663    unsafe fn fetch<S: Storage>(storage: &'s S) -> Self::Iter {
664        storage.component_mut::<C>().iter_mut()
665    }
666}
667
668/// Allows to match over different [`Storage`]s. See also [`All`].
669pub trait Matcher {
670    fn is_match<S: Storage>(storage: &S) -> bool;
671}
672/// Allows to query multiple components from a [`Storage`]. See also [`All`].
673pub trait Query<'s> {
674    type Borrow;
675    type Iter: ExactSizeIterator + 's;
676    unsafe fn query<S: Storage>(storage: &'s S) -> Self::Iter;
677}
678
679/// Is satisfied when a storages contains all of the specified components.
680/// ```rust,ignore
681/// type Query = All<(Write<Position>, Read<Velocity>)>;
682/// ```
683pub struct All<'s, Tuple>(pub PhantomData<&'s Tuple>);
684
685macro_rules! impl_matcher_all{
686    ($($ty: ident),*) => {
687        impl<'s, $($ty,)*> Matcher for All<'s, ($($ty,)*)>
688        where
689            $(
690                $ty: Fetch<'s>,
691            )*
692        {
693            fn is_match<S: Storage>(storage: &S) -> bool {
694                $(
695                    storage.contains::<$ty::Component>()
696                )&&*
697            }
698        }
699    }
700}
701
702impl_matcher_all!(A);
703impl_matcher_all!(A, B);
704impl_matcher_all!(A, B, C);
705impl_matcher_all!(A, B, C, D);
706impl_matcher_all!(A, B, C, D, E);
707impl_matcher_all!(A, B, C, D, E, F);
708impl_matcher_all!(A, B, C, D, E, F, G);
709impl_matcher_all!(A, B, C, D, E, F, G, H);
710// impl_matcher_all!(A, B, C, D, E, F, G, H, I);
711// impl_matcher_all!(A, B, C, D, E, F, G, H, I, J);
712// impl_matcher_all!(A, B, C, D, E, F, G, H, I, J, K);
713
714impl<'s, A> Query<'s> for All<'s, A>
715where
716    A: Fetch<'s>,
717{
718    type Borrow = A;
719    type Iter = A::Iter;
720    unsafe fn query<S: Storage>(storage: &'s S) -> Self::Iter {
721        A::fetch(storage)
722    }
723}
724
725macro_rules! impl_query_all{
726    ($($ty: ident),*) => {
727        impl<'s, $($ty,)*> Query<'s> for All<'s, ($($ty,)*)>
728        where
729            $(
730                $ty: Fetch<'s>,
731            )*
732        {
733            type Borrow = ($($ty,)*);
734            type Iter = Zip<($($ty::Iter,)*)>;
735            unsafe fn query<S1: Storage>(storage: &'s S1) -> Self::Iter {
736                multizip(($($ty::fetch(storage),)*))
737            }
738        }
739    }
740}
741
742impl_query_all!(A);
743impl_query_all!(A, B);
744impl_query_all!(A, B, C);
745impl_query_all!(A, B, C, D);
746impl_query_all!(A, B, C, D, E);
747impl_query_all!(A, B, C, D, E, F);
748impl_query_all!(A, B, C, D, E, F, G);
749impl_query_all!(A, B, C, D, E, F, G, H);
750// impl_query_all!(A, B, C, D, E, F, G, H, I);
751// impl_query_all!(A, B, C, D, E, F, G, H, I, J);
752// impl_query_all!(A, B, C, D, E, F, G, H, I, J, K);
753
754pub struct EmptyStorage<S> {
755    storage: S,
756}
757
758/// [`BuildStorage`] is used to create different [`Storage`]s at runtime. See also
759/// [`AppendComponents`] and [`World::append_components`]
760pub trait BuildStorage {
761    fn build<S: Storage + RegisterComponent>(id: StorageId) -> EmptyStorage<S>;
762}
763
764macro_rules! impl_build_storage {
765    ($($ty: ident),*) => {
766        impl<$($ty),*> BuildStorage for ($($ty,)*)
767        where
768            $(
769                $ty:Component,
770            )*
771        {
772            fn build<S: Storage + RegisterComponent>(id: StorageId) -> EmptyStorage<S> {
773                let mut empty = S::empty(id);
774                $(
775                    empty.register_component::<$ty>();
776                )*
777                empty
778            }
779        }
780    }
781}
782impl_build_storage!(A);
783impl_build_storage!(A, B);
784impl_build_storage!(A, B, C);
785impl_build_storage!(A, B, C, D);
786impl_build_storage!(A, B, C, D, E);
787impl_build_storage!(A, B, C, D, E, F);
788impl_build_storage!(A, B, C, D, E, F, G);
789impl_build_storage!(A, B, C, D, E, F, G, H);
790// impl_build_storage!(A, B, C, D, E, F, G, H, I);
791// impl_build_storage!(A, B, C, D, E, F, G, H, I, J);
792// impl_build_storage!(A, B, C, D, E, F, G, H, I, J, k);
793
794impl<S> EmptyStorage<S>
795where
796    S: Storage + RegisterComponent,
797{
798    pub fn register_component<C: Component>(&mut self) {
799        self.storage.register_component::<C>();
800    }
801    pub fn access(self) -> S {
802        self.storage
803    }
804}
805
806pub trait RuntimeStorage: Downcast {
807    fn remove(&mut self, id: ComponentId);
808}
809
810impl_downcast!(RuntimeStorage);
811impl RuntimeStorage {
812    pub fn as_unsafe_storage<C: Component>(&self) -> &UnsafeStorage<C> {
813        self.downcast_ref::<UnsafeStorage<C>>()
814            .expect("Incorrect storage type")
815    }
816    pub fn as_unsafe_storage_mut<C: Component>(&mut self) -> &mut UnsafeStorage<C> {
817        self.downcast_mut::<UnsafeStorage<C>>()
818            .expect("Incorrect storage type")
819    }
820}
821
822impl<T: Component> RuntimeStorage for UnsafeStorage<T> {
823    fn remove(&mut self, id: ComponentId) {
824        unsafe {
825            self.inner_mut().swap_remove(id as usize);
826        }
827    }
828}
829
830// FIXME: *Unsafe* Fix multiple mutable borrows. Should be fixed in the `Query` API.
831pub struct UnsafeStorage<T>(UnsafeCell<Vec<T>>);
832impl<T> UnsafeStorage<T> {
833    pub fn new() -> Self {
834        UnsafeStorage(UnsafeCell::new(Vec::<T>::new()))
835    }
836    pub unsafe fn inner_mut(&self) -> &mut Vec<T> {
837        &mut (*self.0.get())
838    }
839}
840
841pub trait IteratorSoa: Sized {
842    type Output;
843    fn to_soa<I: Iterator<Item = Self>>(iter: I) -> Self::Output;
844}
845macro_rules! impl_iterator_soa {
846    ( $(($item: ident, $ty: ident )),*) => {
847        impl<$($ty),*> IteratorSoa for ($($ty,)*)
848        where
849            $(
850                $ty: Component,
851            )*
852        {
853            type Output = ($(Vec<$ty>,)*);
854            fn to_soa<Iter: Iterator<Item = Self>>(iter: Iter) -> Self::Output {
855                $(
856                    #[allow(non_snake_case)]
857                    let mut $ty = Vec::new();
858                )*
859                for ($($item,)*) in iter {
860                    $(
861                        $ty.push($item);
862                    )*
863                }
864                ($($ty,)*)
865            }
866        }
867    }
868}
869
870impl_iterator_soa!((a, A));
871impl_iterator_soa!((a, A), (b, B));
872impl_iterator_soa!((a, A), (b, B), (c, C));
873impl_iterator_soa!((a, A), (b, B), (c, C), (d, D));
874impl_iterator_soa!((a, A), (b, B), (c, C), (d, D), (e, E));
875impl_iterator_soa!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F));
876impl_iterator_soa!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G));
877impl_iterator_soa!(
878    (a, A),
879    (b, B),
880    (c, C),
881    (d, D),
882    (e, E),
883    (f, F),
884    (g, G),
885    (h, H)
886);
887impl_iterator_soa!(
888    (a, A),
889    (b, B),
890    (c, C),
891    (d, D),
892    (e, E),
893    (f, F),
894    (g, G),
895    (h, H),
896    (i, I)
897);
898impl_iterator_soa!(
899    (a, A),
900    (b, B),
901    (c, C),
902    (d, D),
903    (e, E),
904    (f, F),
905    (g, G),
906    (h, H),
907    (i, I),
908    (j, J)
909);
910impl_iterator_soa!(
911    (a, A),
912    (b, B),
913    (c, C),
914    (d, D),
915    (e, E),
916    (f, F),
917    (g, G),
918    (h, H),
919    (i, I),
920    (j, J),
921    (k, K)
922);
923
924pub trait AppendComponents
925where
926    Self: IteratorSoa,
927{
928    fn is_match<S: Storage>(storage: &S) -> bool;
929    fn append_components<I, S>(items: I, storage: &mut S) -> usize
930    where
931        S: Storage,
932        I: IntoIterator<Item = Self>;
933}
934
935macro_rules! impl_append_components {
936    ($size: expr => $($ty: ident),*) => {
937        impl<$($ty),*> AppendComponents for ($($ty,)*)
938        where
939            $(
940                $ty: Component,
941            )*
942        {
943            fn is_match<S: Storage>(storage: &S) -> bool {
944                let types = storage.types();
945                let mut b = types.len() == $size;
946                $(
947                    b &= types.contains(&TypeId::of::<$ty>());
948                )*
949                b
950            }
951
952            fn append_components<Iter, S>(items: Iter, storage: &mut S) -> usize
953            where
954                S: Storage,
955                Iter: IntoIterator<Item = Self>,
956            {
957                let tuple = Self::to_soa(items.into_iter());
958                let len = tuple.0.len();
959                #[allow(non_snake_case)]
960                let ($($ty,)*) = tuple;
961                $(
962                    storage.push_components($ty);
963                )*
964                *storage.len_mut() += len;
965                len
966            }
967        }
968    }
969}
970
971impl_append_components!(1  => A);
972impl_append_components!(2  => A, B);
973impl_append_components!(3  => A, B, C);
974impl_append_components!(4  => A, B, C, D);
975impl_append_components!(5  => A, B, C, D, E);
976impl_append_components!(6  => A, B, C, D, E, F);
977impl_append_components!(7  => A, B, C, D, E, F, G);
978impl_append_components!(8  => A, B, C, D, E, F, G, H);
979impl_append_components!(9  => A, B, C, D, E, F, G, H, I);
980impl_append_components!(10 => A, B, C, D, E, F, G, H, I, J);
981impl_append_components!(11 => A, B, C, D, E, F, G, H, I, J, K);
982
983/// A runtime SoA storage. It stands for **S**tructure **o**f **A**rrays.
984///
985/// ```rust,ignore
986/// struct Test {
987///     foo: Foo,
988///     bar: Bar,
989///     baz: Baz,
990/// }
991/// let test: Vec<Test> = ...; // Array of Structs (*AoS*) layout
992///
993/// struct Test {
994///     foo: Vec<Foo>,
995///     bar: Vec<Bar>,
996///     baz: Vec<Baz>,
997/// }
998/// let test: Test = ...; // SoA layout
999/// ```
1000/// Users do not interact with this storage directly, instead [`World`] will use this storage
1001/// behind the scenes. In the future there will be other storages such as *AoSoA*, which is a fancy
1002/// way of saying *SoA* but with arrays that a limited to a size of `8`.
1003pub struct SoaStorage {
1004    len: usize,
1005    id: StorageId,
1006    types: HashSet<TypeId>,
1007    storages: HashMap<TypeId, Box<RuntimeStorage>>,
1008}
1009
1010/// A [`Storage`] won't have any arrays or vectors when it is created. [`RegisterComponent`] can
1011/// register or add those component arrays. See also [`EmptyStorage::register_component`]
1012pub trait RegisterComponent {
1013    fn register_component<C: Component>(&mut self);
1014}
1015
1016impl RegisterComponent for SoaStorage {
1017    fn register_component<C: Component>(&mut self) {
1018        // A `SoAStorage` is backed by `UnsafeStorage`.
1019        let type_id = TypeId::of::<C>();
1020        self.types.insert(type_id);
1021        self.storages
1022            .insert(type_id, Box::new(UnsafeStorage::<C>::new()));
1023    }
1024}
1025
1026/// [`Storage`] allows to abstract over different types of storages. The most common storage that
1027/// implements this trait is [`SoaStorage`].
1028pub trait Storage: Sized {
1029    fn len(&self) -> usize;
1030    fn len_mut(&mut self) -> &mut usize;
1031    fn id(&self) -> StorageId;
1032    /// Creates an [`EmptyStorage`]. This storage will not have any registered components when it
1033    /// is created. See [`RegisterComponent`].
1034    fn empty(id: StorageId) -> EmptyStorage<Self>;
1035    /// Retrieves the component array and panics if `C` is not inside this storage.
1036    unsafe fn component<C: Component>(&self) -> &[C];
1037    /// Same as [`Storage::component`] but mutable.
1038    unsafe fn component_mut<C: Component>(&self) -> &mut [C];
1039    /// Appends components to one array. See [`AppendComponents`] that uses this method.
1040    fn push_components<C, I>(&mut self, components: I)
1041    where
1042        C: Component,
1043        I: IntoIterator<Item = C>;
1044    fn push_component<C: Component>(&mut self, component: C);
1045    /// Returns true if the [`Storage`] has an array of type `C`.
1046    fn contains<C: Component>(&self) -> bool;
1047    fn types(&self) -> &HashSet<TypeId>;
1048    /// Removes **all** the components at the specified index.
1049    fn remove(&mut self, id: ComponentId) -> usize;
1050}
1051
1052impl SoaStorage {
1053    /// Convenience method to easily access an [`UnsafeStorage`].
1054    fn get_storage<C: Component>(&self) -> &UnsafeStorage<C> {
1055        let runtime_storage = self
1056            .storages
1057            .get(&TypeId::of::<C>())
1058            .expect("Unknown storage");
1059        runtime_storage.as_unsafe_storage::<C>()
1060    }
1061    /// Same as [`SoaStorage::get_storage`] but mutable.
1062    fn get_storage_mut<C: Component>(&mut self) -> &mut UnsafeStorage<C> {
1063        let runtime_storage = self
1064            .storages
1065            .get_mut(&TypeId::of::<C>())
1066            .expect("Unknown storage");
1067        runtime_storage.as_unsafe_storage_mut::<C>()
1068    }
1069}
1070
1071impl Storage for SoaStorage {
1072    fn len(&self) -> usize {
1073        self.len
1074    }
1075    fn len_mut(&mut self) -> &mut usize {
1076        &mut self.len
1077    }
1078    fn remove(&mut self, id: ComponentId) -> usize {
1079        self.storages.values_mut().for_each(|storage| {
1080            storage.remove(id);
1081        });
1082        self.len -= 1;
1083        self.len
1084    }
1085    fn id(&self) -> StorageId {
1086        self.id
1087    }
1088    fn push_components<C, I>(&mut self, components: I)
1089    where
1090        C: Component,
1091        I: IntoIterator<Item = C>,
1092    {
1093        unsafe {
1094            self.get_storage_mut::<C>().inner_mut().extend(components);
1095        }
1096    }
1097    fn push_component<C: Component>(&mut self, component: C) {
1098        unsafe {
1099            self.get_storage::<C>().inner_mut().push(component);
1100        }
1101    }
1102    fn empty(id: StorageId) -> EmptyStorage<Self> {
1103        let storage = SoaStorage {
1104            types: HashSet::new(),
1105            storages: HashMap::new(),
1106            id,
1107            len: 0,
1108        };
1109        EmptyStorage { storage }
1110    }
1111    unsafe fn component_mut<C: Component>(&self) -> &mut [C] {
1112        self.get_storage::<C>().inner_mut().as_mut_slice()
1113    }
1114    unsafe fn component<C: Component>(&self) -> &[C] {
1115        self.get_storage::<C>().inner_mut().as_slice()
1116    }
1117
1118    fn contains<C: Component>(&self) -> bool {
1119        self.types.contains(&TypeId::of::<C>())
1120    }
1121
1122    fn types(&self) -> &HashSet<TypeId> {
1123        &self.types
1124    }
1125}