1use crate::alloc::{vec, vec::Vec};
9use core::any::TypeId;
10use core::borrow::Borrow;
11use core::convert::TryFrom;
12use core::hash::{BuildHasherDefault, Hasher};
13use spin::Mutex;
14
15use core::{fmt, ptr};
16
17#[cfg(feature = "std")]
18use std::error::Error;
19
20use hashbrown::hash_map::{Entry, HashMap};
21
22use crate::alloc::boxed::Box;
23use crate::archetype::{Archetype, TypeIdMap, TypeInfo};
24use crate::entities::{Entities, EntityMeta, Location, ReserveEntitiesIterator};
25use crate::query::{assert_borrow, assert_distinct};
26use crate::{
27 Bundle, ColumnBatch, ComponentRef, DynamicBundle, Entity, EntityRef, Fetch, MissingComponent,
28 NoSuchEntity, Query, QueryBorrow, QueryMut, QueryOne, TakenEntity, View, ViewBorrow,
29};
30
31pub struct World {
50 entities: Entities,
51 archetypes: ArchetypeSet,
52 bundle_to_archetype: TypeIdMap<u32>,
54 insert_edges: IndexTypeIdMap<InsertTarget>,
57 remove_edges: IndexTypeIdMap<u32>,
60 id: u64,
61}
62
63impl World {
64 pub fn new() -> Self {
66 static ID: Mutex<u64> = Mutex::new(1);
69 let id = {
70 let mut id = ID.lock();
71 let next = id.checked_add(1).unwrap();
72 *id = next;
73 next
74 };
75 Self {
76 entities: Entities::default(),
77 archetypes: ArchetypeSet::new(),
78 bundle_to_archetype: HashMap::default(),
79 insert_edges: HashMap::default(),
80 remove_edges: HashMap::default(),
81 id,
82 }
83 }
84
85 pub fn spawn(&mut self, components: impl DynamicBundle) -> Entity {
105 self.flush();
108
109 let entity = self.entities.alloc();
110
111 self.spawn_inner(entity, components);
112
113 entity
114 }
115
116 pub fn spawn_at(&mut self, handle: Entity, components: impl DynamicBundle) {
138 self.flush();
141
142 let loc = self.entities.alloc_at(handle);
143 if let Some(loc) = loc {
144 if let Some(moved) = unsafe {
145 self.archetypes.archetypes[loc.archetype as usize].remove(loc.index, true)
146 } {
147 self.entities.meta[moved as usize].location.index = loc.index;
148 }
149 }
150
151 self.spawn_inner(handle, components);
152 }
153
154 fn spawn_inner(&mut self, entity: Entity, components: impl DynamicBundle) {
155 let archetype_id = match components.key() {
156 Some(k) => {
157 let archetypes = &mut self.archetypes;
158 *self.bundle_to_archetype.entry(k).or_insert_with(|| {
159 components.with_ids(|ids| archetypes.get(ids, || components.type_info()))
160 })
161 }
162 None => components.with_ids(|ids| self.archetypes.get(ids, || components.type_info())),
163 };
164
165 let archetype = &mut self.archetypes.archetypes[archetype_id as usize];
166 unsafe {
167 let index = archetype.allocate(entity.id);
168 components.put(|ptr, ty| {
169 archetype.put_dynamic(ptr, ty.id(), ty.layout().size(), index);
170 });
171 self.entities.meta[entity.id as usize].location = Location {
172 archetype: archetype_id,
173 index,
174 };
175 }
176 }
177
178 pub fn spawn_batch<I>(&mut self, iter: I) -> SpawnBatchIter<'_, I::IntoIter>
193 where
194 I: IntoIterator,
195 I::Item: Bundle + 'static,
196 {
197 self.flush();
200
201 let iter = iter.into_iter();
202 let (lower, upper) = iter.size_hint();
203 let archetype_id = self.reserve_inner::<I::Item>(
204 u32::try_from(upper.unwrap_or(lower)).expect("iterator too large"),
205 );
206
207 SpawnBatchIter {
208 inner: iter,
209 entities: &mut self.entities,
210 archetype_id,
211 archetype: &mut self.archetypes.archetypes[archetype_id as usize],
212 }
213 }
214
215 pub fn spawn_column_batch(&mut self, batch: ColumnBatch) -> SpawnColumnBatchIter<'_> {
220 self.flush();
221
222 let archetype = batch.0;
223 let entity_count = archetype.len();
224 let (archetype_id, base) = self.archetypes.insert_batch(archetype);
226
227 let archetype = &mut self.archetypes.archetypes[archetype_id as usize];
228 let id_alloc = self.entities.alloc_many(entity_count, archetype_id, base);
229
230 let mut id_alloc_clone = id_alloc.clone();
232 let mut index = base as usize;
233 while let Some(id) = id_alloc_clone.next(&self.entities) {
234 archetype.set_entity_id(index, id);
235 index += 1;
236 }
237
238 SpawnColumnBatchIter {
240 pending_end: id_alloc.pending_end,
241 id_alloc,
242 entities: &mut self.entities,
243 }
244 }
245
246 pub fn spawn_column_batch_at(&mut self, handles: &[Entity], batch: ColumnBatch) {
248 let archetype = batch.0;
249 assert_eq!(
250 handles.len(),
251 archetype.len() as usize,
252 "number of entity IDs {} must match number of entities {}",
253 handles.len(),
254 archetype.len()
255 );
256
257 for &handle in handles {
259 let loc = self.entities.alloc_at(handle);
260 if let Some(loc) = loc {
261 if let Some(moved) = unsafe {
262 self.archetypes.archetypes[loc.archetype as usize].remove(loc.index, true)
263 } {
264 self.entities.meta[moved as usize].location.index = loc.index;
265 }
266 }
267 }
268
269 let (archetype_id, base) = self.archetypes.insert_batch(archetype);
271
272 let archetype = &mut self.archetypes.archetypes[archetype_id as usize];
274 for (&handle, index) in handles.iter().zip(base as usize..) {
275 archetype.set_entity_id(index, handle.id());
276 self.entities.meta[handle.id() as usize].location = Location {
277 archetype: archetype_id,
278 index: index as u32,
279 };
280 }
281 }
282
283 pub fn reserve_entities(&self, count: u32) -> ReserveEntitiesIterator {
294 self.entities.reserve_entities(count)
295 }
296
297 pub fn reserve_entity(&self) -> Entity {
301 self.entities.reserve_entity()
302 }
303
304 pub fn despawn(&mut self, entity: Entity) -> Result<(), NoSuchEntity> {
308 self.flush();
309 let loc = self.entities.free(entity)?;
310 if let Some(moved) =
311 unsafe { self.archetypes.archetypes[loc.archetype as usize].remove(loc.index, true) }
312 {
313 self.entities.meta[moved as usize].location.index = loc.index;
314 }
315 Ok(())
316 }
317
318 pub fn reserve<T: Bundle + 'static>(&mut self, additional: u32) {
320 self.reserve_inner::<T>(additional);
321 }
322
323 fn reserve_inner<T: Bundle + 'static>(&mut self, additional: u32) -> u32 {
324 self.flush();
325 self.entities.reserve(additional);
326
327 let archetypes = &mut self.archetypes;
328 let archetype_id = *self
329 .bundle_to_archetype
330 .entry(TypeId::of::<T>())
331 .or_insert_with(|| {
332 T::with_static_ids(|ids| {
333 archetypes.get(ids, || T::with_static_type_info(|info| info.to_vec()))
334 })
335 });
336
337 self.archetypes.archetypes[archetype_id as usize].reserve(additional);
338 archetype_id
339 }
340
341 pub fn clear(&mut self) {
345 for x in &mut self.archetypes.archetypes {
346 x.clear();
347 }
348 self.entities.clear();
349 }
350
351 pub fn contains(&self, entity: Entity) -> bool {
353 self.entities.contains(entity)
354 }
355
356 pub fn query<Q: Query>(&self) -> QueryBorrow<'_, Q> {
399 QueryBorrow::new(self)
400 }
401
402 pub fn view<Q: Query>(&self) -> ViewBorrow<'_, Q> {
404 ViewBorrow::new(self)
405 }
406
407 pub fn view_mut<Q: Query>(&mut self) -> View<'_, Q> {
410 assert_borrow::<Q>();
411 unsafe { View::<Q>::new(self.entities_meta(), self.archetypes_inner()) }
412 }
413
414 pub fn query_mut<Q: Query>(&mut self) -> QueryMut<'_, Q> {
420 QueryMut::new(self)
421 }
422
423 pub(crate) fn memo(&self) -> (u64, u32) {
424 (self.id, self.archetypes.generation())
425 }
426
427 #[inline(always)]
428 pub(crate) fn entities_meta(&self) -> &[EntityMeta] {
429 &self.entities.meta
430 }
431
432 #[inline(always)]
433 pub(crate) fn archetypes_inner(&self) -> &[Archetype] {
434 &self.archetypes.archetypes
435 }
436
437 pub fn query_one<Q: Query>(&self, entity: Entity) -> Result<QueryOne<'_, Q>, NoSuchEntity> {
460 let loc = self.entities.get(entity)?;
461 Ok(unsafe {
462 QueryOne::new(
463 &self.archetypes.archetypes[loc.archetype as usize],
464 loc.index,
465 )
466 })
467 }
468
469 pub fn query_one_mut<Q: Query>(
475 &mut self,
476 entity: Entity,
477 ) -> Result<Q::Item<'_>, QueryOneError> {
478 assert_borrow::<Q>();
479
480 let loc = self.entities.get(entity)?;
481 let archetype = &self.archetypes.archetypes[loc.archetype as usize];
482 let state = Q::Fetch::prepare(archetype).ok_or(QueryOneError::Unsatisfied)?;
483 let fetch = Q::Fetch::execute(archetype, state);
484 unsafe { Ok(Q::get(&fetch, loc.index as usize)) }
485 }
486
487 pub fn query_many_mut<Q: Query, const N: usize>(
493 &mut self,
494 entities: [Entity; N],
495 ) -> [Result<Q::Item<'_>, QueryOneError>; N] {
496 assert_borrow::<Q>();
497 assert_distinct(&entities);
498
499 entities.map(|entity| {
500 let loc = self.entities.get(entity)?;
501 let archetype = &self.archetypes.archetypes[loc.archetype as usize];
502 let state = Q::Fetch::prepare(archetype).ok_or(QueryOneError::Unsatisfied)?;
503 let fetch = Q::Fetch::execute(archetype, state);
504 unsafe { Ok(Q::get(&fetch, loc.index as usize)) }
505 })
506 }
507
508 pub fn get<'a, T: ComponentRef<'a>>(
510 &'a self,
511 entity: Entity,
512 ) -> Result<T::Ref, ComponentError> {
513 Ok(self
514 .entity(entity)?
515 .get::<T>()
516 .ok_or_else(MissingComponent::new::<T::Component>)?)
517 }
518
519 pub fn satisfies<Q: Query>(&self, entity: Entity) -> Result<bool, NoSuchEntity> {
521 Ok(self.entity(entity)?.satisfies::<Q>())
522 }
523
524 pub fn entity(&self, entity: Entity) -> Result<EntityRef<'_>, NoSuchEntity> {
528 let loc = self.entities.get(entity)?;
529 unsafe {
530 Ok(EntityRef::new(
531 &self.archetypes.archetypes[loc.archetype as usize],
532 entity,
533 loc.index,
534 ))
535 }
536 }
537
538 pub unsafe fn find_entity_from_id(&self, id: u32) -> Entity {
545 self.entities.resolve_unknown_gen(id)
546 }
547
548 pub fn iter(&self) -> Iter<'_> {
565 Iter::new(&self.archetypes.archetypes, &self.entities)
566 }
567
568 pub fn insert(
585 &mut self,
586 entity: Entity,
587 components: impl DynamicBundle,
588 ) -> Result<(), NoSuchEntity> {
589 self.flush();
590
591 let loc = self.entities.get(entity)?;
592 self.insert_inner(entity, components, loc.archetype, loc);
593 Ok(())
594 }
595
596 fn insert_inner(
602 &mut self,
603 entity: Entity,
604 components: impl DynamicBundle,
605 graph_origin: u32,
606 loc: Location,
607 ) {
608 let target_storage;
609 let target = match components.key() {
610 None => {
611 target_storage = self.archetypes.get_insert_target(graph_origin, &components);
612 &target_storage
613 }
614 Some(key) => match self.insert_edges.entry((graph_origin, key)) {
615 Entry::Occupied(entry) => entry.into_mut(),
616 Entry::Vacant(entry) => {
617 let target = self.archetypes.get_insert_target(graph_origin, &components);
618 entry.insert(target)
619 }
620 },
621 };
622
623 let source_arch = &mut self.archetypes.archetypes[loc.archetype as usize];
624 unsafe {
625 for &ty in &target.replaced {
627 let ptr = source_arch
628 .get_dynamic(ty.id(), ty.layout().size(), loc.index)
629 .unwrap();
630 ty.drop(ptr.as_ptr());
631 }
632
633 if target.index == loc.archetype {
634 let arch = &mut self.archetypes.archetypes[loc.archetype as usize];
636 components.put(|ptr, ty| {
637 arch.put_dynamic(ptr, ty.id(), ty.layout().size(), loc.index);
638 });
639 return;
640 }
641
642 let (source_arch, target_arch) = index2(
643 &mut self.archetypes.archetypes,
644 loc.archetype as usize,
645 target.index as usize,
646 );
647
648 let target_index = target_arch.allocate(entity.id);
650 let meta = &mut self.entities.meta[entity.id as usize];
651 meta.location.archetype = target.index;
652 meta.location.index = target_index;
653
654 components.put(|ptr, ty| {
656 target_arch.put_dynamic(ptr, ty.id(), ty.layout().size(), target_index);
657 });
658
659 for &ty in &target.retained {
661 let src = source_arch
662 .get_dynamic(ty.id(), ty.layout().size(), loc.index)
663 .unwrap();
664 target_arch.put_dynamic(src.as_ptr(), ty.id(), ty.layout().size(), target_index)
665 }
666
667 if let Some(moved) = source_arch.remove(loc.index, false) {
669 self.entities.meta[moved as usize].location.index = loc.index;
670 }
671 }
672 }
673
674 pub fn insert_one(
678 &mut self,
679 entity: Entity,
680 component: impl Component,
681 ) -> Result<(), NoSuchEntity> {
682 self.insert(entity, (component,))
683 }
684
685 pub fn remove<T: Bundle + 'static>(&mut self, entity: Entity) -> Result<T, ComponentError> {
705 self.flush();
706
707 let loc = self.entities.get_mut(entity)?;
709 let old_index = loc.index;
710 let source_arch = &self.archetypes.archetypes[loc.archetype as usize];
711
712 let bundle = unsafe {
714 T::get(|ty| source_arch.get_dynamic(ty.id(), ty.layout().size(), old_index))?
715 };
716
717 let target =
719 Self::remove_target::<T>(&mut self.archetypes, &mut self.remove_edges, loc.archetype);
720
721 if loc.archetype != target {
723 let (source_arch, target_arch) = index2(
725 &mut self.archetypes.archetypes,
726 loc.archetype as usize,
727 target as usize,
728 );
729 let target_index = unsafe { target_arch.allocate(entity.id) };
730 loc.archetype = target;
731 loc.index = target_index;
732 if let Some(moved) = unsafe {
733 source_arch.move_to(old_index, |src, ty, size| {
734 if let Some(dst) = target_arch.get_dynamic(ty, size, target_index) {
736 ptr::copy_nonoverlapping(src, dst.as_ptr(), size);
737 }
738 })
739 } {
740 self.entities.meta[moved as usize].location.index = old_index;
741 }
742 }
743
744 Ok(bundle)
745 }
746
747 fn remove_target<T: Bundle + 'static>(
748 archetypes: &mut ArchetypeSet,
749 remove_edges: &mut IndexTypeIdMap<u32>,
750 old_archetype: u32,
751 ) -> u32 {
752 match remove_edges.entry((old_archetype, TypeId::of::<T>())) {
753 Entry::Occupied(entry) => *entry.into_mut(),
754 Entry::Vacant(entry) => {
755 let info = T::with_static_type_info(|removed| {
756 archetypes.archetypes[old_archetype as usize]
757 .types()
758 .iter()
759 .filter(|x| removed.binary_search(x).is_err())
760 .cloned()
761 .collect::<Vec<_>>()
762 });
763 let elements = info.iter().map(|x| x.id()).collect::<Box<_>>();
764 let index = archetypes.get(&*elements, move || info);
765 *entry.insert(index)
766 }
767 }
768 }
769
770 pub fn remove_one<T: Component>(&mut self, entity: Entity) -> Result<T, ComponentError> {
774 self.remove::<(T,)>(entity).map(|(x,)| x)
775 }
776
777 pub fn exchange<S: Bundle + 'static, T: DynamicBundle>(
782 &mut self,
783 entity: Entity,
784 components: T,
785 ) -> Result<S, ComponentError> {
786 self.flush();
787
788 let loc = self.entities.get(entity)?;
790
791 let source_arch = &self.archetypes.archetypes[loc.archetype as usize];
793
794 let bundle = unsafe {
795 S::get(|ty| source_arch.get_dynamic(ty.id(), ty.layout().size(), loc.index))?
796 };
797
798 let intermediate =
800 Self::remove_target::<S>(&mut self.archetypes, &mut self.remove_edges, loc.archetype);
801
802 self.insert_inner(entity, components, intermediate, loc);
803
804 Ok(bundle)
805 }
806
807 pub fn exchange_one<S: Component, T: Component>(
811 &mut self,
812 entity: Entity,
813 component: T,
814 ) -> Result<S, ComponentError> {
815 self.exchange::<(S,), (T,)>(entity, (component,))
816 .map(|(x,)| x)
817 }
818
819 pub unsafe fn get_unchecked<'a, T: ComponentRef<'a>>(
830 &'a self,
831 entity: Entity,
832 ) -> Result<T, ComponentError> {
833 let loc = self.entities.get(entity)?;
834 let archetype = &self.archetypes.archetypes[loc.archetype as usize];
835 let state = archetype
836 .get_state::<T::Component>()
837 .ok_or_else(MissingComponent::new::<T::Component>)?;
838 Ok(T::from_raw(
839 archetype
840 .get_base::<T::Component>(state)
841 .as_ptr()
842 .add(loc.index as usize),
843 ))
844 }
845
846 pub fn flush(&mut self) {
851 let arch = &mut self.archetypes.archetypes[0];
852 self.entities
853 .flush(|id, location| location.index = unsafe { arch.allocate(id) });
854 }
855
856 #[inline(always)]
861 pub fn archetypes(&self) -> impl ExactSizeIterator<Item = &'_ Archetype> + '_ {
862 self.archetypes_inner().iter()
863 }
864
865 pub fn take(&mut self, entity: Entity) -> Result<TakenEntity<'_>, NoSuchEntity> {
869 self.flush();
870 let loc = self.entities.get(entity)?;
871 let archetype = &mut self.archetypes.archetypes[loc.archetype as usize];
872 unsafe {
873 Ok(TakenEntity::new(
874 &mut self.entities,
875 entity,
876 archetype,
877 loc.index,
878 ))
879 }
880 }
881
882 pub fn archetypes_generation(&self) -> ArchetypesGeneration {
901 ArchetypesGeneration(self.archetypes.generation())
902 }
903
904 #[inline]
906 pub fn len(&self) -> u32 {
907 self.entities.len()
908 }
909
910 #[inline]
912 pub fn is_empty(&self) -> bool {
913 self.len() == 0
914 }
915}
916
917unsafe impl Send for World {}
918unsafe impl Sync for World {}
919
920impl Default for World {
921 fn default() -> Self {
922 Self::new()
923 }
924}
925
926impl<'a> IntoIterator for &'a World {
927 type IntoIter = Iter<'a>;
928 type Item = EntityRef<'a>;
929 fn into_iter(self) -> Iter<'a> {
930 self.iter()
931 }
932}
933
934fn index2<T>(x: &mut [T], i: usize, j: usize) -> (&mut T, &mut T) {
935 assert!(i != j);
936 assert!(i < x.len());
937 assert!(j < x.len());
938 let ptr = x.as_mut_ptr();
939 unsafe { (&mut *ptr.add(i), &mut *ptr.add(j)) }
940}
941
942#[derive(Debug, Clone, Eq, PartialEq, Hash)]
944pub enum ComponentError {
945 NoSuchEntity,
947 MissingComponent(MissingComponent),
949}
950
951#[cfg(feature = "std")]
952impl Error for ComponentError {}
953
954impl fmt::Display for ComponentError {
955 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
956 use ComponentError::*;
957 match *self {
958 NoSuchEntity => f.write_str("no such entity"),
959 MissingComponent(ref x) => x.fmt(f),
960 }
961 }
962}
963
964impl From<NoSuchEntity> for ComponentError {
965 fn from(NoSuchEntity: NoSuchEntity) -> Self {
966 ComponentError::NoSuchEntity
967 }
968}
969
970impl From<MissingComponent> for ComponentError {
971 fn from(x: MissingComponent) -> Self {
972 ComponentError::MissingComponent(x)
973 }
974}
975
976#[derive(Debug, Clone, Eq, PartialEq, Hash)]
978pub enum QueryOneError {
979 NoSuchEntity,
981 Unsatisfied,
983}
984
985#[cfg(feature = "std")]
986impl Error for QueryOneError {}
987
988impl fmt::Display for QueryOneError {
989 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
990 use QueryOneError::*;
991 match *self {
992 NoSuchEntity => f.write_str("no such entity"),
993 Unsatisfied => f.write_str("unsatisfied"),
994 }
995 }
996}
997
998impl From<NoSuchEntity> for QueryOneError {
999 fn from(NoSuchEntity: NoSuchEntity) -> Self {
1000 QueryOneError::NoSuchEntity
1001 }
1002}
1003
1004pub trait Component: Send + Sync + 'static {}
1009impl<T: Send + Sync + 'static> Component for T {}
1010
1011pub struct Iter<'a> {
1013 archetypes: core::slice::Iter<'a, Archetype>,
1014 entities: &'a Entities,
1015 current: Option<&'a Archetype>,
1016 index: u32,
1017}
1018
1019impl<'a> Iter<'a> {
1020 fn new(archetypes: &'a [Archetype], entities: &'a Entities) -> Self {
1021 Self {
1022 archetypes: archetypes.iter(),
1023 entities,
1024 current: None,
1025 index: 0,
1026 }
1027 }
1028}
1029
1030unsafe impl Send for Iter<'_> {}
1031unsafe impl Sync for Iter<'_> {}
1032
1033impl<'a> Iterator for Iter<'a> {
1034 type Item = EntityRef<'a>;
1035 fn next(&mut self) -> Option<Self::Item> {
1036 loop {
1037 match self.current {
1038 None => {
1039 self.current = Some(self.archetypes.next()?);
1040 self.index = 0;
1041 }
1042 Some(current) => {
1043 if self.index == current.len() {
1044 self.current = None;
1045 continue;
1046 }
1047 let index = self.index;
1048 self.index += 1;
1049 let id = current.entity_id(index);
1050 return Some(unsafe {
1051 EntityRef::new(
1052 current,
1053 Entity {
1054 id,
1055 generation: self.entities.meta[id as usize].generation,
1056 },
1057 index,
1058 )
1059 });
1060 }
1061 }
1062 }
1063 }
1064
1065 fn size_hint(&self) -> (usize, Option<usize>) {
1066 (self.len(), Some(self.len()))
1067 }
1068}
1069
1070impl ExactSizeIterator for Iter<'_> {
1071 #[inline]
1072 fn len(&self) -> usize {
1073 self.entities.len() as usize
1074 }
1075}
1076
1077impl<A: DynamicBundle> Extend<A> for World {
1078 fn extend<T>(&mut self, iter: T)
1079 where
1080 T: IntoIterator<Item = A>,
1081 {
1082 for x in iter {
1083 self.spawn(x);
1084 }
1085 }
1086}
1087
1088impl<A: DynamicBundle> core::iter::FromIterator<A> for World {
1089 fn from_iter<I: IntoIterator<Item = A>>(iter: I) -> Self {
1090 let mut world = World::new();
1091 world.extend(iter);
1092 world
1093 }
1094}
1095
1096#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1098pub struct ArchetypesGeneration(u32);
1099
1100pub struct SpawnBatchIter<'a, I>
1102where
1103 I: Iterator,
1104 I::Item: Bundle,
1105{
1106 inner: I,
1107 entities: &'a mut Entities,
1108 archetype_id: u32,
1109 archetype: &'a mut Archetype,
1110}
1111
1112impl<I> Drop for SpawnBatchIter<'_, I>
1113where
1114 I: Iterator,
1115 I::Item: Bundle,
1116{
1117 fn drop(&mut self) {
1118 for _ in self {}
1119 }
1120}
1121
1122impl<I> Iterator for SpawnBatchIter<'_, I>
1123where
1124 I: Iterator,
1125 I::Item: Bundle,
1126{
1127 type Item = Entity;
1128
1129 fn next(&mut self) -> Option<Entity> {
1130 let components = self.inner.next()?;
1131 let entity = self.entities.alloc();
1132 let index = unsafe { self.archetype.allocate(entity.id) };
1133 unsafe {
1134 components.put(|ptr, ty| {
1135 self.archetype
1136 .put_dynamic(ptr, ty.id(), ty.layout().size(), index);
1137 });
1138 }
1139 self.entities.meta[entity.id as usize].location = Location {
1140 archetype: self.archetype_id,
1141 index,
1142 };
1143 Some(entity)
1144 }
1145
1146 fn size_hint(&self) -> (usize, Option<usize>) {
1147 self.inner.size_hint()
1148 }
1149}
1150
1151impl<I, T> ExactSizeIterator for SpawnBatchIter<'_, I>
1152where
1153 I: ExactSizeIterator<Item = T>,
1154 T: Bundle,
1155{
1156 fn len(&self) -> usize {
1157 self.inner.len()
1158 }
1159}
1160
1161pub struct SpawnColumnBatchIter<'a> {
1163 pending_end: usize,
1164 id_alloc: crate::entities::AllocManyState,
1165 entities: &'a mut Entities,
1166}
1167
1168impl Iterator for SpawnColumnBatchIter<'_> {
1169 type Item = Entity;
1170
1171 fn next(&mut self) -> Option<Entity> {
1172 let id = self.id_alloc.next(self.entities)?;
1173 Some(unsafe { self.entities.resolve_unknown_gen(id) })
1174 }
1175
1176 fn size_hint(&self) -> (usize, Option<usize>) {
1177 (self.len(), Some(self.len()))
1178 }
1179}
1180
1181impl ExactSizeIterator for SpawnColumnBatchIter<'_> {
1182 fn len(&self) -> usize {
1183 self.id_alloc.len(self.entities)
1184 }
1185}
1186
1187impl Drop for SpawnColumnBatchIter<'_> {
1188 fn drop(&mut self) {
1189 self.entities.finish_alloc_many(self.pending_end);
1191 }
1192}
1193
1194struct ArchetypeSet {
1195 index: HashMap<Box<[TypeId]>, u32>,
1197 archetypes: Vec<Archetype>,
1198}
1199
1200impl ArchetypeSet {
1201 fn new() -> Self {
1202 Self {
1204 index: Some((Box::default(), 0)).into_iter().collect(),
1205 archetypes: vec![Archetype::new(Vec::new())],
1206 }
1207 }
1208
1209 fn get<T: Borrow<[TypeId]> + Into<Box<[TypeId]>>>(
1211 &mut self,
1212 components: T,
1213 info: impl FnOnce() -> Vec<TypeInfo>,
1214 ) -> u32 {
1215 self.index
1216 .get(components.borrow())
1217 .copied()
1218 .unwrap_or_else(|| self.insert(components.into(), info()))
1219 }
1220
1221 fn insert(&mut self, components: Box<[TypeId]>, info: Vec<TypeInfo>) -> u32 {
1222 let x = self.archetypes.len() as u32;
1223 self.archetypes.push(Archetype::new(info));
1224 let old = self.index.insert(components, x);
1225 debug_assert!(old.is_none(), "inserted duplicate archetype");
1226 x
1227 }
1228
1229 fn insert_batch(&mut self, archetype: Archetype) -> (u32, u32) {
1231 let ids = archetype
1232 .types()
1233 .iter()
1234 .map(|info| info.id())
1235 .collect::<Box<_>>();
1236
1237 match self.index.entry(ids) {
1238 Entry::Occupied(x) => {
1239 let existing = &mut self.archetypes[*x.get() as usize];
1241 let base = existing.len();
1242 unsafe {
1243 existing.merge(archetype);
1244 }
1245 (*x.get(), base)
1246 }
1247 Entry::Vacant(x) => {
1248 let id = self.archetypes.len() as u32;
1250 self.archetypes.push(archetype);
1251 x.insert(id);
1252 (id, 0)
1253 }
1254 }
1255 }
1256
1257 fn generation(&self) -> u32 {
1258 self.archetypes.len() as u32
1259 }
1260
1261 fn get_insert_target(&mut self, src: u32, components: &impl DynamicBundle) -> InsertTarget {
1262 let arch = &mut self.archetypes[src as usize];
1264 let mut info = arch.types().to_vec();
1265 let mut replaced = Vec::new(); let mut retained = Vec::new(); let mut src_ty = 0;
1272 for ty in components.type_info() {
1273 while src_ty < arch.types().len() && arch.types()[src_ty] <= ty {
1274 if arch.types()[src_ty] != ty {
1275 retained.push(arch.types()[src_ty]);
1276 }
1277 src_ty += 1;
1278 }
1279 if arch.has_dynamic(ty.id()) {
1280 replaced.push(ty);
1281 } else {
1282 info.push(ty);
1283 }
1284 }
1285 info.sort_unstable();
1286 retained.extend_from_slice(&arch.types()[src_ty..]);
1287
1288 let elements = info.iter().map(|x| x.id()).collect::<Box<_>>();
1290 let index = self.get(elements, move || info);
1291 InsertTarget {
1292 replaced,
1293 retained,
1294 index,
1295 }
1296 }
1297}
1298
1299struct InsertTarget {
1301 replaced: Vec<TypeInfo>,
1303 retained: Vec<TypeInfo>,
1305 index: u32,
1307}
1308
1309type IndexTypeIdMap<V> = HashMap<(u32, TypeId), V, BuildHasherDefault<IndexTypeIdHasher>>;
1310
1311#[derive(Default)]
1312struct IndexTypeIdHasher(u64);
1313
1314impl Hasher for IndexTypeIdHasher {
1315 fn write_u32(&mut self, index: u32) {
1316 self.0 ^= u64::from(index);
1317 }
1318
1319 fn write_u64(&mut self, type_id: u64) {
1320 self.0 ^= type_id;
1321 }
1322
1323 fn write(&mut self, _bytes: &[u8]) {
1324 unreachable!()
1325 }
1326
1327 fn finish(&self) -> u64 {
1328 self.0
1329 }
1330}
1331
1332#[cfg(test)]
1333mod tests {
1334 use super::*;
1335
1336 #[test]
1337 fn reuse_empty() {
1338 let mut world = World::new();
1339 let a = world.spawn(());
1340 world.despawn(a).unwrap();
1341 let b = world.spawn(());
1342 assert_eq!(a.id, b.id);
1343 assert_ne!(a.generation, b.generation);
1344 }
1345
1346 #[test]
1347 fn clear_repeats_entity_id() {
1348 let mut world = World::new();
1349 let a = world.spawn(());
1350 world.clear();
1351 let b = world.spawn(());
1352 assert_eq!(a.id, b.id);
1353 assert_eq!(a.generation, b.generation);
1354 }
1355
1356 #[test]
1357 fn spawn_at() {
1358 let mut world = World::new();
1359 let a = world.spawn(());
1360 world.despawn(a).unwrap();
1361 let b = world.spawn(());
1362 assert!(world.contains(b));
1363 assert_eq!(a.id, b.id);
1364 assert_ne!(a.generation, b.generation);
1365 world.spawn_at(a, ());
1366 assert!(!world.contains(b));
1367 assert_eq!(b.id, a.id);
1368 assert_ne!(b.generation, a.generation);
1369 }
1370
1371 #[test]
1372 fn reuse_populated() {
1373 let mut world = World::new();
1374 let a = world.spawn((42,));
1375 assert_eq!(*world.get::<&i32>(a).unwrap(), 42);
1376 world.despawn(a).unwrap();
1377 let b = world.spawn((true,));
1378 assert_eq!(a.id, b.id);
1379 assert_ne!(a.generation, b.generation);
1380 assert!(world.get::<&i32>(b).is_err());
1381 assert!(*world.get::<&bool>(b).unwrap());
1382 }
1383
1384 #[test]
1385 fn remove_nothing() {
1386 let mut world = World::new();
1387 let a = world.spawn(("abc", 123));
1388 world.remove::<()>(a).unwrap();
1389 }
1390
1391 #[test]
1392 fn bad_insert() {
1393 let mut world = World::new();
1394 assert!(world.insert_one(Entity::DANGLING, ()).is_err());
1395 }
1396}