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#[derive(Debug)]
63pub struct Universe {
64 id: UniverseId,
65 allocator: Arc<Mutex<BlockAllocator>>,
66}
67
68impl Universe {
69 #[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 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
91pub trait EntityStore {
93 fn has_component<T: Component>(&self, entity: Entity) -> bool;
97
98 fn has_component_by_id(&self, entity: Entity, component: ComponentTypeId) -> bool;
102
103 fn get_component<T: Component>(&self, entity: Entity) -> Option<Ref<T>>;
112
113 unsafe fn get_component_mut_unchecked<T: Component>(&self, entity: Entity)
127 -> Option<RefMut<T>>;
128
129 #[inline]
138 fn get_component_mut<T: Component>(&mut self, entity: Entity) -> Option<RefMut<T>> {
139 unsafe { self.get_component_mut_unchecked(entity) }
141 }
142
143 fn get_tag<T: Tag>(&self, entity: Entity) -> Option<&T>;
148
149 fn is_alive(&self, entity: Entity) -> bool;
151
152 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
171pub 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 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 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 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 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 #[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 let archetype_index = self.find_or_create_archetype(&mut tags, &mut components);
318
319 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 while !components.is_empty() {
327 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 let allocated = components.write(self.entity_allocator.create_entities(), chunk);
339
340 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 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 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 let chunk = self.storage_mut().chunk_mut(location).unwrap();
390
391 if let Some(swapped) = chunk.swap_remove(location.component(), true) {
393 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 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 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 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 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 let current_chunk = unsafe { &mut *self.storage.get() }
499 .chunk_mut(location)
500 .unwrap();
501
502 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 if let Some(swapped) = current_chunk.move_entity(target_chunk, location.component()) {
515 self.entity_locations.set(swapped, location);
517 }
518
519 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 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 let target_chunk = self.move_entity(
563 entity,
564 &[(ComponentTypeId::of::<T>(), ComponentMeta::of::<T>())],
565 &[],
566 &[],
567 &[],
568 );
569
570 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 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 self.move_entity(entity, &[], &[ComponentTypeId::of::<T>()], &[], &[]);
613 }
614
615 Ok(())
616 }
617
618 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 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 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 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 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 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 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 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 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 self.defrag_progress = (self.defrag_progress + 1) % archetypes.len();
758 }
759
760 if budget == 0 || self.defrag_progress == start {
762 break;
763 }
764 }
765 }
766
767 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 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 self.storage_mut()
793 .archetype_mut(arch_index)
794 .unwrap()
795 .move_from(archetype);
796 arch_index
797 } else {
798 self.storage_mut().push(archetype);
800 ArchetypeIndex(self.storage_mut().archetypes().len() - 1)
801 }
802 };
803
804 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 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 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 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 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 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 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 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 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 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 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 let matches = dst_archetype
993 .matches(archetype_data)
994 .matching_indices()
995 .next();
996
997 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 let archetype_data = ArchetypeFilterData {
1012 component_types: self.storage().component_types(),
1013 tag_types: self.storage().tag_types(),
1014 };
1015
1016 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 let archetype_data = unsafe { self.storage().archetype_unchecked(archetype) };
1058
1059 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 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 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
1205pub trait CloneImpl {
1208 fn map_component_type(
1212 &self,
1213 component_type_id: ComponentTypeId,
1214 ) -> (ComponentTypeId, ComponentMeta);
1215
1216 #[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
1235pub trait CloneImplResult {
1238 fn add_result(&mut self, src_entity: Entity, dst_entity: Entity);
1241}
1242
1243pub trait EntityReplacePolicy<'s> {
1254 fn src_entities<'a>(&'s self) -> Box<dyn Iterator<Item = Entity> + 'a>
1262 where
1263 's: 'a;
1264
1265 fn dst_entities<'a>(&'s self) -> Box<dyn Iterator<Item = Entity> + 'a>
1273 where
1274 's: 'a;
1275
1276 fn get_dst_entity(&self, src_entity: Entity) -> Option<Entity>;
1286}
1287
1288pub struct NoneCloneImplResult;
1291impl CloneImplResult for NoneCloneImplResult {
1292 fn add_result(&mut self, _src_entity: Entity, _dst_entity: Entity) {
1293 }
1295}
1296
1297pub 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
1318pub 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
1329pub 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
1360pub trait ComponentLayout: Sized {
1362 type Filter: for<'a> Filter<ArchetypeFilterData<'a>>;
1364
1365 fn get_filter(&mut self) -> &mut Self::Filter;
1367
1368 fn tailor_archetype(&self, archetype: &mut ArchetypeDescription);
1370}
1371
1372pub trait TagLayout: Sized {
1374 type Filter: for<'a> Filter<ArchetypeFilterData<'a>>;
1376
1377 fn get_filter(&mut self) -> &mut Self::Filter;
1379
1380 fn tailor_archetype(&self, archetype: &mut ArchetypeDescription);
1382}
1383
1384pub trait TagSet {
1386 fn write_tags(&self, tags: &mut Tags);
1388}
1389
1390pub trait ComponentSource: ComponentLayout {
1392 fn is_empty(&mut self) -> bool;
1394
1395 fn len(&self) -> usize;
1397
1398 fn write<T: Iterator<Item = Entity>>(
1400 &mut self,
1401 entities: T,
1402 chunk: &mut ComponentStorage,
1403 ) -> usize;
1404}
1405
1406pub trait IntoComponentSource {
1408 type Source: ComponentSource;
1410
1411 fn into(self) -> Self::Source;
1413}
1414
1415pub 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 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 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 !self.remove.contains(t)
1809 && (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 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 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 !self.remove.contains(t)
1865 && (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 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 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}