legion_core/
world.rs

1use crate::borrow::Ref;
2use crate::borrow::RefMut;
3use crate::entity::BlockAllocator;
4use crate::entity::Entity;
5use crate::entity::EntityAllocator;
6use crate::entity::EntityLocation;
7use crate::entity::Locations;
8use crate::event::Event;
9use crate::filter::ArchetypeFilterData;
10use crate::filter::ChunksetFilterData;
11use crate::filter::EntityFilter;
12use crate::filter::Filter;
13use crate::index::ArchetypeIndex;
14use crate::index::ComponentIndex;
15use crate::index::SetIndex;
16use crate::iterator::SliceVecIter;
17use crate::storage::ArchetypeData;
18use crate::storage::ArchetypeDescription;
19use crate::storage::Component;
20use crate::storage::ComponentMeta;
21use crate::storage::ComponentStorage;
22use crate::storage::ComponentTypeId;
23use crate::storage::Storage;
24use crate::storage::Tag;
25use crate::storage::TagMeta;
26use crate::storage::TagTypeId;
27use crate::storage::Tags;
28use crate::{
29    prelude::Query,
30    query::View,
31    subworld::{ComponentAccess, ComponentAccessError, StorageAccessor, SubWorld},
32    tuple::TupleEq,
33};
34use parking_lot::Mutex;
35use std::cell::UnsafeCell;
36use std::collections::HashMap;
37use std::iter::Enumerate;
38use std::iter::Fuse;
39use std::iter::FusedIterator;
40use std::iter::Peekable;
41use std::iter::Repeat;
42use std::iter::Take;
43use std::marker::PhantomData;
44use std::ops::Deref;
45use std::ptr::NonNull;
46use std::sync::atomic::AtomicUsize;
47use std::sync::atomic::Ordering;
48use std::sync::Arc;
49use thiserror::Error;
50use tracing::{info, span, trace, Level};
51
52static NEXT_UNIVERSE_ID: AtomicUsize = AtomicUsize::new(1);
53static NEXT_WORLD_ID: AtomicUsize = AtomicUsize::new(0);
54
55#[derive(Default, Copy, Clone, PartialEq, Eq, Hash, Debug)]
56pub struct UniverseId(usize);
57
58/// The `Universe` is a factory for creating `World`s.
59///
60/// Entities inserted into worlds created within the same universe are guarenteed to have
61/// unique `Entity` IDs, even across worlds.
62#[derive(Debug)]
63pub struct Universe {
64    id: UniverseId,
65    allocator: Arc<Mutex<BlockAllocator>>,
66}
67
68impl Universe {
69    /// Creates a new `Universe`.
70    #[allow(clippy::new_without_default)]
71    pub fn new() -> Self {
72        Self {
73            id: UniverseId(NEXT_UNIVERSE_ID.fetch_add(1, Ordering::SeqCst)),
74            allocator: Arc::new(Mutex::new(BlockAllocator::new())),
75        }
76    }
77
78    /// Creates a new `World` within this `Universe`.
79    ///
80    /// Entities inserted into worlds created within the same universe are guarenteed to have
81    /// unique `Entity` IDs, even across worlds. See also `World::new`.
82    pub fn create_world(&self) -> World {
83        let id = WorldId::next(self.id.0);
84        let world = World::new_in_universe(id, EntityAllocator::new(self.allocator.clone()));
85
86        info!(universe = self.id.0, world = world.id().1, "Created world");
87        world
88    }
89}
90
91/// A queryable collection of entities.
92pub trait EntityStore {
93    /// Checks that the provided `Component` is present on a given entity.
94    ///
95    /// Returns true if it exists, otherwise false.
96    fn has_component<T: Component>(&self, entity: Entity) -> bool;
97
98    /// Checks that the provided `ComponentTypeId` is present on a given entity.
99    ///
100    /// Returns true if it exists, otherwise false.
101    fn has_component_by_id(&self, entity: Entity, component: ComponentTypeId) -> bool;
102
103    /// Borrows component data for the given entity.
104    ///
105    /// Returns `Some(data)` if the entity was found and contains the specified data.
106    /// Otherwise `None` is returned.
107    ///
108    /// # Panics
109    ///
110    /// This function may panic if the component was not declared as read by this system.
111    fn get_component<T: Component>(&self, entity: Entity) -> Option<Ref<T>>;
112
113    /// Borrows component data for the given entity. Does not perform static borrow checking.
114    ///
115    /// Returns `Some(data)` if the entity was found and contains the specified data.
116    /// Otherwise `None` is returned.
117    ///
118    /// # Safety
119    ///
120    /// Accessing a component which is already being concurrently accessed elsewhere is undefined behavior.
121    ///
122    /// # Panics
123    ///
124    /// This function may panic if any other code is currently borrowing `T` mutable or if the component was not declared
125    /// as written by this system.
126    unsafe fn get_component_mut_unchecked<T: Component>(&self, entity: Entity)
127        -> Option<RefMut<T>>;
128
129    /// Mutably borrows entity data for the given entity.
130    ///
131    /// Returns `Some(data)` if the entity was found and contains the specified data.
132    /// Otherwise `None` is returned.
133    ///
134    /// # Panics
135    ///
136    /// This function may panic if the component was not declared as written by this system.
137    #[inline]
138    fn get_component_mut<T: Component>(&mut self, entity: Entity) -> Option<RefMut<T>> {
139        // safe because the &mut self ensures exclusivity
140        unsafe { self.get_component_mut_unchecked(entity) }
141    }
142
143    /// Gets tag data for the given entity.
144    ///
145    /// Returns `Some(data)` if the entity was found and contains the specified data.
146    /// Otherwise `None` is returned.
147    fn get_tag<T: Tag>(&self, entity: Entity) -> Option<&T>;
148
149    /// Determines if the given `Entity` is alive within this `World`.
150    fn is_alive(&self, entity: Entity) -> bool;
151
152    /// Gets the entity component storage. Validates that the world can provide access to everything needed by the view.
153    fn get_component_storage<V: for<'a> View<'a>>(
154        &self,
155    ) -> Result<StorageAccessor, ComponentAccessError>;
156}
157
158#[derive(Default, Copy, Clone, PartialEq, Eq, Hash, Debug)]
159pub struct WorldId(usize, usize);
160
161impl WorldId {
162    fn next(universe: usize) -> Self {
163        Self(universe, NEXT_WORLD_ID.fetch_add(1, Ordering::SeqCst))
164    }
165
166    pub fn index(self) -> usize { self.0 }
167
168    pub fn is_same_universe(self, other: WorldId) -> bool { self.0 == other.0 }
169}
170
171/// Contains queryable collections of data associated with `Entity`s.
172pub struct World {
173    id: WorldId,
174    storage: UnsafeCell<Storage>,
175    pub(crate) entity_allocator: Arc<EntityAllocator>,
176    entity_locations: Locations,
177    defrag_progress: usize,
178    command_buffer_size: usize,
179    pub(crate) allocation_buffer: Vec<Entity>,
180}
181
182unsafe impl Send for World {}
183
184unsafe impl Sync for World {}
185
186impl World {
187    pub const DEFAULT_COMMAND_BUFFER_SIZE: usize = 64;
188
189    /// Create a new `World` independent of any `Universe`.
190    ///
191    /// `Entity` IDs in such a world will only be unique within that world. See also
192    /// `Universe::create_world`.
193    pub fn new() -> Self {
194        Self::new_in_universe(
195            WorldId::next(0),
196            EntityAllocator::new(Arc::new(Mutex::new(BlockAllocator::new()))),
197        )
198    }
199
200    fn new_in_universe(id: WorldId, allocator: EntityAllocator) -> Self {
201        Self {
202            id,
203            storage: UnsafeCell::new(Storage::new(id)),
204            entity_allocator: Arc::new(allocator),
205            entity_locations: Locations::new(),
206            defrag_progress: 0,
207            command_buffer_size: Self::DEFAULT_COMMAND_BUFFER_SIZE,
208            allocation_buffer: Vec::with_capacity(Self::DEFAULT_COMMAND_BUFFER_SIZE),
209        }
210    }
211
212    #[inline]
213    pub fn command_buffer_size(&self) -> usize { self.command_buffer_size }
214
215    #[inline]
216    pub fn set_command_buffer_size(&mut self, command_buffer_size: usize) {
217        self.command_buffer_size = command_buffer_size;
218    }
219
220    /// Subscribes to event notifications.
221    ///
222    /// A filter determines which events are of interest. Use `any()` to listen to all events.
223    ///
224    /// # Examples
225    ///
226    /// ```
227    /// # use legion_core::prelude::*;
228    /// # #[derive(Copy, Clone, Debug, PartialEq)]
229    /// # struct Position(f32);
230    /// # #[derive(Copy, Clone, Debug, PartialEq)]
231    /// # struct Model;
232    /// # let universe = Universe::new();
233    /// # let mut world = universe.create_world();
234    /// let (sender, receiver) = crossbeam_channel::unbounded();
235    /// world.subscribe(sender, component::<Position>() | tag::<Model>());
236    ///
237    /// for event in receiver.try_iter() {
238    ///     println!("{:?}", event);
239    /// }
240    /// ```
241    pub fn subscribe<T: EntityFilter + Sync + 'static>(
242        &mut self,
243        sender: crossbeam_channel::Sender<Event>,
244        filter: T,
245    ) {
246        self.storage_mut().subscribe(sender, filter);
247    }
248
249    pub fn storage(&self) -> &Storage { unsafe { &*self.storage.get() } }
250
251    pub fn storage_mut(&mut self) -> &mut Storage { unsafe { &mut *self.storage.get() } }
252
253    /// Gets the unique ID of this world within its universe.
254    pub fn id(&self) -> WorldId { self.id }
255
256    pub fn get_entity_location(&self, entity: Entity) -> Option<EntityLocation> {
257        if self.is_alive(entity) {
258            self.entity_locations.get(entity)
259        } else {
260            None
261        }
262    }
263
264    /// Iterate all entities in existence. Internally this iterates archetypes instead of
265    /// entity allocators because the data structures contains a list of free entities instead
266    /// of allocated entities
267    pub fn iter_entities<'a>(&'a self) -> impl Iterator<Item = Entity> + 'a {
268        self.storage()
269            .archetypes()
270            .iter()
271            .flat_map(|archetype_data| archetype_data.iter_entities().map(|entity| entity))
272    }
273
274    /// Inserts new entities into the world. This insertion method should be preferred, as it performs
275    /// no movement of components for inserting multiple entities and components.
276    ///
277    /// # Examples
278    ///
279    /// Inserting entity tuples:
280    ///
281    /// ```
282    /// # use legion_core::prelude::*;
283    /// # #[derive(Copy, Clone, Debug, PartialEq)]
284    /// # struct Position(f32);
285    /// # #[derive(Copy, Clone, Debug, PartialEq)]
286    /// # struct Rotation(f32);
287    /// # let universe = Universe::new();
288    /// # let mut world = universe.create_world();
289    /// # let model = 0u8;
290    /// # let color = 0u16;
291    /// let tags = (model, color);
292    /// let data = vec![
293    ///     (Position(0.0), Rotation(0.0)),
294    ///     (Position(1.0), Rotation(1.0)),
295    ///     (Position(2.0), Rotation(2.0)),
296    /// ];
297    /// world.insert(tags, data);
298    /// ```
299    #[inline]
300    pub fn insert<T, C>(&mut self, tags: T, components: C) -> &[Entity]
301    where
302        T: TagSet + TagLayout + for<'a> Filter<ChunksetFilterData<'a>>,
303        C: IntoComponentSource,
304    {
305        self.insert_impl(tags, components.into())
306    }
307
308    pub(crate) fn insert_impl<T, C>(&mut self, mut tags: T, mut components: C) -> &[Entity]
309    where
310        T: TagSet + TagLayout + for<'a> Filter<ChunksetFilterData<'a>>,
311        C: ComponentSource,
312    {
313        let span = span!(Level::TRACE, "Inserting entities", world = self.id().0);
314        let _guard = span.enter();
315
316        // find or create archetype
317        let archetype_index = self.find_or_create_archetype(&mut tags, &mut components);
318
319        // find or create chunk set
320        let chunk_set_index = self.find_or_create_chunk(archetype_index, &mut tags);
321
322        self.allocation_buffer.clear();
323        self.allocation_buffer.reserve(components.len());
324
325        // insert components into chunks
326        while !components.is_empty() {
327            // get chunk component storage
328            let archetype =
329                unsafe { (&mut *self.storage.get()).archetype_unchecked_mut(archetype_index) };
330            let chunk_index = archetype.get_free_chunk(chunk_set_index, 1);
331            let chunk = unsafe {
332                archetype
333                    .chunkset_unchecked_mut(chunk_set_index)
334                    .chunk_unchecked_mut(chunk_index)
335            };
336
337            // insert as many components as we can into the chunk
338            let allocated = components.write(self.entity_allocator.create_entities(), chunk);
339
340            // record new entity locations
341            let start = chunk.len() - allocated;
342            let added = chunk.entities().iter().enumerate().skip(start);
343            for (i, e) in added {
344                let location = EntityLocation::new(
345                    archetype_index,
346                    chunk_set_index,
347                    chunk_index,
348                    ComponentIndex(i),
349                );
350                self.entity_locations.set(*e, location);
351                self.allocation_buffer.push(*e);
352            }
353        }
354
355        trace!(count = self.allocation_buffer.len(), "Inserted entities");
356
357        &self.allocation_buffer
358    }
359
360    /// Removes the given `Entity` from the `World`.
361    ///
362    /// Returns `true` if the entity was deleted; else `false`.
363    pub fn delete(&mut self, entity: Entity) -> bool {
364        if !self.is_alive(entity) {
365            return false;
366        }
367
368        if self.entity_allocator.delete_entity(entity) {
369            let location = self.entity_locations.get(entity).unwrap();
370            self.delete_location(location);
371            trace!(world = self.id().0, ?entity, "Deleted entity");
372            true
373        } else {
374            false
375        }
376    }
377
378    /// Delete all entity data. This leaves subscriptions and the command buffer intact.
379    pub fn delete_all(&mut self) {
380        for archetype in self.storage_mut().archetypes_mut() {
381            archetype.delete_all();
382        }
383
384        self.entity_allocator.delete_all_entities();
385    }
386
387    fn delete_location(&mut self, location: EntityLocation) {
388        // find entity's chunk
389        let chunk = self.storage_mut().chunk_mut(location).unwrap();
390
391        // swap remove with last entity in chunk
392        if let Some(swapped) = chunk.swap_remove(location.component(), true) {
393            // record swapped entity's new location
394            self.entity_locations.set(swapped, location);
395        }
396    }
397
398    fn find_chunk_with_delta(
399        &mut self,
400        source_location: EntityLocation,
401        add_components: &[(ComponentTypeId, ComponentMeta)],
402        remove_components: &[ComponentTypeId],
403        add_tags: &[(TagTypeId, TagMeta, NonNull<u8>)],
404        remove_tags: &[TagTypeId],
405    ) -> (ArchetypeIndex, SetIndex) {
406        let archetype = {
407            let result = {
408                let source_archetype = self
409                    .storage()
410                    .archetype(source_location.archetype())
411                    .unwrap();
412
413                // find target chunk
414                let mut component_layout = DynamicComponentLayout {
415                    existing: source_archetype.description().components(),
416                    add: add_components,
417                    remove: remove_components,
418                };
419
420                let mut tag_layout = DynamicTagLayout {
421                    storage: self.storage(),
422                    archetype: source_location.archetype(),
423                    set: source_location.set(),
424                    existing: source_archetype.description().tags(),
425                    add: add_tags,
426                    remove: remove_tags,
427                };
428
429                let archetype = self.find_archetype(&mut tag_layout, &mut component_layout);
430                if let Some(archetype) = archetype.as_ref() {
431                    if let Some(chunk) = self.find_chunk_set(*archetype, &mut tag_layout) {
432                        // fast path: chunk already exists
433                        return (*archetype, chunk);
434                    }
435
436                    Ok(*archetype)
437                } else {
438                    let mut description = ArchetypeDescription::default();
439                    component_layout.tailor_archetype(&mut description);
440                    tag_layout.tailor_archetype(&mut description);
441
442                    Err(description)
443                }
444            };
445
446            match result {
447                Ok(arch) => arch,
448                Err(desc) => {
449                    let (index, _) = unsafe { &mut *self.storage.get() }.alloc_archetype(desc);
450                    index
451                }
452            }
453        };
454
455        // slow path: create new chunk
456        let source_archetype = self
457            .storage()
458            .archetype(source_location.archetype())
459            .unwrap();
460        let mut tags = source_archetype.tags().tag_set(source_location.set());
461        for type_id in remove_tags.iter() {
462            tags.remove(*type_id);
463        }
464        for (type_id, meta, ptr) in add_tags.iter() {
465            tags.push(*type_id, *meta, *ptr);
466        }
467
468        let chunk = self.create_chunk_set(archetype, &tags);
469
470        (archetype, chunk)
471    }
472
473    fn move_entity(
474        &mut self,
475        entity: Entity,
476        add_components: &[(ComponentTypeId, ComponentMeta)],
477        remove_components: &[ComponentTypeId],
478        add_tags: &[(TagTypeId, TagMeta, NonNull<u8>)],
479        remove_tags: &[TagTypeId],
480    ) -> &mut ComponentStorage {
481        let location = self.entity_locations.get(entity).expect("entity not found");
482
483        // find or create the target chunk
484        let (target_arch_index, target_chunkset_index) = self.find_chunk_with_delta(
485            location,
486            add_components,
487            remove_components,
488            add_tags,
489            remove_tags,
490        );
491
492        // Safety Note:
493        // It is only safe for us to have 2 &mut references to storage here because
494        // we know we are only going to be modifying two chunks that are at different
495        // indexes.
496
497        // fetch entity's chunk
498        let current_chunk = unsafe { &mut *self.storage.get() }
499            .chunk_mut(location)
500            .unwrap();
501
502        // fetch target chunk
503        let archetype = unsafe { &mut *self.storage.get() }
504            .archetype_mut(target_arch_index)
505            .unwrap();
506        let target_chunk_index = archetype.get_free_chunk(target_chunkset_index, 1);
507        let target_chunk = unsafe {
508            archetype
509                .chunkset_unchecked_mut(target_chunkset_index)
510                .chunk_unchecked_mut(target_chunk_index)
511        };
512
513        // move existing data over into new chunk
514        if let Some(swapped) = current_chunk.move_entity(target_chunk, location.component()) {
515            // update location of any entity that was moved into the previous location
516            self.entity_locations.set(swapped, location);
517        }
518
519        // record the entity's new location
520        self.entity_locations.set(
521            entity,
522            EntityLocation::new(
523                target_arch_index,
524                target_chunkset_index,
525                target_chunk_index,
526                ComponentIndex(target_chunk.len() - 1),
527            ),
528        );
529
530        target_chunk
531    }
532
533    /// Adds a component to an entity, or sets its value if the component is
534    /// already present.
535    ///
536    /// # Notes
537    /// This function has the overhead of moving the entity to either an existing or new archetype,
538    /// causing a memory copy of the entity to a new location. This function should not be used
539    /// multiple times in successive order.
540    pub fn add_component<T: Component>(
541        &mut self,
542        entity: Entity,
543        component: T,
544    ) -> Result<(), EntityMutationError> {
545        if !self.is_alive(entity) {
546            return Err(EntityMutationError::DoesNotExist);
547        }
548
549        if let Some(mut comp) = self.get_component_mut(entity) {
550            *comp = component;
551            return Ok(());
552        }
553
554        trace!(
555            world = self.id().0,
556            ?entity,
557            component = std::any::type_name::<T>(),
558            "Adding component to entity"
559        );
560
561        // move the entity into a suitable chunk
562        let target_chunk = self.move_entity(
563            entity,
564            &[(ComponentTypeId::of::<T>(), ComponentMeta::of::<T>())],
565            &[],
566            &[],
567            &[],
568        );
569
570        // push new component into chunk
571        let mut writer = target_chunk.writer();
572        let (_, components) = writer.get();
573        let slice = [component];
574        unsafe {
575            let components = &mut *components.get();
576            components
577                .get_mut(ComponentTypeId::of::<T>())
578                .unwrap()
579                .writer()
580                .push(&slice);
581        }
582        std::mem::forget(slice);
583
584        Ok(())
585    }
586
587    /// Removes a component from an entity.
588    ///
589    /// # Notes
590    /// This function has the overhead of moving the entity to either an existing or new archetype,
591    /// causing a memory copy of the entity to a new location. This function should not be used
592    /// multiple times in successive order.
593    ///
594    /// `World::remove_components` should be used for adding multiple omponents to an entity at once.
595    pub fn remove_component<T: Component>(
596        &mut self,
597        entity: Entity,
598    ) -> Result<(), EntityMutationError> {
599        if !self.is_alive(entity) {
600            return Err(EntityMutationError::DoesNotExist);
601        }
602
603        if self.get_component::<T>(entity).is_some() {
604            trace!(
605                world = self.id().0,
606                ?entity,
607                component = std::any::type_name::<T>(),
608                "Removing component from entity"
609            );
610
611            // move the entity into a suitable chunk
612            self.move_entity(entity, &[], &[ComponentTypeId::of::<T>()], &[], &[]);
613        }
614
615        Ok(())
616    }
617
618    /// Removes
619    ///
620    /// # Notes
621    /// This function is provided for bulk deleting components from an entity. This difference between this
622    /// function and `remove_component` is this allows us to remove multiple components and still only
623    /// perform a single move operation of the entity.
624    pub fn remove_components<T: ComponentTypeTupleSet>(
625        &mut self,
626        entity: Entity,
627    ) -> Result<(), EntityMutationError> {
628        if !self.is_alive(entity) {
629            return Err(EntityMutationError::DoesNotExist);
630        }
631
632        let components = T::collect();
633        for component in components.iter() {
634            if !self.has_component_by_id(entity, *component) {
635                return Ok(());
636            }
637        }
638
639        self.move_entity(entity, &[], &components, &[], &[]);
640        Ok(())
641    }
642
643    /// Adds a tag to an entity, or sets its value if the tag is
644    /// already present.
645    pub fn add_tag<T: Tag>(&mut self, entity: Entity, tag: T) -> Result<(), EntityMutationError> {
646        if !self.is_alive(entity) {
647            return Err(EntityMutationError::DoesNotExist);
648        }
649
650        if self.get_tag::<T>(entity).is_some() {
651            self.remove_tag::<T>(entity)?;
652        }
653
654        trace!(
655            world = self.id().0,
656            ?entity,
657            tag = std::any::type_name::<T>(),
658            "Adding tag to entity"
659        );
660
661        // move the entity into a suitable chunk
662        self.move_entity(
663            entity,
664            &[],
665            &[],
666            &[(
667                TagTypeId::of::<T>(),
668                TagMeta::of::<T>(),
669                NonNull::new(&tag as *const _ as *mut u8).unwrap(),
670            )],
671            &[],
672        );
673
674        Ok(())
675    }
676
677    /// Removes a tag from an entity.
678    pub fn remove_tag<T: Tag>(&mut self, entity: Entity) -> Result<(), EntityMutationError> {
679        if !self.is_alive(entity) {
680            return Err(EntityMutationError::DoesNotExist);
681        }
682
683        if self.get_tag::<T>(entity).is_some() {
684            trace!(
685                world = self.id().0,
686                ?entity,
687                tag = std::any::type_name::<T>(),
688                "Removing tag from entity"
689            );
690
691            // move the entity into a suitable chunk
692            self.move_entity(entity, &[], &[], &[], &[TagTypeId::of::<T>()]);
693        }
694
695        Ok(())
696    }
697
698    fn get_component_storage(&self, entity: Entity) -> Option<&ComponentStorage> {
699        let location = self.entity_locations.get(entity)?;
700        self.storage().chunk(location)
701    }
702
703    /// Returns the entity's component types, if the entity exists.
704    pub fn entity_component_types(
705        &self,
706        entity: Entity,
707    ) -> Option<&[(ComponentTypeId, ComponentMeta)]> {
708        if !self.is_alive(entity) {
709            return None;
710        }
711        let location = self.entity_locations.get(entity);
712        let archetype = location
713            .map(|location| self.storage().archetype(location.archetype()))
714            .unwrap_or(None);
715        archetype.map(|archetype| archetype.description().components())
716    }
717
718    /// Returns the entity's tag types, if the entity exists.
719    pub fn entity_tag_types(&self, entity: Entity) -> Option<&[(TagTypeId, TagMeta)]> {
720        if !self.is_alive(entity) {
721            return None;
722        }
723        let location = self.entity_locations.get(entity);
724        let archetype = location
725            .map(|location| self.storage().archetype(location.archetype()))
726            .unwrap_or(None);
727        archetype.map(|archetype| archetype.description().tags())
728    }
729
730    /// Iteratively defragments the world's internal memory.
731    ///
732    /// This compacts entities into fewer more continuous chunks.
733    ///
734    /// `budget` describes the maximum number of entities that can be moved
735    /// in one call. Subsequent calls to `defrag` will resume progress from the
736    /// previous call.
737    pub fn defrag(&mut self, budget: Option<usize>) {
738        let span = span!(
739            Level::INFO,
740            "Defragmenting",
741            world = self.id().0,
742            start_archetype = self.defrag_progress
743        );
744        let _guard = span.enter();
745
746        let archetypes = unsafe { &mut *self.storage.get() }.archetypes_mut();
747        let mut budget = budget.unwrap_or(std::usize::MAX);
748        let start = self.defrag_progress;
749        while self.defrag_progress < archetypes.len() {
750            // defragment the next archetype
751            let complete =
752                (&mut archetypes[self.defrag_progress]).defrag(&mut budget, |e, location| {
753                    self.entity_locations.set(e, location);
754                });
755            if complete {
756                // increment the index, looping it once we get to the end
757                self.defrag_progress = (self.defrag_progress + 1) % archetypes.len();
758            }
759
760            // stop once we run out of budget or reach back to where we started
761            if budget == 0 || self.defrag_progress == start {
762                break;
763            }
764        }
765    }
766
767    /// Move entities from a world to this world, copying all appropriate archetypes,
768    /// tags entities and components into this world.
769    pub fn move_from(&mut self, world: World) {
770        let span =
771            span!(Level::INFO, "Merging worlds", source = world.id().0, destination = ?self.id());
772        let _guard = span.enter();
773
774        self.entity_allocator
775            .merge(Arc::try_unwrap(world.entity_allocator).unwrap());
776
777        for archetype in unsafe { &mut *world.storage.get() }.drain(..) {
778            let target_archetype = {
779                // use the description as an archetype filter
780                let mut desc = archetype.description().clone();
781                let archetype_data = ArchetypeFilterData {
782                    component_types: self.storage().component_types(),
783                    tag_types: self.storage().tag_types(),
784                };
785                let matches = desc
786                    .matches(archetype_data)
787                    .matching_indices()
788                    .next()
789                    .map(ArchetypeIndex);
790                if let Some(arch_index) = matches {
791                    // similar archetype already exists, merge
792                    self.storage_mut()
793                        .archetype_mut(arch_index)
794                        .unwrap()
795                        .move_from(archetype);
796                    arch_index
797                } else {
798                    // archetype does not already exist, append
799                    self.storage_mut().push(archetype);
800                    ArchetypeIndex(self.storage_mut().archetypes().len() - 1)
801                }
802            };
803
804            // update entity locations
805            let archetype = &unsafe { &*self.storage.get() }.archetypes()[target_archetype];
806            for (entity, location) in archetype.iter_entity_locations(target_archetype) {
807                self.entity_locations.set(entity, location);
808            }
809        }
810    }
811
812    /// This will *copy* the data from `src_world` into this world. The logic to do the copy is
813    /// delegated to the `clone_impl` provided by the user. In addition to simple copying, it's also
814    /// possible to transform from one type to another. This is useful for cases where you want to
815    /// read from serializable data (like a physics shape definition) and construct something that
816    /// isn't serializable (like a handle to a physics body)
817    ///
818    /// By default, all entities in the new world will be assigned a new Entity. `result_mappings`
819    /// (if not None) will be populated with the old/new Entities, which allows for mapping data
820    /// between the old and new world.
821    ///
822    /// If you want to replace existing entities (for example to hot-reload data from a file,)
823    /// populate `replace_mappings`. For every entry in this map, the key must exist in the source
824    /// world and the value must exist in the destination world. All entities in the destination
825    /// world referenced by this map will be deleted, and the entities copied over will be assigned
826    /// the same entity. If these constraints are not met, this function will panic.
827    pub fn clone_from<
828        's,
829        CloneImplT: CloneImpl,
830        CloneImplResultT: CloneImplResult,
831        EntityReplacePolicyT: EntityReplacePolicy<'s>,
832    >(
833        &mut self,
834        src_world: &World,
835        clone_impl: &CloneImplT,
836        clone_impl_result: &mut CloneImplResultT,
837        entity_replace_policy: &'s EntityReplacePolicyT,
838    ) {
839        let span = span!(Level::INFO, "CloneMerging worlds", source = src_world.id().0, destination = ?self.id());
840        let _guard = span.enter();
841
842        let src_storage = unsafe { &(*src_world.storage.get()) };
843        let dst_storage = unsafe { &mut (*self.storage.get()) };
844
845        // First check that all the src entities exist in the source world. We're assuming the
846        // source data will be available later to replace the data we're about to delete
847        for k in entity_replace_policy.src_entities() {
848            if !src_world.entity_allocator.is_alive(k) {
849                panic!("clone_from assumes all replace_mapping keys exist in the source world");
850            }
851        }
852
853        // Delete all the data associated with dst_entities. This leaves the
854        // associated entities in a dangling state, but we'll fix this later when we copy the
855        // data over
856        for entity_to_replace in entity_replace_policy.dst_entities() {
857            if self.entity_allocator.is_alive(entity_to_replace) {
858                let location = self
859                    .entity_locations
860                    .get(entity_to_replace)
861                    .expect("Failed to get location of live entity");
862                self.delete_location(location);
863            } else {
864                panic!(
865                    "clone_from assumes all replace_mapping values exist in the destination world"
866                );
867            }
868        }
869
870        // Iterate all archetypes in the src world
871        for src_archetype in src_storage.archetypes() {
872            let archetype_data = ArchetypeFilterData {
873                component_types: self.storage().component_types(),
874                tag_types: self.storage().tag_types(),
875            };
876
877            let dst_archetype_index = World::find_or_create_archetype_for_clone_move(
878                clone_impl,
879                src_archetype.description(),
880                archetype_data,
881                dst_storage,
882            );
883
884            // Do the clone_from for this archetype
885            dst_storage
886                .archetype_mut(dst_archetype_index)
887                .unwrap()
888                .clone_from(
889                    &src_world,
890                    src_archetype,
891                    dst_archetype_index,
892                    &self.entity_allocator,
893                    &mut self.entity_locations,
894                    clone_impl,
895                    clone_impl_result,
896                    entity_replace_policy,
897                );
898        }
899    }
900
901    /// This will *copy* the `src_entity` from `src_world` into this world. The logic to do the copy
902    /// is delegated to the `clone_impl` provided by the user. In addition to simple copying, it's
903    /// also possible to transform from one type to another. This is useful for cases where you want
904    /// to read from serializable data (like a physics shape definition) and construct something
905    /// that isn't serializable (like a handle to a physics body)
906    ///
907    /// By default, the entity in the new world will be assigned a new Entity. The return value
908    /// indicates the Entity in the new world, which allows for mapping data the old and new world.
909    ///
910    /// If you want to replace an existing entity (for example to hot-reload data from a file,)
911    /// populate `replace_mapping`. This entity must exist in the destination world. The entity in
912    /// the destination world will be deleted, and the entity copied over will be assigned
913    /// the same entity. If these constraints are not met, this function will panic.
914    pub fn clone_from_single<C: CloneImpl>(
915        &mut self,
916        src_world: &World,
917        src_entity: Entity,
918        clone_impl: &C,
919        replace_mapping: Option<Entity>,
920    ) -> Entity {
921        let span = span!(Level::INFO, "CloneMergingSingle worlds", source = src_world.id().0, destination = ?self.id());
922        let _guard = span.enter();
923
924        let src_storage = unsafe { &(*src_world.storage.get()) };
925        let dst_storage = unsafe { &mut (*self.storage.get()) };
926
927        if !src_world.entity_allocator.is_alive(src_entity) {
928            panic!("src_entity not alive");
929        }
930
931        // Erase all entities that are referred to by value. The code following will update the location
932        // of all these entities to point to new, valid locations
933        if let Some(replace_mapping) = replace_mapping {
934            if self.entity_allocator.is_alive(replace_mapping) {
935                let location = self
936                    .entity_locations
937                    .get(replace_mapping)
938                    .expect("Failed to get location of live entity");
939                self.delete_location(location);
940            } else {
941                panic!("clone_from_single assumes entity_mapping exists in the destination world");
942            }
943        }
944
945        let src_location = src_world.entity_locations.get(src_entity).unwrap();
946        let src_archetype = &src_storage.archetypes()[src_location.archetype()];
947
948        // Iterate all archetypes in the src world
949        let archetype_data = ArchetypeFilterData {
950            component_types: self.storage().component_types(),
951            tag_types: self.storage().tag_types(),
952        };
953
954        let dst_archetype_index = World::find_or_create_archetype_for_clone_move(
955            clone_impl,
956            src_archetype.description(),
957            archetype_data,
958            dst_storage,
959        );
960
961        // Do the clone_from for this archetype
962        dst_storage
963            .archetype_mut(dst_archetype_index)
964            .unwrap()
965            .clone_from_single(
966                &src_world,
967                src_archetype,
968                &src_location,
969                dst_archetype_index,
970                &self.entity_allocator,
971                &mut self.entity_locations,
972                clone_impl,
973                replace_mapping,
974            )
975    }
976
977    fn find_or_create_archetype_for_clone_move<C: CloneImpl>(
978        clone_impl: &C,
979        src_archetype_description: &ArchetypeDescription,
980        archetype_data: ArchetypeFilterData,
981        dst_storage: &mut Storage,
982    ) -> ArchetypeIndex {
983        // Build the archetype that we will write into. The caller of this function provides an
984        // impl to do the clone, optionally transforming components from one type to another
985        let mut dst_archetype = ArchetypeDescription::default();
986        for (from_type_id, _from_meta) in src_archetype_description.components() {
987            let (into_type_id, into_meta) = clone_impl.map_component_type(*from_type_id);
988            dst_archetype.register_component_raw(into_type_id, into_meta);
989        }
990
991        // Find or create the archetype in the destination world
992        let matches = dst_archetype
993            .matches(archetype_data)
994            .matching_indices()
995            .next();
996
997        // If it doesn't exist, allocate it
998        if let Some(arch_index) = matches {
999            ArchetypeIndex(arch_index)
1000        } else {
1001            dst_storage.alloc_archetype(dst_archetype).0
1002        }
1003    }
1004
1005    fn find_archetype<T, C>(&self, tags: &mut T, components: &mut C) -> Option<ArchetypeIndex>
1006    where
1007        T: for<'a> Filter<ArchetypeFilterData<'a>>,
1008        C: for<'a> Filter<ArchetypeFilterData<'a>>,
1009    {
1010        // search for an archetype with an exact match for the desired component layout
1011        let archetype_data = ArchetypeFilterData {
1012            component_types: self.storage().component_types(),
1013            tag_types: self.storage().tag_types(),
1014        };
1015
1016        // zip the two filters together - find the first index that matches both
1017        tags.matches(archetype_data)
1018            .zip(components.matches(archetype_data))
1019            .enumerate()
1020            .take(self.storage().archetypes().len())
1021            .filter(|(_, (a, b))| *a && *b)
1022            .map(|(i, _)| i)
1023            .next()
1024            .map(ArchetypeIndex)
1025    }
1026
1027    fn create_archetype<T, C>(&mut self, tags: &T, components: &C) -> ArchetypeIndex
1028    where
1029        T: TagLayout,
1030        C: ComponentLayout,
1031    {
1032        let mut description = ArchetypeDescription::default();
1033        tags.tailor_archetype(&mut description);
1034        components.tailor_archetype(&mut description);
1035
1036        let (index, _) = unsafe { &mut *self.storage.get() }.alloc_archetype(description);
1037        index
1038    }
1039
1040    fn find_or_create_archetype<T, C>(&mut self, tags: &mut T, components: &mut C) -> ArchetypeIndex
1041    where
1042        T: TagLayout,
1043        C: ComponentLayout,
1044    {
1045        if let Some(i) = self.find_archetype(tags.get_filter(), components.get_filter()) {
1046            i
1047        } else {
1048            self.create_archetype(tags, components)
1049        }
1050    }
1051
1052    fn find_chunk_set<T>(&self, archetype: ArchetypeIndex, tags: &mut T) -> Option<SetIndex>
1053    where
1054        T: for<'a> Filter<ChunksetFilterData<'a>>,
1055    {
1056        // fetch the archetype, we can already assume that the archetype index is valid
1057        let archetype_data = unsafe { self.storage().archetype_unchecked(archetype) };
1058
1059        // find a chunk with the correct tags
1060        let chunk_filter_data = ChunksetFilterData {
1061            archetype_data: archetype_data.deref(),
1062        };
1063
1064        if let Some(i) = tags.matches(chunk_filter_data).matching_indices().next() {
1065            return Some(SetIndex(i));
1066        }
1067
1068        None
1069    }
1070
1071    fn create_chunk_set<T>(&mut self, archetype: ArchetypeIndex, tags: &T) -> SetIndex
1072    where
1073        T: TagSet,
1074    {
1075        let archetype_data = unsafe { self.storage_mut().archetype_unchecked_mut(archetype) };
1076        archetype_data.alloc_chunk_set(|chunk_tags| tags.write_tags(chunk_tags))
1077    }
1078
1079    fn find_or_create_chunk<T>(&mut self, archetype: ArchetypeIndex, tags: &mut T) -> SetIndex
1080    where
1081        T: TagSet + for<'a> Filter<ChunksetFilterData<'a>>,
1082    {
1083        if let Some(i) = self.find_chunk_set(archetype, tags) {
1084            i
1085        } else {
1086            self.create_chunk_set(archetype, tags)
1087        }
1088    }
1089
1090    /// Splits the world into two. The left world allows access only to the data declared by the view;
1091    /// the right world allows access to all else.
1092    pub fn split<T: for<'v> View<'v>>(&mut self) -> (SubWorld, SubWorld) {
1093        let permissions = T::requires_permissions();
1094        let (left, right) = ComponentAccess::All.split(permissions);
1095
1096        (
1097            SubWorld {
1098                world: self,
1099                components: left,
1100                archetypes: None,
1101            },
1102            SubWorld {
1103                world: self,
1104                components: right,
1105                archetypes: None,
1106            },
1107        )
1108    }
1109
1110    /// Splits the world into two. The left world allows access only to the data declared by the query's view;
1111    /// the right world allows access to all else.
1112    pub fn split_for_query<'q, V: for<'v> View<'v>, F: EntityFilter>(
1113        &mut self,
1114        _: &'q Query<V, F>,
1115    ) -> (SubWorld, SubWorld) {
1116        self.split::<V>()
1117    }
1118}
1119
1120impl EntityStore for World {
1121    #[inline]
1122    fn has_component<T: Component>(&self, entity: Entity) -> bool {
1123        self.has_component_by_id(entity, ComponentTypeId::of::<T>())
1124    }
1125
1126    fn has_component_by_id(&self, entity: Entity, component: ComponentTypeId) -> bool {
1127        if !self.is_alive(entity) {
1128            return false;
1129        }
1130
1131        if let Some(chunkset) = self.get_component_storage(entity) {
1132            return chunkset.components(component).is_some();
1133        }
1134
1135        false
1136    }
1137
1138    #[inline]
1139    fn get_component<T: Component>(&self, entity: Entity) -> Option<Ref<T>> {
1140        if !self.is_alive(entity) {
1141            return None;
1142        }
1143
1144        let location = self.entity_locations.get(entity)?;
1145        let chunk = self.storage().chunk(location)?;
1146        let (slice_borrow, slice) = unsafe {
1147            chunk
1148                .components(ComponentTypeId::of::<T>())?
1149                .data_slice::<T>()
1150                .deconstruct()
1151        };
1152        let component = slice.get(*location.component())?;
1153
1154        Some(Ref::new(slice_borrow, component))
1155    }
1156
1157    #[inline]
1158    unsafe fn get_component_mut_unchecked<T: Component>(
1159        &self,
1160        entity: Entity,
1161    ) -> Option<RefMut<T>> {
1162        if !self.is_alive(entity) {
1163            return None;
1164        }
1165
1166        let location = self.entity_locations.get(entity)?;
1167        let chunk = self.storage().chunk(location)?;
1168        let (slice_borrow, slice) = chunk
1169            .components(ComponentTypeId::of::<T>())?
1170            .data_slice_mut::<T>()
1171            .deconstruct();
1172        let component = slice.get_mut(*location.component())?;
1173
1174        Some(RefMut::new(slice_borrow, component))
1175    }
1176
1177    #[inline]
1178    fn get_tag<T: Tag>(&self, entity: Entity) -> Option<&T> {
1179        if !self.is_alive(entity) {
1180            return None;
1181        }
1182
1183        let location = self.entity_locations.get(entity)?;
1184        let archetype = self.storage().archetype(location.archetype())?;
1185        let tags = archetype.tags().get(TagTypeId::of::<T>())?;
1186
1187        unsafe { tags.data_slice::<T>().get(*location.set()) }
1188    }
1189
1190    #[inline]
1191    fn is_alive(&self, entity: Entity) -> bool { self.entity_allocator.is_alive(entity) }
1192
1193    #[inline]
1194    fn get_component_storage<V: for<'b> View<'b>>(
1195        &self,
1196    ) -> Result<StorageAccessor, ComponentAccessError> {
1197        Ok(StorageAccessor::new(self.storage(), None))
1198    }
1199}
1200
1201impl Default for World {
1202    fn default() -> Self { Self::new() }
1203}
1204
1205/// Describes how to handle a `clone_from`. Allows the user to transform components from one type
1206/// to another and provide their own implementation for cloning/transforming
1207pub trait CloneImpl {
1208    /// When a component of the provided `component_type` is encountered, we will transfer data
1209    /// from it into the returned component type. For a basic clone implementation, this function
1210    /// should return the same type as was passed into it
1211    fn map_component_type(
1212        &self,
1213        component_type_id: ComponentTypeId,
1214    ) -> (ComponentTypeId, ComponentMeta);
1215
1216    /// When called, the implementation should copy the data from src_data to dst_data. The
1217    /// src_world and src_entities are provided so that other components on the same Entity can
1218    /// be looked up. The dst_resources are provided so that any required side effects to resources
1219    /// (like registering a physics body into a physics engine) can be implemented.
1220    #[allow(clippy::too_many_arguments)]
1221    fn clone_components(
1222        &self,
1223        src_world: &World,
1224        src_component_storage: &ComponentStorage,
1225        src_component_storage_indexes: core::ops::Range<ComponentIndex>,
1226        src_type: ComponentTypeId,
1227        src_entities: &[Entity],
1228        dst_entities: &[Entity],
1229        src_data: *const u8,
1230        dst_data: *mut u8,
1231        num_components: usize,
1232    );
1233}
1234
1235/// Used along with `CloneImpl`, allows receiving results from a `clone_from` or `clone_from_single`
1236/// call.
1237pub trait CloneImplResult {
1238    /// For every entity that is copied, this function will be called, passing the entity in the
1239    /// source and destination worlds
1240    fn add_result(&mut self, src_entity: Entity, dst_entity: Entity);
1241}
1242
1243/// Used along with `CloneImpl`, allows specifying that certain entities in the receiving world should
1244/// be replaced with entities from the source world.
1245///
1246/// A typical implementation of this trait would be to wrap a HashMap. `src_entities` would be
1247/// implemented by returning keys(), `dst_entities` would be implemented by returning values(), and
1248/// `get_dst_entity` would be implemented by returning the result of get(src_entity).
1249///
1250/// Default implementations provided in legion include:
1251/// * `NoneEntityReplacePolicy` - No entity replacement will occur
1252/// * `HashMapCloneImplResult` - Wraps the standard library's HashMap.
1253pub trait EntityReplacePolicy<'s> {
1254    /// Returns all entities in the source world that will replace data in the destination world
1255    ///
1256    /// # Safety
1257    ///
1258    /// * All entities returned via the iterator must exist in the source world
1259    /// * All entities that will be copied from the source world must be included in the
1260    ///   returned iterator.
1261    fn src_entities<'a>(&'s self) -> Box<dyn Iterator<Item = Entity> + 'a>
1262    where
1263        's: 'a;
1264
1265    /// Returns all entities in the destination world that will be replaced
1266    ///
1267    /// # Safety
1268    ///
1269    /// * All entities returned via the iterator must exist in the destination world
1270    /// * All entities that will be replaced in the destination world must be included in the
1271    ///   returned iterator
1272    fn dst_entities<'a>(&'s self) -> Box<dyn Iterator<Item = Entity> + 'a>
1273    where
1274        's: 'a;
1275
1276    /// Returns the entity in the destination world that will be replaced by the given entity in the
1277    /// source world, otherwise None if the entity in the source world should not replace anything.
1278    ///
1279    /// # Safety
1280    ///
1281    /// * All entities passed into this function that result in a non-None return value must be
1282    ///   included in the iterator returned by `src_entities`
1283    /// * All entities returned by this function must be included in the iterator returned by
1284    ///   `dst_entities`
1285    fn get_dst_entity(&self, src_entity: Entity) -> Option<Entity>;
1286}
1287
1288/// Used to opt-out of receiving results from a `clone_from` or `clone_from_single` call
1289/// (See comments on `CloneImplResult`)
1290pub struct NoneCloneImplResult;
1291impl CloneImplResult for NoneCloneImplResult {
1292    fn add_result(&mut self, _src_entity: Entity, _dst_entity: Entity) {
1293        // do nothing
1294    }
1295}
1296
1297/// Used to opt-out of replacing entities during a `clone_from` or `clone_from_single` call.
1298/// (See comments on `EntityReplacePolicy`)
1299pub struct NoneEntityReplacePolicy;
1300impl<'s> EntityReplacePolicy<'s> for NoneEntityReplacePolicy {
1301    fn src_entities<'a>(&self) -> Box<dyn Iterator<Item = Entity> + 'a>
1302    where
1303        's: 'a,
1304    {
1305        Box::new(std::iter::Empty::default())
1306    }
1307
1308    fn dst_entities<'a>(&self) -> Box<dyn Iterator<Item = Entity> + 'a>
1309    where
1310        's: 'a,
1311    {
1312        Box::new(std::iter::Empty::default())
1313    }
1314
1315    fn get_dst_entity(&self, _src_entity: Entity) -> Option<Entity> { None }
1316}
1317
1318/// Default implementation of `CloneImplResult` that uses a hash map. Keys are entities in the
1319/// source world and values are entities in the destination world. (See comments on
1320/// `CloneImplResult`)
1321pub struct HashMapCloneImplResult<'m>(pub &'m mut HashMap<Entity, Entity>);
1322
1323impl<'m> CloneImplResult for HashMapCloneImplResult<'m> {
1324    fn add_result(&mut self, src_entity: Entity, dst_entity: Entity) {
1325        self.0.insert(src_entity, dst_entity);
1326    }
1327}
1328
1329/// Default implementation of `EntityReplacePolicy` that uses a hash map. Keys are entities in the
1330/// source world and values are entities in the destination world. (See comments on
1331/// `EntityReplacePolicy`)
1332pub struct HashMapEntityReplacePolicy<'m>(pub &'m HashMap<Entity, Entity>);
1333
1334impl<'m, 's> EntityReplacePolicy<'s> for HashMapEntityReplacePolicy<'m> {
1335    fn src_entities<'a>(&'s self) -> Box<dyn Iterator<Item = Entity> + 'a>
1336    where
1337        's: 'a,
1338    {
1339        Box::new(self.0.keys().cloned())
1340    }
1341
1342    fn dst_entities<'a>(&'s self) -> Box<dyn Iterator<Item = Entity> + 'a>
1343    where
1344        's: 'a,
1345    {
1346        Box::new(self.0.values().cloned())
1347    }
1348
1349    fn get_dst_entity(&self, src_entity: Entity) -> Option<Entity> {
1350        self.0.get(&src_entity).copied()
1351    }
1352}
1353
1354#[derive(Error, Debug)]
1355pub enum EntityMutationError {
1356    #[error("entity does not exist")]
1357    DoesNotExist,
1358}
1359
1360/// Describes the types of a set of components attached to an entity.
1361pub trait ComponentLayout: Sized {
1362    /// A filter type which filters archetypes to an exact match with this layout.
1363    type Filter: for<'a> Filter<ArchetypeFilterData<'a>>;
1364
1365    /// Gets the archetype filter for this layout.
1366    fn get_filter(&mut self) -> &mut Self::Filter;
1367
1368    /// Modifies an archetype description to include the components described by this layout.
1369    fn tailor_archetype(&self, archetype: &mut ArchetypeDescription);
1370}
1371
1372/// Describes the types of a set of tags attached to an entity.
1373pub trait TagLayout: Sized {
1374    /// A filter type which filters archetypes to an exact match with this layout.
1375    type Filter: for<'a> Filter<ArchetypeFilterData<'a>>;
1376
1377    /// Gets the archetype filter for this layout.
1378    fn get_filter(&mut self) -> &mut Self::Filter;
1379
1380    /// Modifies an archetype description to include the tags described by this layout.
1381    fn tailor_archetype(&self, archetype: &mut ArchetypeDescription);
1382}
1383
1384/// A set of tag values to be attached to an entity.
1385pub trait TagSet {
1386    /// Writes the tags in this set to a new chunk.
1387    fn write_tags(&self, tags: &mut Tags);
1388}
1389
1390/// A set of components to be attached to one or more entities.
1391pub trait ComponentSource: ComponentLayout {
1392    /// Determines if this component source has any more entity data to write.
1393    fn is_empty(&mut self) -> bool;
1394
1395    /// Retrieves the nubmer of entities in this component source.
1396    fn len(&self) -> usize;
1397
1398    /// Writes as many components as possible into a chunk.
1399    fn write<T: Iterator<Item = Entity>>(
1400        &mut self,
1401        entities: T,
1402        chunk: &mut ComponentStorage,
1403    ) -> usize;
1404}
1405
1406/// An object that can be converted into a `ComponentSource`.
1407pub trait IntoComponentSource {
1408    /// The component source type that can be converted into.
1409    type Source: ComponentSource;
1410
1411    /// Converts `self` into a component source.
1412    fn into(self) -> Self::Source;
1413}
1414
1415/// A `ComponentSource` which can insert tuples of components representing each entity into a world.
1416pub struct ComponentTupleSet<T, I>
1417where
1418    I: Iterator<Item = T>,
1419{
1420    iter: Peekable<I>,
1421    filter: ComponentTupleFilter<T>,
1422}
1423
1424impl<T, I> From<I> for ComponentTupleSet<T, I>
1425where
1426    I: Iterator<Item = T>,
1427    ComponentTupleSet<T, I>: ComponentSource,
1428{
1429    fn from(iter: I) -> Self {
1430        ComponentTupleSet {
1431            iter: iter.peekable(),
1432            filter: ComponentTupleFilter {
1433                _phantom: PhantomData,
1434            },
1435        }
1436    }
1437}
1438
1439impl<I> IntoComponentSource for I
1440where
1441    I: IntoIterator,
1442    ComponentTupleSet<I::Item, I::IntoIter>: ComponentSource,
1443{
1444    type Source = ComponentTupleSet<I::Item, I::IntoIter>;
1445
1446    fn into(self) -> Self::Source {
1447        ComponentTupleSet {
1448            iter: self.into_iter().peekable(),
1449            filter: ComponentTupleFilter {
1450                _phantom: PhantomData,
1451            },
1452        }
1453    }
1454}
1455
1456pub struct PreallocComponentSource<I: Iterator<Item = Entity> + FusedIterator, C: ComponentSource> {
1457    entities: I,
1458    components: C,
1459}
1460
1461impl<I: Iterator<Item = Entity> + FusedIterator, C: ComponentSource> IntoComponentSource
1462    for PreallocComponentSource<I, C>
1463{
1464    type Source = Self;
1465
1466    fn into(self) -> Self::Source { self }
1467}
1468
1469impl<I: Iterator<Item = Entity>, C: ComponentSource> PreallocComponentSource<Fuse<I>, C> {
1470    pub fn new(entities: I, components: C) -> Self {
1471        Self {
1472            entities: entities.fuse(),
1473            components,
1474        }
1475    }
1476}
1477
1478impl<I: Iterator<Item = Entity> + FusedIterator, C: ComponentSource> ComponentLayout
1479    for PreallocComponentSource<I, C>
1480{
1481    type Filter = C::Filter;
1482
1483    fn get_filter(&mut self) -> &mut Self::Filter { self.components.get_filter() }
1484
1485    fn tailor_archetype(&self, archetype: &mut ArchetypeDescription) {
1486        self.components.tailor_archetype(archetype)
1487    }
1488}
1489
1490impl<I: Iterator<Item = Entity> + FusedIterator, C: ComponentSource> ComponentSource
1491    for PreallocComponentSource<I, C>
1492{
1493    fn is_empty(&mut self) -> bool { self.components.is_empty() }
1494
1495    fn len(&self) -> usize { self.components.len() }
1496
1497    fn write<T: Iterator<Item = Entity>>(
1498        &mut self,
1499        mut entities: T,
1500        chunk: &mut ComponentStorage,
1501    ) -> usize {
1502        let iter = ConcatIter {
1503            a: &mut self.entities,
1504            b: &mut entities,
1505        };
1506        self.components.write(iter, chunk)
1507    }
1508}
1509
1510struct ConcatIter<'a, T, A: Iterator<Item = T> + FusedIterator, B: Iterator<Item = T>> {
1511    a: &'a mut A,
1512    b: &'a mut B,
1513}
1514
1515impl<'a, T, A: Iterator<Item = T> + FusedIterator, B: Iterator<Item = T>> Iterator
1516    for ConcatIter<'a, T, A, B>
1517{
1518    type Item = T;
1519
1520    fn next(&mut self) -> Option<T> { self.a.next().or_else(|| self.b.next()) }
1521}
1522
1523pub struct ComponentTupleFilter<T> {
1524    _phantom: PhantomData<T>,
1525}
1526
1527pub trait ComponentTypeTupleSet {
1528    fn collect() -> Vec<ComponentTypeId>;
1529}
1530
1531mod tuple_impls {
1532    use super::*;
1533    use crate::iterator::SliceVecIter;
1534    use crate::storage::Component;
1535    use crate::storage::ComponentTypeId;
1536    use crate::storage::Tag;
1537    use crate::zip::Zip;
1538    use std::iter::Repeat;
1539    use std::iter::Take;
1540    use std::slice::Iter;
1541
1542    macro_rules! impl_data_tuple {
1543        ( $( $ty: ident => $id: ident ),* ) => {
1544            impl_data_tuple!(@TAG_SET $( $ty => $id ),*);
1545            impl_data_tuple!(@COMPONENT_SOURCE $( $ty => $id ),*);
1546        };
1547        ( @COMPONENT_SOURCE $( $ty: ident => $id: ident ),* ) => {
1548            impl<UWU, $( $ty ),*> ComponentLayout for ComponentTupleSet<($( $ty, )*), UWU>
1549            where
1550                UWU: ExactSizeIterator + Iterator<Item = ($( $ty, )*)>,
1551                $( $ty: Component ),*
1552            {
1553                type Filter = ComponentTupleFilter<($( $ty, )*)>;
1554
1555                fn get_filter(&mut self) -> &mut Self::Filter {
1556                    &mut self.filter
1557                }
1558
1559                fn tailor_archetype(&self, archetype: &mut ArchetypeDescription) {
1560                    #![allow(unused_variables)]
1561                    $(
1562                        archetype.register_component::<$ty>();
1563                    )*
1564                }
1565            }
1566
1567            impl<UWU, $( $ty ),*> ComponentSource for ComponentTupleSet<($( $ty, )*), UWU>
1568            where
1569                UWU: ExactSizeIterator + Iterator<Item = ($( $ty, )*)>,
1570                $( $ty: Component ),*
1571            {
1572                fn is_empty(&mut self) -> bool {
1573                    self.iter.peek().is_none()
1574                }
1575
1576                fn len(&self) -> usize {
1577                    self.iter.len()
1578                }
1579                fn write<EntityIter: Iterator<Item = Entity>>(&mut self, mut allocator: EntityIter, chunk: &mut ComponentStorage) -> usize {
1580                    #![allow(unused_variables)]
1581                    #![allow(unused_unsafe)]
1582                    #![allow(non_snake_case)]
1583                    let space = chunk.capacity() - chunk.len();
1584                    let mut writer = chunk.writer();
1585                    let (entities, components) = writer.get();
1586                    let mut count = 0;
1587
1588                    unsafe {
1589                        $(
1590                            let mut $ty = (&mut *components.get()).get_mut(ComponentTypeId::of::<$ty>()).unwrap().writer();
1591                        )*
1592
1593                        while let Some(($( $id, )*)) = { if count == space { None } else { self.iter.next() } } {
1594                            let entity = allocator.next().unwrap();
1595                            entities.push(entity);
1596
1597                            $(
1598                                let slice = [$id];
1599                                $ty.push(&slice);
1600                                std::mem::forget(slice);
1601                            )*
1602                            count += 1;
1603                        }
1604                    }
1605
1606                    count
1607                }
1608            }
1609
1610            impl<'a, $( $ty ),*> Filter<ArchetypeFilterData<'a>> for ComponentTupleFilter<($( $ty, )*)>
1611            where
1612                $( $ty: Component ),*
1613            {
1614                type Iter = SliceVecIter<'a, ComponentTypeId>;
1615
1616                fn collect(&self, source: ArchetypeFilterData<'a>) -> Self::Iter {
1617                    source.component_types.iter()
1618                }
1619
1620                fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1621                    let types = &[$( ComponentTypeId::of::<$ty>() ),*];
1622                    Some(types.len() == item.len() && types.iter().all(|t| item.contains(t)))
1623                }
1624            }
1625
1626            impl<$( $ty ),*> ComponentTypeTupleSet for ($( $ty, )*)
1627            where
1628                $( $ty: Component ),*
1629            {
1630                fn collect() -> Vec<ComponentTypeId> {
1631                    vec![$( ComponentTypeId::of::<$ty>() ),*]
1632                }
1633            }
1634        };
1635        ( @TAG_SET $( $ty: ident => $id: ident ),* ) => {
1636            impl_data_tuple!(@CHUNK_FILTER $( $ty => $id ),*);
1637
1638            impl<$( $ty ),*> TagSet for ($( $ty, )*)
1639            where
1640                $( $ty: Tag ),*
1641            {
1642                fn write_tags(&self, tags: &mut Tags) {
1643                    #![allow(unused_variables)]
1644                    #![allow(non_snake_case)]
1645                    let ($($id,)*) = self;
1646                    $(
1647                        unsafe {
1648                            tags.get_mut(TagTypeId::of::<$ty>())
1649                                .unwrap()
1650                                .push($id.clone())
1651                        };
1652                    )*
1653                }
1654            }
1655
1656            impl <$( $ty ),*> TagLayout for ($( $ty, )*)
1657            where
1658                $( $ty: Tag ),*
1659            {
1660                type Filter = Self;
1661
1662                fn get_filter(&mut self) -> &mut Self {
1663                    self
1664                }
1665
1666                fn tailor_archetype(&self, archetype: &mut ArchetypeDescription) {
1667                    #![allow(unused_variables)]
1668                    $(
1669                        archetype.register_tag::<$ty>();
1670                    )*
1671                }
1672            }
1673
1674            impl<'a, $( $ty ),*> Filter<ArchetypeFilterData<'a>> for ($( $ty, )*)
1675            where
1676                $( $ty: Tag ),*
1677            {
1678                type Iter = SliceVecIter<'a, TagTypeId>;
1679
1680                fn collect(&self, source: ArchetypeFilterData<'a>) -> Self::Iter {
1681                    source.tag_types.iter()
1682                }
1683
1684                fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1685                    let types = &[$( TagTypeId::of::<$ty>() ),*];
1686                    Some(types.len() == item.len() && types.iter().all(|t| item.contains(t)))
1687                }
1688            }
1689        };
1690        ( @CHUNK_FILTER $( $ty: ident => $id: ident ),+ ) => {
1691            impl<'a, $( $ty ),*> Filter<ChunksetFilterData<'a>> for ($( $ty, )*)
1692            where
1693                $( $ty: Tag ),*
1694            {
1695                type Iter = Zip<($( Iter<'a, $ty>, )*)>;
1696
1697                fn collect(&self, source: ChunksetFilterData<'a>) -> Self::Iter {
1698                    let iters = (
1699                        $(
1700                            unsafe {
1701                                source.archetype_data
1702                                    .tags()
1703                                    .get(TagTypeId::of::<$ty>())
1704                                    .unwrap()
1705                                    .data_slice::<$ty>()
1706                                    .iter()
1707                            },
1708                        )*
1709
1710                    );
1711
1712                    crate::zip::multizip(iters)
1713                }
1714
1715                fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1716                    #![allow(non_snake_case)]
1717                    let ($( $ty, )*) = self;
1718                    Some(($( &*$ty, )*).legion_eq(item))
1719                }
1720            }
1721        };
1722        ( @CHUNK_FILTER ) => {
1723            impl<'a> Filter<ChunksetFilterData<'a>> for () {
1724                type Iter = Take<Repeat<()>>;
1725
1726                fn collect(&self, source: ChunksetFilterData<'a>) -> Self::Iter {
1727                    std::iter::repeat(()).take(source.archetype_data.len())
1728                }
1729
1730                fn is_match(&self, _: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1731                    Some(true)
1732                }
1733            }
1734        };
1735    }
1736
1737    impl_data_tuple!();
1738    impl_data_tuple!(A => a);
1739    impl_data_tuple!(A => a, B => b);
1740    impl_data_tuple!(A => a, B => b, C => c);
1741    impl_data_tuple!(A => a, B => b, C => c, D => d);
1742    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e);
1743    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f);
1744    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g);
1745    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h);
1746    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i);
1747    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j);
1748    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k);
1749    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l);
1750    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m);
1751    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n);
1752    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o);
1753    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p);
1754    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q);
1755    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r);
1756    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s);
1757    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s, T => t);
1758    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s, T => t, U => u);
1759    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s, T => t, U => u, V => v);
1760    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s, T => t, U => u, V => v, W => w);
1761    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s, T => t, U => u, V => v, W => w, X => x);
1762    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s, T => t, U => u, V => v, W => w, X => x, Y => y);
1763    impl_data_tuple!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l, M => m, N => n, O => o, P => p, Q => q, R => r, S => s, T => t, U => u, V => v, W => w, X => x, Y => y, Z => z);
1764}
1765
1766struct DynamicComponentLayout<'a> {
1767    existing: &'a [(ComponentTypeId, ComponentMeta)],
1768    add: &'a [(ComponentTypeId, ComponentMeta)],
1769    remove: &'a [ComponentTypeId],
1770}
1771
1772impl<'a> ComponentLayout for DynamicComponentLayout<'a> {
1773    type Filter = Self;
1774
1775    fn get_filter(&mut self) -> &mut Self::Filter { self }
1776
1777    fn tailor_archetype(&self, archetype: &mut ArchetypeDescription) {
1778        // copy components from existing archetype into new
1779        // except for those in `remove`
1780        let components = self
1781            .existing
1782            .iter()
1783            .filter(|(t, _)| !self.remove.contains(t));
1784
1785        for (comp_type, meta) in components {
1786            archetype.register_component_raw(*comp_type, *meta);
1787        }
1788
1789        // append components from `add`
1790        for (comp_type, meta) in self.add.iter() {
1791            archetype.register_component_raw(*comp_type, *meta);
1792        }
1793    }
1794}
1795
1796impl<'a, 'b> Filter<ArchetypeFilterData<'b>> for DynamicComponentLayout<'a> {
1797    type Iter = SliceVecIter<'b, ComponentTypeId>;
1798
1799    fn collect(&self, source: ArchetypeFilterData<'b>) -> Self::Iter {
1800        source.component_types.iter()
1801    }
1802
1803    fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1804        Some(
1805            item.len() == (self.existing.len() + self.add.len() - self.remove.len())
1806                && item.iter().all(|t| {
1807                    // all types are not in remove
1808                    !self.remove.contains(t)
1809                    // any are either in existing or add
1810                    && (self.existing.iter().any(|(x, _)| x == t)
1811                    || self.add.iter().any(|(x, _)| x == t))
1812                }),
1813        )
1814    }
1815}
1816
1817struct DynamicTagLayout<'a> {
1818    storage: &'a Storage,
1819    archetype: ArchetypeIndex,
1820    set: SetIndex,
1821    existing: &'a [(TagTypeId, TagMeta)],
1822    add: &'a [(TagTypeId, TagMeta, NonNull<u8>)],
1823    remove: &'a [TagTypeId],
1824}
1825
1826unsafe impl<'a> Send for DynamicTagLayout<'a> {}
1827
1828unsafe impl<'a> Sync for DynamicTagLayout<'a> {}
1829
1830impl<'a> TagLayout for DynamicTagLayout<'a> {
1831    type Filter = Self;
1832
1833    fn get_filter(&mut self) -> &mut Self::Filter { self }
1834
1835    fn tailor_archetype(&self, archetype: &mut ArchetypeDescription) {
1836        // copy tags from existing archetype into new
1837        // except for those in `remove`
1838        let tags = self
1839            .existing
1840            .iter()
1841            .filter(|(t, _)| !self.remove.contains(t));
1842
1843        for (tag_type, meta) in tags {
1844            archetype.register_tag_raw(*tag_type, *meta);
1845        }
1846
1847        // append tag from `add`
1848        for (tag_type, meta, _) in self.add.iter() {
1849            archetype.register_tag_raw(*tag_type, *meta);
1850        }
1851    }
1852}
1853
1854impl<'a, 'b> Filter<ArchetypeFilterData<'b>> for DynamicTagLayout<'a> {
1855    type Iter = SliceVecIter<'b, TagTypeId>;
1856
1857    fn collect(&self, source: ArchetypeFilterData<'b>) -> Self::Iter { source.tag_types.iter() }
1858
1859    fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1860        Some(
1861            item.len() == (self.existing.len() + self.add.len() - self.remove.len())
1862                && item.iter().all(|t| {
1863                    // all types are not in remove
1864                    !self.remove.contains(t)
1865                    // any are either in existing or add
1866                    && (self.existing.iter().any(|(x, _)| x == t)
1867                    || self.add.iter().any(|(x, _, _)| x == t))
1868                }),
1869        )
1870    }
1871}
1872
1873impl<'a, 'b> Filter<ChunksetFilterData<'b>> for DynamicTagLayout<'a> {
1874    type Iter = Take<Enumerate<Repeat<&'b ArchetypeData>>>;
1875
1876    fn collect(&self, source: ChunksetFilterData<'b>) -> Self::Iter {
1877        std::iter::repeat(source.archetype_data)
1878            .enumerate()
1879            .take(source.archetype_data.len())
1880    }
1881
1882    fn is_match(&self, (set_index, arch): &<Self::Iter as Iterator>::Item) -> Option<bool> {
1883        for &(type_id, ref meta) in self.existing {
1884            if self.remove.contains(&type_id) {
1885                continue;
1886            }
1887
1888            unsafe {
1889                // find the value of the tag in the source set
1890                let (slice_ptr, element_size, _) = self
1891                    .storage
1892                    .archetype(self.archetype)
1893                    .unwrap()
1894                    .tags()
1895                    .get(type_id)
1896                    .unwrap()
1897                    .data_raw();
1898                let current = slice_ptr.as_ptr().add(*self.set * element_size);
1899
1900                // find the value of the tag in the candidate set
1901                let (slice_ptr, element_size, count) = arch.tags().get(type_id).unwrap().data_raw();
1902                debug_assert!(*set_index < count);
1903                let candidate = slice_ptr.as_ptr().add(set_index * element_size);
1904
1905                if !meta.equals(current, candidate) {
1906                    return Some(false);
1907                }
1908            }
1909        }
1910
1911        for &(type_id, meta, ptr) in self.add {
1912            unsafe {
1913                let (slice_ptr, element_size, count) = arch.tags().get(type_id).unwrap().data_raw();
1914                debug_assert!(*set_index < count);
1915                let candidate = slice_ptr.as_ptr().add(set_index * element_size);
1916
1917                if !meta.equals(ptr.as_ptr(), candidate) {
1918                    return Some(false);
1919                }
1920            }
1921        }
1922
1923        Some(true)
1924    }
1925}
1926
1927#[cfg(test)]
1928mod tests {
1929    use super::*;
1930
1931    #[derive(Clone, Copy, Debug, PartialEq)]
1932    struct Pos(f32, f32, f32);
1933    #[derive(Clone, Copy, Debug, PartialEq)]
1934    struct Rot(f32, f32, f32);
1935    #[derive(Clone, Copy, Debug, PartialEq)]
1936    struct Scale(f32, f32, f32);
1937    #[derive(Clone, Copy, Debug, PartialEq)]
1938    struct Vel(f32, f32, f32);
1939    #[derive(Clone, Copy, Debug, PartialEq)]
1940    struct Accel(f32, f32, f32);
1941    #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
1942    struct Model(u32);
1943    #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
1944    struct Static;
1945
1946    fn create() -> World {
1947        let universe = Universe::new();
1948        universe.create_world()
1949    }
1950
1951    #[test]
1952    fn create_universe() {
1953        let _ = tracing_subscriber::fmt::try_init();
1954
1955        Universe::new();
1956    }
1957
1958    #[test]
1959    fn create_world() {
1960        let _ = tracing_subscriber::fmt::try_init();
1961
1962        let universe = Universe::new();
1963        universe.create_world();
1964    }
1965
1966    #[test]
1967    fn insert_many() {
1968        let _ = tracing_subscriber::fmt::try_init();
1969
1970        let mut world = create();
1971
1972        struct One;
1973        struct Two;
1974        struct Three;
1975        struct Four;
1976        struct Five;
1977        struct Six;
1978        struct Seven;
1979        struct Eight;
1980        struct Nine;
1981        struct Ten;
1982
1983        let shared = (1usize, 2f32, 3u16);
1984        let components = vec![
1985            (One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten),
1986            (One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten),
1987        ];
1988        world.insert(shared, components);
1989
1990        assert_eq!(2, world.allocation_buffer.len());
1991    }
1992
1993    #[test]
1994    fn insert_empty() {
1995        let _ = tracing_subscriber::fmt::try_init();
1996
1997        let mut world = create();
1998
1999        let entity = world.insert((), vec![()])[0];
2000        world.add_component(entity, Pos(1., 2., 3.)).unwrap();
2001
2002        let components = vec![
2003            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2004            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2005        ];
2006
2007        let entities = world.insert((), vec![(), ()]).to_vec();
2008        world.insert(
2009            (),
2010            PreallocComponentSource::new(
2011                entities.iter().copied(),
2012                IntoComponentSource::into(components.clone()),
2013            ),
2014        );
2015
2016        for (i, e) in entities.iter().enumerate() {
2017            world.add_component(*e, Scale(2., 2., 2.)).unwrap();
2018            assert_eq!(
2019                components.get(i).unwrap().0,
2020                *world.get_component(*e).unwrap()
2021            );
2022            assert_eq!(
2023                components.get(i).unwrap().1,
2024                *world.get_component(*e).unwrap()
2025            );
2026            assert_eq!(Scale(2., 2., 2.), *world.get_component(*e).unwrap());
2027        }
2028
2029        assert_eq!(2, world.allocation_buffer.len());
2030    }
2031
2032    #[test]
2033    fn insert() {
2034        let _ = tracing_subscriber::fmt::try_init();
2035
2036        let mut world = create();
2037
2038        let shared = (1usize, 2f32, 3u16);
2039        let components = vec![(4f32, 5u64, 6u16), (4f32, 5u64, 6u16)];
2040        world.insert(shared, components);
2041
2042        assert_eq!(2, world.allocation_buffer.len());
2043    }
2044
2045    #[test]
2046    fn get_component() {
2047        let _ = tracing_subscriber::fmt::try_init();
2048
2049        let mut world = create();
2050
2051        let shared = (Static, Model(5));
2052        let components = vec![
2053            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2054            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2055        ];
2056
2057        world.insert(shared, components.clone());
2058
2059        for (i, e) in world.allocation_buffer.iter().enumerate() {
2060            match world.get_component(*e) {
2061                Some(x) => assert_eq!(components.get(i).map(|(x, _)| x), Some(&x as &Pos)),
2062                None => assert_eq!(components.get(i).map(|(x, _)| x), None),
2063            }
2064            match world.get_component(*e) {
2065                Some(x) => assert_eq!(components.get(i).map(|(_, x)| x), Some(&x as &Rot)),
2066                None => assert_eq!(components.get(i).map(|(_, x)| x), None),
2067            }
2068        }
2069    }
2070
2071    #[test]
2072    fn get_component_wrong_type() {
2073        let _ = tracing_subscriber::fmt::try_init();
2074
2075        let mut world = create();
2076
2077        world.insert((), vec![(0f64,)]);
2078
2079        let entity = *world.allocation_buffer.get(0).unwrap();
2080
2081        assert!(world.get_component::<i32>(entity).is_none());
2082    }
2083
2084    #[test]
2085    fn get_tag() {
2086        let _ = tracing_subscriber::fmt::try_init();
2087
2088        let mut world = create();
2089
2090        let shared = (Static, Model(5));
2091        let components = vec![
2092            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2093            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2094        ];
2095
2096        world.insert(shared, components);
2097
2098        for e in world.allocation_buffer.iter() {
2099            assert_eq!(&Static, world.get_tag::<Static>(*e).unwrap().deref());
2100            assert_eq!(&Model(5), world.get_tag::<Model>(*e).unwrap().deref());
2101        }
2102    }
2103
2104    #[test]
2105    fn get_tag_wrong_type() {
2106        let _ = tracing_subscriber::fmt::try_init();
2107
2108        let mut world = create();
2109
2110        let entity = world.insert((Static,), vec![(0f64,)])[0];
2111
2112        assert!(world.get_tag::<Model>(entity).is_none());
2113    }
2114
2115    #[test]
2116    fn delete() {
2117        let _ = tracing_subscriber::fmt::try_init();
2118
2119        let mut world = create();
2120
2121        let shared = (Static, Model(5));
2122        let components = vec![
2123            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2124            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2125        ];
2126
2127        let entities = world.insert(shared, components).to_vec();
2128
2129        for e in entities.iter() {
2130            assert!(world.get_component::<Pos>(*e).is_some());
2131        }
2132
2133        for e in entities.iter() {
2134            world.delete(*e);
2135            assert!(world.get_component::<Pos>(*e).is_none());
2136        }
2137    }
2138
2139    #[test]
2140    fn delete_last() {
2141        let _ = tracing_subscriber::fmt::try_init();
2142
2143        let mut world = create();
2144
2145        let shared = (Static, Model(5));
2146        let components = vec![
2147            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2148            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2149        ];
2150
2151        let entities = world.insert(shared, components.clone()).to_vec();
2152
2153        let last = *entities.last().unwrap();
2154        world.delete(last);
2155
2156        for (i, e) in entities.iter().take(entities.len() - 1).enumerate() {
2157            match world.get_component(*e) {
2158                Some(x) => assert_eq!(components.get(i).map(|(x, _)| x), Some(&x as &Pos)),
2159                None => assert_eq!(components.get(i).map(|(x, _)| x), None),
2160            }
2161            match world.get_component(*e) {
2162                Some(x) => assert_eq!(components.get(i).map(|(_, x)| x), Some(&x as &Rot)),
2163                None => assert_eq!(components.get(i).map(|(_, x)| x), None),
2164            }
2165        }
2166    }
2167
2168    #[test]
2169    fn delete_first() {
2170        let _ = tracing_subscriber::fmt::try_init();
2171
2172        let mut world = create();
2173
2174        let shared = (Static, Model(5));
2175        let components = vec![
2176            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2177            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2178        ];
2179
2180        let entities = world.insert(shared, components.clone()).to_vec();
2181
2182        let first = *entities.first().unwrap();
2183        world.delete(first);
2184
2185        for (i, e) in entities.iter().skip(1).enumerate() {
2186            match world.get_component(*e) {
2187                Some(x) => assert_eq!(components.get(i + 1).map(|(x, _)| x), Some(&x as &Pos)),
2188                None => assert_eq!(components.get(i + 1).map(|(x, _)| x), None),
2189            }
2190            match world.get_component(*e) {
2191                Some(x) => assert_eq!(components.get(i + 1).map(|(_, x)| x), Some(&x as &Rot)),
2192                None => assert_eq!(components.get(i + 1).map(|(_, x)| x), None),
2193            }
2194        }
2195    }
2196
2197    #[test]
2198    fn add_component() -> Result<(), EntityMutationError> {
2199        let _ = tracing_subscriber::fmt::try_init();
2200
2201        let mut world = create();
2202
2203        let components = vec![
2204            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2205            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2206        ];
2207
2208        let entities = world.insert((Static,), components.clone()).to_vec();
2209
2210        for (i, e) in entities.iter().enumerate() {
2211            world.add_component(*e, Scale(2., 2., 2.))?;
2212            assert_eq!(
2213                components.get(i).unwrap().0,
2214                *world.get_component(*e).unwrap()
2215            );
2216            assert_eq!(
2217                components.get(i).unwrap().1,
2218                *world.get_component(*e).unwrap()
2219            );
2220            assert_eq!(Scale(2., 2., 2.), *world.get_component(*e).unwrap());
2221        }
2222
2223        Ok(())
2224    }
2225
2226    #[test]
2227    fn remove_component() -> Result<(), EntityMutationError> {
2228        let _ = tracing_subscriber::fmt::try_init();
2229
2230        let mut world = create();
2231
2232        let components = vec![
2233            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2234            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2235        ];
2236
2237        let entities = world.insert((Static,), components.clone()).to_vec();
2238
2239        for (i, e) in entities.iter().enumerate() {
2240            world.remove_component::<Rot>(*e)?;
2241            assert_eq!(
2242                components.get(i).unwrap().0,
2243                *world.get_component(*e).unwrap()
2244            );
2245            assert!(world.get_component::<Rot>(*e).is_none());
2246        }
2247
2248        Ok(())
2249    }
2250
2251    #[test]
2252    fn add_tag() -> Result<(), EntityMutationError> {
2253        let _ = tracing_subscriber::fmt::try_init();
2254
2255        let mut world = create();
2256
2257        let components = vec![
2258            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2259            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2260        ];
2261
2262        let entities = world.insert((Static,), components.clone()).to_vec();
2263
2264        for (i, e) in entities.iter().enumerate() {
2265            world.add_tag(*e, Model(2))?;
2266            assert_eq!(
2267                components.get(i).unwrap().0,
2268                *world.get_component(*e).unwrap()
2269            );
2270            assert_eq!(
2271                components.get(i).unwrap().1,
2272                *world.get_component(*e).unwrap()
2273            );
2274            assert_eq!(Static, *world.get_tag(*e).unwrap());
2275            assert_eq!(Model(2), *world.get_tag(*e).unwrap());
2276        }
2277
2278        Ok(())
2279    }
2280
2281    #[test]
2282    fn remove_tag() -> Result<(), EntityMutationError> {
2283        let _ = tracing_subscriber::fmt::try_init();
2284
2285        let mut world = create();
2286
2287        let components = vec![
2288            (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2289            (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2290        ];
2291
2292        let entities = world.insert((Static,), components.clone()).to_vec();
2293
2294        for (i, e) in entities.iter().enumerate() {
2295            world.remove_tag::<Static>(*e)?;
2296            assert_eq!(
2297                components.get(i).unwrap().0,
2298                *world.get_component(*e).unwrap()
2299            );
2300            assert_eq!(
2301                components.get(i).unwrap().1,
2302                *world.get_component(*e).unwrap()
2303            );
2304            assert!(world.get_tag::<Static>(*e).is_none());
2305        }
2306        Ok(())
2307    }
2308
2309    #[test]
2310    fn add_component2() {
2311        let _ = tracing_subscriber::fmt::try_init();
2312        struct Transform {
2313            translation: Vec<f32>,
2314        }
2315        let mut world = create();
2316        let entity = world.insert((5u32,), vec![(3u32,)])[0];
2317        world
2318            .add_component::<Transform>(
2319                entity,
2320                Transform {
2321                    translation: vec![0., 1., 2.],
2322                },
2323            )
2324            .unwrap();
2325    }
2326
2327    #[test]
2328    fn move_from() {
2329        let universe = Universe::new();
2330        let mut a = universe.create_world();
2331        let mut b = universe.create_world();
2332
2333        let entity_a = a.insert(
2334            (),
2335            vec![
2336                (Pos(1., 2., 3.), Rot(0.1, 0.2, 0.3)),
2337                (Pos(4., 5., 6.), Rot(0.4, 0.5, 0.6)),
2338            ],
2339        )[0];
2340
2341        let entity_b = b.insert(
2342            (),
2343            vec![
2344                (Pos(7., 8., 9.), Rot(0.7, 0.8, 0.9)),
2345                (Pos(10., 11., 12.), Rot(0.10, 0.11, 0.12)),
2346            ],
2347        )[0];
2348
2349        b.move_from(a);
2350
2351        assert_eq!(*b.get_component::<Pos>(entity_b).unwrap(), Pos(7., 8., 9.));
2352        assert_eq!(*b.get_component::<Pos>(entity_a).unwrap(), Pos(1., 2., 3.));
2353    }
2354}